cu-cli 0.1.0b1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cu_cli/__init__.py +17 -0
- cu_cli/__main__.py +11 -0
- cu_cli/apiversion.py +124 -0
- cu_cli/cli.py +138 -0
- cu_cli/client.py +138 -0
- cu_cli/commands/__init__.py +4 -0
- cu_cli/commands/_command_spec.py +94 -0
- cu_cli/commands/_help.py +33 -0
- cu_cli/commands/_infra_models.py +184 -0
- cu_cli/commands/_infra_wizard.py +630 -0
- cu_cli/commands/_model_setup.py +46 -0
- cu_cli/commands/_options.py +112 -0
- cu_cli/commands/analyze.py +631 -0
- cu_cli/commands/analyzer.py +1462 -0
- cu_cli/commands/defaults.py +172 -0
- cu_cli/commands/doctor.py +166 -0
- cu_cli/commands/env_var.py +67 -0
- cu_cli/commands/infra.py +302 -0
- cu_cli/commands/profile_cmd.py +525 -0
- cu_cli/commands/upgrade.py +120 -0
- cu_cli/core/__init__.py +17 -0
- cu_cli/core/analyze.py +44 -0
- cu_cli/core/analyzers.py +30 -0
- cu_cli/core/azure_resources.py +486 -0
- cu_cli/core/defaults.py +18 -0
- cu_cli/core/doctor.py +42 -0
- cu_cli/core/foundry.py +68 -0
- cu_cli/core/infra_models.py +367 -0
- cu_cli/core/inputs.py +209 -0
- cu_cli/core/schema.py +24 -0
- cu_cli/errors.py +174 -0
- cu_cli/exit_codes.py +20 -0
- cu_cli/modality.py +24 -0
- cu_cli/output.py +179 -0
- cu_cli/profile.py +30 -0
- cu_cli/py.typed +0 -0
- cu_cli/resources/__init__.py +4 -0
- cu_cli/resources/azd_template/README.md +187 -0
- cu_cli/resources/azd_template/azure.yaml +27 -0
- cu_cli/resources/azd_template/hooks/postprovision.ps1 +320 -0
- cu_cli/resources/azd_template/hooks/postprovision.sh +299 -0
- cu_cli/resources/azd_template/infra/main.bicep +115 -0
- cu_cli/resources/azd_template/infra/main.parameters.json +30 -0
- cu_cli/resources/azd_template/infra/models.json +1 -0
- cu_cli/resources/azd_template/infra/modules/foundry.bicep +122 -0
- cu_cli/schema_validate.py +28 -0
- cu_cli/spec_validate.py +18 -0
- cu_cli/telemetry.py +42 -0
- cu_cli/update_check.py +154 -0
- cu_cli/update_provider.py +92 -0
- cu_cli/windows_self_upgrade.py +245 -0
- cu_cli-0.1.0b1.dist-info/METADATA +345 -0
- cu_cli-0.1.0b1.dist-info/RECORD +56 -0
- cu_cli-0.1.0b1.dist-info/WHEEL +5 -0
- cu_cli-0.1.0b1.dist-info/entry_points.txt +3 -0
- cu_cli-0.1.0b1.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
#!/usr/bin/env pwsh
|
|
2
|
+
# Copyright (c) Microsoft Corporation.
|
|
3
|
+
# Licensed under the MIT license.
|
|
4
|
+
|
|
5
|
+
# Post-provision hook: prints a summary and optionally wires the `cu` CLI
|
|
6
|
+
# to the freshly provisioned Foundry endpoint.
|
|
7
|
+
#
|
|
8
|
+
# Live model setup is controlled by CU_MODEL_SELECTION. CU CLI profile setup is
|
|
9
|
+
# automatic unless CU_DISABLE_AUTO_PROFILE_SETUP=true.
|
|
10
|
+
|
|
11
|
+
$ErrorActionPreference = 'Stop'
|
|
12
|
+
|
|
13
|
+
$envLines = azd env get-values
|
|
14
|
+
|
|
15
|
+
function Get-AzdValue {
|
|
16
|
+
param([string] $Name)
|
|
17
|
+
$line = $envLines | Where-Object { $_ -match "^$Name=" } | Select-Object -First 1
|
|
18
|
+
if (-not $line) { return '' }
|
|
19
|
+
if ($line -match "^$Name=`"?(.*?)`"?$") { return $Matches[1] }
|
|
20
|
+
return ''
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
$endpoint = Get-AzdValue 'FOUNDRY_ENDPOINT'
|
|
24
|
+
$project = Get-AzdValue 'FOUNDRY_PROJECT_NAME'
|
|
25
|
+
$account = Get-AzdValue 'FOUNDRY_RESOURCE_NAME'
|
|
26
|
+
$rg = Get-AzdValue 'AZURE_RESOURCE_GROUP'
|
|
27
|
+
$subscriptionId = Get-AzdValue 'AZURE_SUBSCRIPTION_ID'
|
|
28
|
+
$existingEndpoint = Get-AzdValue 'FOUNDRY_EXISTING_ENDPOINT'
|
|
29
|
+
$apiVersion = Get-AzdValue 'CU_API_VERSION'
|
|
30
|
+
$modelSelection = Get-AzdValue 'CU_MODEL_SELECTION'
|
|
31
|
+
$modelSetupComplete = Get-AzdValue 'CU_MODEL_SETUP_COMPLETE'
|
|
32
|
+
$assignRoles = Get-AzdValue 'AZD_ASSIGN_ROLES'
|
|
33
|
+
$profileSetupForce = Get-AzdValue 'CU_PROFILE_SETUP_FORCE'
|
|
34
|
+
|
|
35
|
+
# Detect the right cu CLI command (macOS ships a built-in `cu` UUCP tool)
|
|
36
|
+
$cuCmd = $null
|
|
37
|
+
if (Get-Command cu-cli -ErrorAction SilentlyContinue) { $cuCmd = 'cu-cli' }
|
|
38
|
+
elseif (Get-Command cu -ErrorAction SilentlyContinue) { $cuCmd = 'cu' }
|
|
39
|
+
|
|
40
|
+
Write-Host ""
|
|
41
|
+
if ($existingEndpoint) {
|
|
42
|
+
Write-Host "================================================================" -ForegroundColor Cyan
|
|
43
|
+
Write-Host " Existing Microsoft Foundry resource configured" -ForegroundColor Cyan
|
|
44
|
+
Write-Host "================================================================" -ForegroundColor Cyan
|
|
45
|
+
Write-Host " Resource group : $rg"
|
|
46
|
+
Write-Host " Account : $account"
|
|
47
|
+
Write-Host " Endpoint : $endpoint"
|
|
48
|
+
} else {
|
|
49
|
+
Write-Host "================================================================" -ForegroundColor Cyan
|
|
50
|
+
Write-Host " Microsoft Foundry resource provisioned" -ForegroundColor Cyan
|
|
51
|
+
Write-Host "================================================================" -ForegroundColor Cyan
|
|
52
|
+
Write-Host " Resource group : $rg"
|
|
53
|
+
Write-Host " Account : $account"
|
|
54
|
+
Write-Host " Project : $project"
|
|
55
|
+
Write-Host " Endpoint : $endpoint"
|
|
56
|
+
}
|
|
57
|
+
Write-Host ""
|
|
58
|
+
|
|
59
|
+
$modelSetupFailed = $false
|
|
60
|
+
if ($modelSetupComplete -ne 'true') {
|
|
61
|
+
if ($modelSelection -eq 'none') {
|
|
62
|
+
Set-Content -Path 'infra/models.json' -Value "[]`n" -NoNewline
|
|
63
|
+
Write-Host "No model deployments selected." -ForegroundColor Green
|
|
64
|
+
Write-Host "Available without a large language model (LLM) or embeddings model: prebuilt-digitalParse, prebuilt-read, prebuilt-layout"
|
|
65
|
+
} else {
|
|
66
|
+
if (-not $cuCmd) {
|
|
67
|
+
Write-Host "Could not set up optional model deployments because cu CLI is not on PATH." -ForegroundColor Yellow
|
|
68
|
+
$modelSetupFailed = $true
|
|
69
|
+
} else {
|
|
70
|
+
$modelAuthArgs = @()
|
|
71
|
+
$previousApiKey = $env:CU_API_KEY
|
|
72
|
+
$previousAuthMode = $env:CU_AUTH_MODE
|
|
73
|
+
try {
|
|
74
|
+
if ($assignRoles -eq 'false') {
|
|
75
|
+
$azForModelSetup = Get-Command az -ErrorAction SilentlyContinue
|
|
76
|
+
if (-not $azForModelSetup) {
|
|
77
|
+
Write-Host "Could not set up optional model deployments because Azure CLI is not on PATH." -ForegroundColor Yellow
|
|
78
|
+
$modelSetupFailed = $true
|
|
79
|
+
} else {
|
|
80
|
+
$key = (& az cognitiveservices account keys list `
|
|
81
|
+
-g $rg -n $account --subscription $subscriptionId --query key1 -o tsv 2>$null)
|
|
82
|
+
}
|
|
83
|
+
if (-not $modelSetupFailed -and -not $key) {
|
|
84
|
+
Write-Host "Could not obtain a Microsoft Foundry resource key for optional model setup." -ForegroundColor Yellow
|
|
85
|
+
$modelSetupFailed = $true
|
|
86
|
+
} elseif ($key) {
|
|
87
|
+
$env:CU_API_KEY = $key
|
|
88
|
+
$env:CU_AUTH_MODE = 'key'
|
|
89
|
+
}
|
|
90
|
+
} else {
|
|
91
|
+
$modelAuthArgs = @('--auth-mode', 'login')
|
|
92
|
+
}
|
|
93
|
+
if (-not $modelSetupFailed) {
|
|
94
|
+
& $cuCmd _infra-models `
|
|
95
|
+
--resource-group $rg `
|
|
96
|
+
--account $account `
|
|
97
|
+
--subscription $subscriptionId `
|
|
98
|
+
--selection $(if ($modelSelection) { $modelSelection } else { 'prompt' }) `
|
|
99
|
+
--out 'infra/models.json' `
|
|
100
|
+
--deploy `
|
|
101
|
+
--endpoint $endpoint `
|
|
102
|
+
--api-version $(if ($apiVersion) { $apiVersion } else { '2025-11-01' }) `
|
|
103
|
+
@modelAuthArgs
|
|
104
|
+
if ($LASTEXITCODE -ne 0) {
|
|
105
|
+
$modelSetupFailed = $true
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
} finally {
|
|
109
|
+
$env:CU_API_KEY = $previousApiKey
|
|
110
|
+
$env:CU_AUTH_MODE = $previousAuthMode
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
if (-not $modelSetupFailed) {
|
|
115
|
+
& azd env set CU_MODEL_SETUP_COMPLETE true *> $null
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
if ($env:CU_DISABLE_AUTO_PROFILE_SETUP -eq 'true' -or $env:CU_AUTOCONFIG -eq 'false') {
|
|
120
|
+
Write-Host "Automatic CU CLI profile setup disabled." -ForegroundColor Yellow
|
|
121
|
+
Write-Host "To configure manually: cu-cli profile set endpoint $endpoint --name default" -ForegroundColor Yellow
|
|
122
|
+
return
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
if (-not $cuCmd) {
|
|
126
|
+
Write-Host "cu CLI not found on PATH. To configure manually:" -ForegroundColor Yellow
|
|
127
|
+
Write-Host " cu-cli profile set endpoint $endpoint --name default" -ForegroundColor Yellow
|
|
128
|
+
return
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
& $cuCmd profile _has-values --name default *> $null
|
|
132
|
+
$profileStatus = $LASTEXITCODE
|
|
133
|
+
if ($profileStatus -eq 0 -and $profileSetupForce -ne 'true') {
|
|
134
|
+
Write-Host "Default CU CLI profile already has saved values; preserving it." -ForegroundColor Yellow
|
|
135
|
+
Write-Host "Current default CU CLI profile:"
|
|
136
|
+
& $cuCmd profile show --name default
|
|
137
|
+
if ($LASTEXITCODE -ne 0) {
|
|
138
|
+
Write-Host "Could not display the preserved default CU CLI profile." -ForegroundColor Yellow
|
|
139
|
+
}
|
|
140
|
+
Write-Host "To replace its values, rerun cu infra generate with --force, then run azd up." -ForegroundColor Yellow
|
|
141
|
+
return
|
|
142
|
+
} elseif ($profileStatus -ne 0 -and $profileStatus -ne 3) {
|
|
143
|
+
Write-Host "Could not inspect the default CU CLI profile; refusing to overwrite it." -ForegroundColor Yellow
|
|
144
|
+
Write-Host "Run: $cuCmd profile show --name default" -ForegroundColor Yellow
|
|
145
|
+
exit 1
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
$setupIncomplete = $false
|
|
149
|
+
$authReady = $true
|
|
150
|
+
$endpointReady = $false
|
|
151
|
+
if ($assignRoles -eq 'false') {
|
|
152
|
+
$az = Get-Command az -ErrorAction SilentlyContinue
|
|
153
|
+
if (-not $az) {
|
|
154
|
+
Write-Host ""
|
|
155
|
+
Write-Host "Roles were skipped and 'az' CLI is not on PATH." -ForegroundColor Yellow
|
|
156
|
+
Write-Host "To enable key-based auth from cu, install az and run:" -ForegroundColor Yellow
|
|
157
|
+
Write-Host " az login" -ForegroundColor Yellow
|
|
158
|
+
Write-Host " cu profile set api_key (az cognitiveservices account keys list -g $rg -n $account --subscription $subscriptionId --query key1 -o tsv) --name default" -ForegroundColor Yellow
|
|
159
|
+
$authReady = $false
|
|
160
|
+
$setupIncomplete = $true
|
|
161
|
+
} else {
|
|
162
|
+
& az account show --subscription $subscriptionId --only-show-errors *> $null
|
|
163
|
+
if ($LASTEXITCODE -ne 0) {
|
|
164
|
+
Write-Host ""
|
|
165
|
+
Write-Host "Roles were skipped and 'az' isn't logged in (azd auth login is separate from az login)." -ForegroundColor Yellow
|
|
166
|
+
Write-Host "To enable key-based auth from cu, run:" -ForegroundColor Yellow
|
|
167
|
+
Write-Host " az login" -ForegroundColor Yellow
|
|
168
|
+
Write-Host " cu profile set api_key (az cognitiveservices account keys list -g $rg -n $account --subscription $subscriptionId --query key1 -o tsv) --name default" -ForegroundColor Yellow
|
|
169
|
+
$authReady = $false
|
|
170
|
+
$setupIncomplete = $true
|
|
171
|
+
} else {
|
|
172
|
+
Write-Host "Roles were skipped; fetching account key for cu..." -ForegroundColor Green
|
|
173
|
+
$key = (& az cognitiveservices account keys list -g $rg -n $account --subscription $subscriptionId --query key1 -o tsv 2>$null)
|
|
174
|
+
if ($LASTEXITCODE -eq 0 -and $key) {
|
|
175
|
+
& $cuCmd profile set api_key $key --name default
|
|
176
|
+
if ($LASTEXITCODE -eq 0) {
|
|
177
|
+
Write-Host "API key written to the default CU CLI profile." -ForegroundColor Green
|
|
178
|
+
} else {
|
|
179
|
+
Write-Host "Could not configure key authentication." -ForegroundColor Yellow
|
|
180
|
+
$authReady = $false
|
|
181
|
+
$setupIncomplete = $true
|
|
182
|
+
}
|
|
183
|
+
} else {
|
|
184
|
+
Write-Host "Could not configure key authentication." -ForegroundColor Yellow
|
|
185
|
+
Write-Host "Try: az cognitiveservices account keys list -g $rg -n $account --subscription $subscriptionId" -ForegroundColor Yellow
|
|
186
|
+
$authReady = $false
|
|
187
|
+
$setupIncomplete = $true
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
} else {
|
|
192
|
+
Write-Host "Configuring cu CLI to use Entra authentication..." -ForegroundColor Green
|
|
193
|
+
& $cuCmd profile set auth_mode login --name default
|
|
194
|
+
if ($LASTEXITCODE -ne 0) {
|
|
195
|
+
Write-Host "Could not configure Entra authentication." -ForegroundColor Yellow
|
|
196
|
+
$authReady = $false
|
|
197
|
+
$setupIncomplete = $true
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
Write-Host "Configuring cu CLI endpoint..." -ForegroundColor Green
|
|
202
|
+
& $cuCmd profile set endpoint $endpoint --name default
|
|
203
|
+
if ($LASTEXITCODE -eq 0) {
|
|
204
|
+
$endpointReady = $true
|
|
205
|
+
} else {
|
|
206
|
+
Write-Host "Could not configure the cu CLI endpoint." -ForegroundColor Yellow
|
|
207
|
+
$setupIncomplete = $true
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
Write-Host "Configuring prebuilt-layout as the default analyzer..." -ForegroundColor Green
|
|
211
|
+
& $cuCmd profile set default_analyzer prebuilt-layout --name default
|
|
212
|
+
if ($LASTEXITCODE -ne 0) {
|
|
213
|
+
Write-Host "Could not configure the default analyzer." -ForegroundColor Yellow
|
|
214
|
+
$setupIncomplete = $true
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
$maybeSetDefaults = $false
|
|
218
|
+
$defaultsInitialized = $false
|
|
219
|
+
$defaultsFailed = $false
|
|
220
|
+
$depCompletion = $null
|
|
221
|
+
$depMini = $null
|
|
222
|
+
$depEmbedding = $null
|
|
223
|
+
$completionReady = $false
|
|
224
|
+
$embeddingReady = $false
|
|
225
|
+
$azForDefaults = Get-Command az -ErrorAction SilentlyContinue
|
|
226
|
+
if ($azForDefaults) {
|
|
227
|
+
& az account show --subscription $subscriptionId --only-show-errors *> $null
|
|
228
|
+
if ($LASTEXITCODE -eq 0) {
|
|
229
|
+
$deploymentsJson = & az cognitiveservices account deployment list -g $rg -n $account --subscription $subscriptionId -o json 2>$null
|
|
230
|
+
if ($deploymentsJson) {
|
|
231
|
+
$deployments = $deploymentsJson | ConvertFrom-Json
|
|
232
|
+
foreach ($dep in $deployments) {
|
|
233
|
+
$modelName = $dep.properties.model.name
|
|
234
|
+
if ($modelName) {
|
|
235
|
+
& $cuCmd profile set "model_deployments.$modelName" $dep.name --name default
|
|
236
|
+
$maybeSetDefaults = $true
|
|
237
|
+
if ($modelName -like 'text-embedding-*') {
|
|
238
|
+
if (-not $depEmbedding) { $depEmbedding = $dep.name }
|
|
239
|
+
if ($dep.properties.provisioningState -eq 'Succeeded') { $embeddingReady = $true }
|
|
240
|
+
} elseif ($modelName -like '*-mini') {
|
|
241
|
+
if (-not $depMini) { $depMini = $dep.name }
|
|
242
|
+
if (-not $depCompletion) { $depCompletion = $dep.name }
|
|
243
|
+
if ($dep.properties.provisioningState -eq 'Succeeded') { $completionReady = $true }
|
|
244
|
+
} else {
|
|
245
|
+
if (-not $depCompletion) { $depCompletion = $dep.name }
|
|
246
|
+
if ($dep.properties.provisioningState -eq 'Succeeded') { $completionReady = $true }
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
if ($maybeSetDefaults) {
|
|
255
|
+
$completionDep = $depCompletion
|
|
256
|
+
$miniDep = if ($depMini) { $depMini } else { $completionDep }
|
|
257
|
+
if ($completionDep) {
|
|
258
|
+
& $cuCmd profile set "model_deployments.prebuilt-analyzer-completion" $completionDep --name default
|
|
259
|
+
& $cuCmd profile set "model_deployments.prebuilt-analyzer-completion-mini" $miniDep --name default
|
|
260
|
+
}
|
|
261
|
+
if ($depEmbedding) {
|
|
262
|
+
& $cuCmd profile set "model_deployments.prebuilt-analyzer-embedding" $depEmbedding --name default
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
Write-Host "Initializing Foundry defaults from configured model deployments..." -ForegroundColor Green
|
|
266
|
+
& $cuCmd defaults set --from-profile --profile default *> $null
|
|
267
|
+
if ($LASTEXITCODE -eq 0) {
|
|
268
|
+
Write-Host "Foundry defaults initialized." -ForegroundColor Green
|
|
269
|
+
$defaultsInitialized = $true
|
|
270
|
+
} else {
|
|
271
|
+
Write-Host "Could not initialize Foundry defaults automatically." -ForegroundColor Yellow
|
|
272
|
+
Write-Host "Run: $cuCmd defaults set --from-profile --profile default" -ForegroundColor Yellow
|
|
273
|
+
$defaultsFailed = $true
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
$llmReady = $defaultsInitialized -and $completionReady -and $embeddingReady
|
|
278
|
+
if ($llmReady) {
|
|
279
|
+
Write-Host "Model readiness verified: LLM and embeddings model deployments succeeded and Content Understanding defaults are configured." -ForegroundColor Green
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
Write-Host ""
|
|
283
|
+
if ($setupIncomplete) {
|
|
284
|
+
Write-Host "Azure provisioning completed, but cu auto-configuration is incomplete." -ForegroundColor Yellow
|
|
285
|
+
Write-Host "Run: $cuCmd doctor" -ForegroundColor Yellow
|
|
286
|
+
exit 1
|
|
287
|
+
}
|
|
288
|
+
Write-Host "Setup complete." -ForegroundColor Green
|
|
289
|
+
if ($endpointReady) {
|
|
290
|
+
Write-Host "Default CU CLI profile configured:"
|
|
291
|
+
& $cuCmd profile show --name default
|
|
292
|
+
if ($LASTEXITCODE -ne 0) {
|
|
293
|
+
Write-Host " Warning: profile setup succeeded, but its values could not be displayed." -ForegroundColor Yellow
|
|
294
|
+
}
|
|
295
|
+
Write-Host ""
|
|
296
|
+
Write-Host " Verify setup with:"
|
|
297
|
+
Write-Host " $cuCmd doctor" -ForegroundColor Cyan
|
|
298
|
+
}
|
|
299
|
+
if ($endpointReady -and $authReady) {
|
|
300
|
+
Write-Host " Available without an LLM or embeddings model: prebuilt-digitalParse, prebuilt-read, prebuilt-layout"
|
|
301
|
+
Write-Host " Content extraction sanity check:"
|
|
302
|
+
Write-Host " $cuCmd analyze <file> --analyzer prebuilt-layout" -ForegroundColor Cyan
|
|
303
|
+
}
|
|
304
|
+
if ($modelSetupFailed) {
|
|
305
|
+
Write-Host " Optional model setup failed; the Microsoft Foundry resource and CU CLI profile are still ready." -ForegroundColor Yellow
|
|
306
|
+
Write-Host " Resolve the deployment issue, then rerun azd up before using generative AI" -ForegroundColor Yellow
|
|
307
|
+
Write-Host " prebuilt analyzers such as prebuilt-invoice or custom analyzers." -ForegroundColor Yellow
|
|
308
|
+
} elseif ($llmReady) {
|
|
309
|
+
Write-Host " Custom analyzer workflow:"
|
|
310
|
+
Write-Host " $cuCmd analyzer schema create --from-sample <file> --output-file schema.json" -ForegroundColor Cyan
|
|
311
|
+
Write-Host " $cuCmd analyzer create --name my-analyzer --schema schema.json" -ForegroundColor Cyan
|
|
312
|
+
Write-Host " $cuCmd analyze <file> --analyzer my-analyzer" -ForegroundColor Cyan
|
|
313
|
+
} elseif ($defaultsFailed) {
|
|
314
|
+
Write-Host " Generative AI workflows are not ready because Content Understanding defaults configuration failed." -ForegroundColor Yellow
|
|
315
|
+
Write-Host " Repair with: $cuCmd defaults set --from-profile --profile default" -ForegroundColor Yellow
|
|
316
|
+
} elseif ($maybeSetDefaults) {
|
|
317
|
+
Write-Host " Generative AI workflows require succeeded LLM and embeddings model deployments." -ForegroundColor Yellow
|
|
318
|
+
} else {
|
|
319
|
+
Write-Host " No optional models were configured; content extraction analyzers remain available." -ForegroundColor DarkGray
|
|
320
|
+
}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
# Copyright (c) Microsoft Corporation.
|
|
3
|
+
# Licensed under the MIT license.
|
|
4
|
+
|
|
5
|
+
# Post-provision hook: prints a summary and optionally wires the `cu` CLI
|
|
6
|
+
# to the freshly provisioned Foundry endpoint.
|
|
7
|
+
#
|
|
8
|
+
# Live model setup is controlled by CU_MODEL_SELECTION. CU CLI profile setup is
|
|
9
|
+
# automatic unless CU_DISABLE_AUTO_PROFILE_SETUP=true.
|
|
10
|
+
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
values=$(azd env get-values)
|
|
14
|
+
endpoint=$(printf '%s\n' "$values" | sed -n 's/^FOUNDRY_ENDPOINT="\{0,1\}\([^"]*\)"\{0,1\}/\1/p')
|
|
15
|
+
project=$(printf '%s\n' "$values" | sed -n 's/^FOUNDRY_PROJECT_NAME="\{0,1\}\([^"]*\)"\{0,1\}/\1/p')
|
|
16
|
+
account=$(printf '%s\n' "$values" | sed -n 's/^FOUNDRY_RESOURCE_NAME="\{0,1\}\([^"]*\)"\{0,1\}/\1/p')
|
|
17
|
+
rg=$(printf '%s\n' "$values" | sed -n 's/^AZURE_RESOURCE_GROUP="\{0,1\}\([^"]*\)"\{0,1\}/\1/p')
|
|
18
|
+
subscription_id=$(printf '%s\n' "$values" | sed -n 's/^AZURE_SUBSCRIPTION_ID="\{0,1\}\([^"]*\)"\{0,1\}/\1/p')
|
|
19
|
+
existing_endpoint=$(printf '%s\n' "$values" | sed -n 's/^FOUNDRY_EXISTING_ENDPOINT="\{0,1\}\([^"]*\)"\{0,1\}/\1/p')
|
|
20
|
+
api_version=$(printf '%s\n' "$values" | sed -n 's/^CU_API_VERSION="\{0,1\}\([^"]*\)"\{0,1\}/\1/p')
|
|
21
|
+
model_selection=$(printf '%s\n' "$values" | sed -n 's/^CU_MODEL_SELECTION="\{0,1\}\([^"]*\)"\{0,1\}/\1/p')
|
|
22
|
+
model_setup_complete=$(printf '%s\n' "$values" | sed -n 's/^CU_MODEL_SETUP_COMPLETE="\{0,1\}\([^"]*\)"\{0,1\}/\1/p')
|
|
23
|
+
assign_roles=$(printf '%s\n' "$values" | sed -n 's/^AZD_ASSIGN_ROLES="\{0,1\}\([^"]*\)"\{0,1\}/\1/p')
|
|
24
|
+
profile_setup_force=$(printf '%s\n' "$values" | sed -n 's/^CU_PROFILE_SETUP_FORCE="\{0,1\}\([^"]*\)"\{0,1\}/\1/p')
|
|
25
|
+
|
|
26
|
+
# Detect the right cu CLI command (macOS ships a built-in `cu` UUCP tool)
|
|
27
|
+
if command -v cu-cli >/dev/null 2>&1; then
|
|
28
|
+
CU_CMD="cu-cli"
|
|
29
|
+
elif command -v cu >/dev/null 2>&1; then
|
|
30
|
+
CU_CMD="cu"
|
|
31
|
+
else
|
|
32
|
+
CU_CMD=""
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
if [ -n "$existing_endpoint" ]; then
|
|
36
|
+
cat <<EOF
|
|
37
|
+
|
|
38
|
+
================================================================
|
|
39
|
+
Existing Microsoft Foundry resource configured
|
|
40
|
+
================================================================
|
|
41
|
+
Resource group : $rg
|
|
42
|
+
Account : $account
|
|
43
|
+
Endpoint : $endpoint
|
|
44
|
+
|
|
45
|
+
EOF
|
|
46
|
+
else
|
|
47
|
+
cat <<EOF
|
|
48
|
+
|
|
49
|
+
================================================================
|
|
50
|
+
Microsoft Foundry resource provisioned
|
|
51
|
+
================================================================
|
|
52
|
+
Resource group : $rg
|
|
53
|
+
Account : $account
|
|
54
|
+
Project : $project
|
|
55
|
+
Endpoint : $endpoint
|
|
56
|
+
|
|
57
|
+
EOF
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
model_setup_failed=false
|
|
61
|
+
if [ "$model_setup_complete" != "true" ]; then
|
|
62
|
+
if [ "$model_selection" = "none" ]; then
|
|
63
|
+
printf '[]\n' > infra/models.json
|
|
64
|
+
echo "No model deployments selected."
|
|
65
|
+
echo "Available without a large language model (LLM) or embeddings model: prebuilt-digitalParse, prebuilt-read, prebuilt-layout"
|
|
66
|
+
else
|
|
67
|
+
if [ -z "$CU_CMD" ]; then
|
|
68
|
+
echo "Could not set up optional model deployments because cu CLI is not on PATH."
|
|
69
|
+
model_setup_failed=true
|
|
70
|
+
elif [ "$assign_roles" = "false" ]; then
|
|
71
|
+
key=$(az cognitiveservices account keys list \
|
|
72
|
+
-g "$rg" -n "$account" --subscription "$subscription_id" \
|
|
73
|
+
--query key1 -o tsv 2>/dev/null || true)
|
|
74
|
+
if [ -z "$key" ]; then
|
|
75
|
+
echo "Could not obtain a Microsoft Foundry resource key for optional model setup."
|
|
76
|
+
model_setup_failed=true
|
|
77
|
+
elif ! CU_API_KEY="$key" CU_AUTH_MODE=key "$CU_CMD" _infra-models \
|
|
78
|
+
--resource-group "$rg" \
|
|
79
|
+
--account "$account" \
|
|
80
|
+
--subscription "$subscription_id" \
|
|
81
|
+
--selection "${model_selection:-prompt}" \
|
|
82
|
+
--out infra/models.json \
|
|
83
|
+
--deploy \
|
|
84
|
+
--endpoint "$endpoint" \
|
|
85
|
+
--api-version "${api_version:-2025-11-01}"; then
|
|
86
|
+
model_setup_failed=true
|
|
87
|
+
fi
|
|
88
|
+
elif ! "$CU_CMD" _infra-models \
|
|
89
|
+
--resource-group "$rg" \
|
|
90
|
+
--account "$account" \
|
|
91
|
+
--subscription "$subscription_id" \
|
|
92
|
+
--selection "${model_selection:-prompt}" \
|
|
93
|
+
--out infra/models.json \
|
|
94
|
+
--deploy \
|
|
95
|
+
--endpoint "$endpoint" \
|
|
96
|
+
--api-version "${api_version:-2025-11-01}" \
|
|
97
|
+
--auth-mode login; then
|
|
98
|
+
model_setup_failed=true
|
|
99
|
+
fi
|
|
100
|
+
fi
|
|
101
|
+
if [ "$model_setup_failed" = "false" ]; then
|
|
102
|
+
azd env set CU_MODEL_SETUP_COMPLETE true >/dev/null
|
|
103
|
+
fi
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
if [ "${CU_DISABLE_AUTO_PROFILE_SETUP:-}" = "true" ] || [ "${CU_AUTOCONFIG:-}" = "false" ]; then
|
|
107
|
+
echo "Automatic CU CLI profile setup disabled."
|
|
108
|
+
echo "To configure manually: cu-cli profile set endpoint $endpoint --name default"
|
|
109
|
+
exit 0
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
if [ -z "$CU_CMD" ]; then
|
|
113
|
+
echo "cu CLI not found on PATH. Install it to auto-configure:"
|
|
114
|
+
echo " pip install -e <path-to-cu-cli>"
|
|
115
|
+
echo "Then run: cu-cli profile set endpoint $endpoint --name default"
|
|
116
|
+
exit 0
|
|
117
|
+
fi
|
|
118
|
+
|
|
119
|
+
profile_status=0
|
|
120
|
+
"$CU_CMD" profile _has-values --name default >/dev/null 2>&1 || profile_status=$?
|
|
121
|
+
if [ "$profile_status" -eq 0 ] && [ "$profile_setup_force" != "true" ]; then
|
|
122
|
+
echo "Default CU CLI profile already has saved values; preserving it."
|
|
123
|
+
echo "Current default CU CLI profile:"
|
|
124
|
+
if ! "$CU_CMD" profile show --name default; then
|
|
125
|
+
echo "Could not display the preserved default CU CLI profile."
|
|
126
|
+
fi
|
|
127
|
+
echo "To replace its values, rerun cu infra generate with --force, then run azd up."
|
|
128
|
+
exit 0
|
|
129
|
+
elif [ "$profile_status" -ne 0 ] && [ "$profile_status" -ne 3 ]; then
|
|
130
|
+
echo "Could not inspect the default CU CLI profile; refusing to overwrite it."
|
|
131
|
+
echo "Run: $CU_CMD profile show --name default"
|
|
132
|
+
exit 1
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
setup_incomplete=false
|
|
136
|
+
auth_ready=true
|
|
137
|
+
endpoint_ready=false
|
|
138
|
+
if [ "$assign_roles" = "false" ]; then
|
|
139
|
+
if ! command -v az >/dev/null 2>&1; then
|
|
140
|
+
echo
|
|
141
|
+
echo "Roles were skipped and 'az' CLI is not on PATH."
|
|
142
|
+
echo "To enable key-based auth from cu, install az and run:"
|
|
143
|
+
echo " az login"
|
|
144
|
+
echo " cu profile set api_key \$(az cognitiveservices account keys list -g $rg -n $account --subscription $subscription_id --query key1 -o tsv) --name default"
|
|
145
|
+
auth_ready=false
|
|
146
|
+
setup_incomplete=true
|
|
147
|
+
elif ! az account show --subscription "$subscription_id" --only-show-errors >/dev/null 2>&1; then
|
|
148
|
+
echo
|
|
149
|
+
echo "Roles were skipped and 'az' isn't logged in (azd auth login is separate from az login)."
|
|
150
|
+
echo "To enable key-based auth from cu, run:"
|
|
151
|
+
echo " az login"
|
|
152
|
+
echo " cu profile set api_key \$(az cognitiveservices account keys list -g $rg -n $account --subscription $subscription_id --query key1 -o tsv) --name default"
|
|
153
|
+
auth_ready=false
|
|
154
|
+
setup_incomplete=true
|
|
155
|
+
else
|
|
156
|
+
echo "Roles were skipped; fetching account key for cu..."
|
|
157
|
+
key=$(az cognitiveservices account keys list -g "$rg" -n "$account" --subscription "$subscription_id" --query key1 -o tsv 2>/dev/null || true)
|
|
158
|
+
if [ -n "$key" ] && $CU_CMD profile set api_key "$key" --name default; then
|
|
159
|
+
echo "API key written to the default CU CLI profile."
|
|
160
|
+
else
|
|
161
|
+
echo "Could not configure key authentication."
|
|
162
|
+
echo "Try: az cognitiveservices account keys list -g $rg -n $account --subscription $subscription_id"
|
|
163
|
+
auth_ready=false
|
|
164
|
+
setup_incomplete=true
|
|
165
|
+
fi
|
|
166
|
+
fi
|
|
167
|
+
else
|
|
168
|
+
echo "Configuring cu CLI to use Entra authentication..."
|
|
169
|
+
if ! $CU_CMD profile set auth_mode login --name default; then
|
|
170
|
+
echo "Could not configure Entra authentication."
|
|
171
|
+
auth_ready=false
|
|
172
|
+
setup_incomplete=true
|
|
173
|
+
fi
|
|
174
|
+
fi
|
|
175
|
+
|
|
176
|
+
echo "Configuring cu CLI endpoint..."
|
|
177
|
+
if $CU_CMD profile set endpoint "$endpoint" --name default; then
|
|
178
|
+
endpoint_ready=true
|
|
179
|
+
else
|
|
180
|
+
echo "Could not configure the cu CLI endpoint."
|
|
181
|
+
setup_incomplete=true
|
|
182
|
+
fi
|
|
183
|
+
|
|
184
|
+
echo "Configuring prebuilt-layout as the default analyzer..."
|
|
185
|
+
if ! $CU_CMD profile set default_analyzer prebuilt-layout --name default; then
|
|
186
|
+
echo "Could not configure the default analyzer."
|
|
187
|
+
setup_incomplete=true
|
|
188
|
+
fi
|
|
189
|
+
|
|
190
|
+
maybe_set_defaults=false
|
|
191
|
+
defaults_initialized=false
|
|
192
|
+
defaults_failed=false
|
|
193
|
+
dep_completion=""
|
|
194
|
+
dep_mini=""
|
|
195
|
+
dep_embedding=""
|
|
196
|
+
completion_ready=false
|
|
197
|
+
embedding_ready=false
|
|
198
|
+
if command -v az >/dev/null 2>&1 && az account show --subscription "$subscription_id" --only-show-errors >/dev/null 2>&1; then
|
|
199
|
+
# Discover all deployed models and configure mappings dynamically.
|
|
200
|
+
# Use a POSIX here-doc (not a bash `<<<` here-string) so this runs under
|
|
201
|
+
# /bin/sh (dash), and so the loop stays in the current shell and the flag
|
|
202
|
+
# variables set below persist. `tab` is a literal tab for the TSV columns.
|
|
203
|
+
tab=$(printf '\t')
|
|
204
|
+
deployments=$(az cognitiveservices account deployment list \
|
|
205
|
+
-g "$rg" -n "$account" --subscription "$subscription_id" \
|
|
206
|
+
--query "[].{dep:name,model:properties.model.name,state:properties.provisioningState}" \
|
|
207
|
+
-o tsv 2>/dev/null || true)
|
|
208
|
+
while IFS="$tab" read -r dep_name model_name deployment_state; do
|
|
209
|
+
[ -z "$dep_name" ] && continue
|
|
210
|
+
$CU_CMD profile set "model_deployments.$model_name" "$dep_name" --name default
|
|
211
|
+
maybe_set_defaults=true
|
|
212
|
+
case "$model_name" in
|
|
213
|
+
text-embedding-*)
|
|
214
|
+
[ -z "$dep_embedding" ] && dep_embedding="$dep_name"
|
|
215
|
+
[ "$deployment_state" = "Succeeded" ] && embedding_ready=true
|
|
216
|
+
;;
|
|
217
|
+
*-mini)
|
|
218
|
+
[ -z "$dep_mini" ] && dep_mini="$dep_name"
|
|
219
|
+
[ -z "$dep_completion" ] && dep_completion="$dep_name"
|
|
220
|
+
[ "$deployment_state" = "Succeeded" ] && completion_ready=true
|
|
221
|
+
;;
|
|
222
|
+
*)
|
|
223
|
+
[ -z "$dep_completion" ] && dep_completion="$dep_name"
|
|
224
|
+
[ "$deployment_state" = "Succeeded" ] && completion_ready=true
|
|
225
|
+
;;
|
|
226
|
+
esac
|
|
227
|
+
done <<EOF
|
|
228
|
+
$deployments
|
|
229
|
+
EOF
|
|
230
|
+
fi
|
|
231
|
+
|
|
232
|
+
if [ "$maybe_set_defaults" = "true" ]; then
|
|
233
|
+
completion_dep="$dep_completion"
|
|
234
|
+
mini_dep="$dep_mini"
|
|
235
|
+
[ -z "$mini_dep" ] && mini_dep="$completion_dep"
|
|
236
|
+
if [ -n "$completion_dep" ]; then
|
|
237
|
+
$CU_CMD profile set "model_deployments.prebuilt-analyzer-completion" "$completion_dep" --name default
|
|
238
|
+
$CU_CMD profile set "model_deployments.prebuilt-analyzer-completion-mini" "$mini_dep" --name default
|
|
239
|
+
fi
|
|
240
|
+
if [ -n "$dep_embedding" ]; then
|
|
241
|
+
$CU_CMD profile set "model_deployments.prebuilt-analyzer-embedding" "$dep_embedding" --name default
|
|
242
|
+
fi
|
|
243
|
+
echo "Initializing Foundry defaults from configured model deployments..."
|
|
244
|
+
if $CU_CMD defaults set --from-profile --profile default >/dev/null 2>&1; then
|
|
245
|
+
echo "Foundry defaults initialized."
|
|
246
|
+
defaults_initialized=true
|
|
247
|
+
else
|
|
248
|
+
echo "Could not initialize Foundry defaults automatically."
|
|
249
|
+
echo "Run: $CU_CMD defaults set --from-profile --profile default"
|
|
250
|
+
defaults_failed=true
|
|
251
|
+
fi
|
|
252
|
+
fi
|
|
253
|
+
|
|
254
|
+
llm_ready=false
|
|
255
|
+
if [ "$defaults_initialized" = "true" ] &&
|
|
256
|
+
[ "$completion_ready" = "true" ] &&
|
|
257
|
+
[ "$embedding_ready" = "true" ]; then
|
|
258
|
+
llm_ready=true
|
|
259
|
+
echo "Model readiness verified: LLM and embeddings model deployments succeeded and Content Understanding defaults are configured."
|
|
260
|
+
fi
|
|
261
|
+
|
|
262
|
+
echo
|
|
263
|
+
if [ "$setup_incomplete" = "true" ]; then
|
|
264
|
+
echo "Azure provisioning completed, but cu auto-configuration is incomplete."
|
|
265
|
+
echo "Run: $CU_CMD doctor"
|
|
266
|
+
exit 1
|
|
267
|
+
fi
|
|
268
|
+
echo "Setup complete."
|
|
269
|
+
if [ "$endpoint_ready" = "true" ]; then
|
|
270
|
+
echo "Default CU CLI profile configured:"
|
|
271
|
+
if ! "$CU_CMD" profile show --name default; then
|
|
272
|
+
echo " Warning: profile setup succeeded, but its values could not be displayed."
|
|
273
|
+
fi
|
|
274
|
+
echo
|
|
275
|
+
echo " Verify setup with:"
|
|
276
|
+
echo " $CU_CMD doctor"
|
|
277
|
+
fi
|
|
278
|
+
if [ "$endpoint_ready" = "true" ] && [ "$auth_ready" = "true" ]; then
|
|
279
|
+
echo " Available without an LLM or embeddings model: prebuilt-digitalParse, prebuilt-read, prebuilt-layout"
|
|
280
|
+
echo " Content extraction sanity check:"
|
|
281
|
+
echo " $CU_CMD analyze <file> --analyzer prebuilt-layout"
|
|
282
|
+
fi
|
|
283
|
+
if [ "$model_setup_failed" = "true" ]; then
|
|
284
|
+
echo " Optional model setup failed; the Microsoft Foundry resource and CU CLI profile are still ready."
|
|
285
|
+
echo " Resolve the deployment issue, then rerun azd up before using generative AI"
|
|
286
|
+
echo " prebuilt analyzers such as prebuilt-invoice or custom analyzers."
|
|
287
|
+
elif [ "$llm_ready" = "true" ]; then
|
|
288
|
+
echo " Custom analyzer workflow:"
|
|
289
|
+
echo " $CU_CMD analyzer schema create --from-sample <file> --output-file schema.json"
|
|
290
|
+
echo " $CU_CMD analyzer create --name my-analyzer --schema schema.json"
|
|
291
|
+
echo " $CU_CMD analyze <file> --analyzer my-analyzer"
|
|
292
|
+
elif [ "$defaults_failed" = "true" ]; then
|
|
293
|
+
echo " Generative AI workflows are not ready because Content Understanding defaults configuration failed."
|
|
294
|
+
echo " Repair with: $CU_CMD defaults set --from-profile --profile default"
|
|
295
|
+
elif [ "$maybe_set_defaults" = "true" ]; then
|
|
296
|
+
echo " Generative AI workflows require succeeded LLM and embeddings model deployments."
|
|
297
|
+
else
|
|
298
|
+
echo " No optional models were configured; content extraction analyzers remain available."
|
|
299
|
+
fi
|