aui-agent-builder 0.3.104 → 0.3.106
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.
- package/dist/commands/import-agent.d.ts.map +1 -1
- package/dist/commands/import-agent.js +198 -95
- package/dist/commands/import-agent.js.map +1 -1
- package/dist/commands/legacy/push-records-mode.d.ts.map +1 -1
- package/dist/commands/legacy/push-records-mode.js +49 -10
- package/dist/commands/legacy/push-records-mode.js.map +1 -1
- package/dist/commands/pull-agent.js +74 -34
- package/dist/commands/pull-agent.js.map +1 -1
- package/dist/commands/push.js +145 -22
- package/dist/commands/push.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"import-agent.d.ts","sourceRoot":"","sources":["../../src/commands/import-agent.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAwDH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,wBAAwB,EAAE,UAAU,CAAC;IACzD,MAAM,CAAC,EAAE,OAAO,oCAAoC,EAAE,WAAW,EAAE,CAAC;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAmED,wBAAsB,WAAW,CAC/B,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAiBf;
|
|
1
|
+
{"version":3,"file":"import-agent.d.ts","sourceRoot":"","sources":["../../src/commands/import-agent.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAwDH,MAAM,WAAW,aAAa;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,OAAO,wBAAwB,EAAE,UAAU,CAAC;IACzD,MAAM,CAAC,EAAE,OAAO,oCAAoC,EAAE,WAAW,EAAE,CAAC;IACpE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAmED,wBAAsB,WAAW,CAC/B,OAAO,CAAC,EAAE,MAAM,EAChB,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAiBf;AAqVD,wBAAsB,sBAAsB,CAC1C,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAgBf;AAoFD,wBAAsB,kBAAkB,CACtC,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,IAAI,CAAC,CAgBf"}
|
|
@@ -128,69 +128,148 @@ async function _importAgent(parentSpan, agentId, options = {}) {
|
|
|
128
128
|
// those are `agent_management_id`s (also 24-char hex, but a
|
|
129
129
|
// different document family). Same regex, different collection.
|
|
130
130
|
//
|
|
131
|
-
//
|
|
132
|
-
//
|
|
133
|
-
//
|
|
134
|
-
//
|
|
135
|
-
//
|
|
136
|
-
//
|
|
137
|
-
//
|
|
131
|
+
// Resolution order (first success wins, then we cache the resolved
|
|
132
|
+
// `AgentInfo` as `knownAgentInfo` so `selectVersionForAgent` /
|
|
133
|
+
// `doImport` skip a duplicate lookup AND the new `/pull` endpoint
|
|
134
|
+
// is reachable on the first import attempt):
|
|
135
|
+
//
|
|
136
|
+
// 0) listAgents with BOTH `network_id=<input>` AND
|
|
137
|
+
// `network_category_id=<input>` — handles the case where the
|
|
138
|
+
// input is either a legacy `network_id` (regular agent) or a
|
|
139
|
+
// `network_category_id` (template). The server OR's the two
|
|
140
|
+
// filters, so a single call covers both shapes (verified
|
|
141
|
+
// 2026-05-27 against staging — see thread with Adli). If the
|
|
142
|
+
// input is actually an `agent_management_id`, listAgents
|
|
143
|
+
// returns no items (an agent_management_id is almost never
|
|
144
|
+
// also a network_id / category_id of a DIFFERENT agent), and
|
|
145
|
+
// we fall through to step 1.
|
|
146
|
+
//
|
|
147
|
+
// Originally added (2026-05-26) as a [TEMP] workaround for
|
|
148
|
+
// the BFF passing `network_id` instead of `agent_management_id`.
|
|
149
|
+
// Promoted to the canonical first step once we extended it
|
|
150
|
+
// to also resolve `network_category_id` — there is no longer
|
|
151
|
+
// a "remove once the BFF migrates" exit condition because the
|
|
152
|
+
// template case has no other resolver (templates never appear
|
|
153
|
+
// in `networks.get` and `getAgent(category_id)` 404s).
|
|
154
|
+
//
|
|
155
|
+
// 1) getAgent(<input>) — treat the id as an agent_management_id.
|
|
156
|
+
// Still the canonical path for callers that already have it.
|
|
157
|
+
//
|
|
158
|
+
// 2) networks.get(<input>) — last-ditch legacy networks lookup.
|
|
159
|
+
// Kept for back-compat with old scripts that have neither
|
|
160
|
+
// flow available (e.g. agent-management endpoint down).
|
|
138
161
|
const spinner = startSpinner("Fetching agent...");
|
|
139
162
|
let resolved = false;
|
|
140
163
|
let lastErr;
|
|
141
|
-
//
|
|
164
|
+
// 0) listAgents with both `network_id` and `network_category_id`
|
|
165
|
+
// set to the input id — server OR's the filters, returning
|
|
166
|
+
// either a regular agent (matched by `scope.network_id`) or a
|
|
167
|
+
// template (matched by `scope.network_category_id`). If the
|
|
168
|
+
// input is actually an `agent_management_id`, neither filter
|
|
169
|
+
// matches and we fall through to step 1.
|
|
142
170
|
try {
|
|
143
|
-
const
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
//
|
|
148
|
-
//
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
if (
|
|
155
|
-
|
|
171
|
+
const resp = await client.agentManagement.listAgents(client.getOrganizationId(), 1, 50, {
|
|
172
|
+
network_id: effectiveAgentId,
|
|
173
|
+
network_category_id: effectiveAgentId,
|
|
174
|
+
});
|
|
175
|
+
// `find` (not `[0]`) to be defensive about the server returning
|
|
176
|
+
// unrelated rows. We require `scope.network_id === <input>` for
|
|
177
|
+
// the regular-agent case OR `scope.network_category_id === <input>`
|
|
178
|
+
// for the template case so siblings on the same listing page
|
|
179
|
+
// can't accidentally win.
|
|
180
|
+
const match = resp.items.find((a) => a.scope.network_id === effectiveAgentId ||
|
|
181
|
+
a.scope.network_category_id === effectiveAgentId);
|
|
182
|
+
if (match) {
|
|
183
|
+
knownAgentInfo = match;
|
|
184
|
+
selectedAgent = agentInfoToNetwork(match);
|
|
185
|
+
// Bias scope toward the agent's own org/account (mirrors the
|
|
186
|
+
// step-1 success branch — keep both in sync). Templates have
|
|
187
|
+
// `scope.account_id === null` (category-scoped, not account-
|
|
188
|
+
// scoped) — skipping the scope update in that case keeps the
|
|
189
|
+
// session's org context as-is, which is what downstream
|
|
190
|
+
// template flows expect.
|
|
191
|
+
const scopeUpdate = {};
|
|
192
|
+
if (match.scope?.account_id)
|
|
193
|
+
scopeUpdate.accountId = match.scope.account_id;
|
|
194
|
+
if (match.scope?.organization_id)
|
|
195
|
+
scopeUpdate.organizationId = match.scope.organization_id;
|
|
196
|
+
if (scopeUpdate.accountId || scopeUpdate.organizationId) {
|
|
197
|
+
client.setScope(scopeUpdate);
|
|
198
|
+
}
|
|
199
|
+
const matchedVia = match.scope.network_id === effectiveAgentId
|
|
200
|
+
? "network_id"
|
|
201
|
+
: "network_category_id";
|
|
202
|
+
spinner.succeed(`Found agent (via listAgents ${matchedVia} lookup): ${match.name}`);
|
|
203
|
+
resolved = true;
|
|
204
|
+
}
|
|
205
|
+
else if (process.env.AUI_DEBUG) {
|
|
206
|
+
console.log(`[debug] listAgents(network_id=${effectiveAgentId}, network_category_id=${effectiveAgentId}) returned ${resp.items.length} row(s) but none matched; trying getAgent next`);
|
|
156
207
|
}
|
|
157
|
-
spinner.succeed(`Found agent (via agent-management): ${ami.name}`);
|
|
158
|
-
resolved = true;
|
|
159
208
|
}
|
|
160
209
|
catch (err) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
err.status);
|
|
166
|
-
// Fall through to the legacy networks lookup on ANY non-auth
|
|
167
|
-
// error — not just 404. Rationale (2026-05-24):
|
|
168
|
-
//
|
|
169
|
-
// - 404 ⇒ id isn't an agent_management_id; try as network_id.
|
|
170
|
-
// - 422 ⇒ the new agent-settings response schema has stricter
|
|
171
|
-
// validation than some legacy docs (e.g. the post-`kind`
|
|
172
|
-
// rollout returned 422 for any pre-rollout agent until
|
|
173
|
-
// a backfill landed). The legacy networks endpoint
|
|
174
|
-
// lives in a different service and doesn't share that
|
|
175
|
-
// validation, so it can still resolve the same agent.
|
|
176
|
-
// - 5xx / network blip ⇒ a transient agent-settings failure
|
|
177
|
-
// shouldn't block the import when there's an alternate
|
|
178
|
-
// resolver available; the legacy attempt will either
|
|
179
|
-
// succeed (problem masked) or 4xx itself (we report
|
|
180
|
-
// the more informative agent-settings error via
|
|
181
|
-
// `lastErr` at the end of step 2).
|
|
182
|
-
//
|
|
183
|
-
// Auth errors (401/403) STILL fail loudly here — no point in
|
|
184
|
-
// trying the next endpoint with the same credentials.
|
|
185
|
-
if (isAuthError(err)) {
|
|
186
|
-
spinner.fail("Authentication failed");
|
|
187
|
-
handleAuthError(err);
|
|
188
|
-
throw err;
|
|
189
|
-
}
|
|
210
|
+
// Listing failed (auth / 5xx / org context wrong). Don't bail
|
|
211
|
+
// — fall through to the existing dual-shape resolution. Worst
|
|
212
|
+
// case we make the same call sequence we'd have made before
|
|
213
|
+
// this resolver was added.
|
|
190
214
|
if (process.env.AUI_DEBUG) {
|
|
191
|
-
console.log(`[debug]
|
|
215
|
+
console.log(`[debug] listAgents(network_id=${effectiveAgentId}, network_category_id=${effectiveAgentId}) failed: ${err instanceof Error ? err.message : err}; trying getAgent next`);
|
|
192
216
|
}
|
|
193
217
|
}
|
|
218
|
+
// 1) Treat the id as an agent-management UUID.
|
|
219
|
+
if (!resolved) {
|
|
220
|
+
try {
|
|
221
|
+
const ami = await client.agentManagement.getAgent(effectiveAgentId);
|
|
222
|
+
knownAgentInfo = ami;
|
|
223
|
+
selectedAgent = agentInfoToNetwork(ami);
|
|
224
|
+
// Bias the client scope toward the agent's own org/account so
|
|
225
|
+
// downstream listAgents/listVersions calls don't 403 against the
|
|
226
|
+
// session's default scope.
|
|
227
|
+
const scopeUpdate = {};
|
|
228
|
+
if (ami.scope?.account_id)
|
|
229
|
+
scopeUpdate.accountId = ami.scope.account_id;
|
|
230
|
+
if (ami.scope?.organization_id)
|
|
231
|
+
scopeUpdate.organizationId = ami.scope.organization_id;
|
|
232
|
+
if (scopeUpdate.accountId || scopeUpdate.organizationId) {
|
|
233
|
+
client.setScope(scopeUpdate);
|
|
234
|
+
}
|
|
235
|
+
spinner.succeed(`Found agent (via agent-management): ${ami.name}`);
|
|
236
|
+
resolved = true;
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
lastErr = err;
|
|
240
|
+
const status = err instanceof AUIAPIError
|
|
241
|
+
? err.status
|
|
242
|
+
: (err.statusCode ??
|
|
243
|
+
err.status);
|
|
244
|
+
// Fall through to the legacy networks lookup on ANY non-auth
|
|
245
|
+
// error — not just 404. Rationale (2026-05-24):
|
|
246
|
+
//
|
|
247
|
+
// - 404 ⇒ id isn't an agent_management_id; try as network_id.
|
|
248
|
+
// - 422 ⇒ the new agent-settings response schema has stricter
|
|
249
|
+
// validation than some legacy docs (e.g. the post-`kind`
|
|
250
|
+
// rollout returned 422 for any pre-rollout agent until
|
|
251
|
+
// a backfill landed). The legacy networks endpoint
|
|
252
|
+
// lives in a different service and doesn't share that
|
|
253
|
+
// validation, so it can still resolve the same agent.
|
|
254
|
+
// - 5xx / network blip ⇒ a transient agent-settings failure
|
|
255
|
+
// shouldn't block the import when there's an alternate
|
|
256
|
+
// resolver available; the legacy attempt will either
|
|
257
|
+
// succeed (problem masked) or 4xx itself (we report
|
|
258
|
+
// the more informative agent-settings error via
|
|
259
|
+
// `lastErr` at the end of step 2).
|
|
260
|
+
//
|
|
261
|
+
// Auth errors (401/403) STILL fail loudly here — no point in
|
|
262
|
+
// trying the next endpoint with the same credentials.
|
|
263
|
+
if (isAuthError(err)) {
|
|
264
|
+
spinner.fail("Authentication failed");
|
|
265
|
+
handleAuthError(err);
|
|
266
|
+
throw err;
|
|
267
|
+
}
|
|
268
|
+
if (process.env.AUI_DEBUG) {
|
|
269
|
+
console.log(`[debug] agentManagement.getAgent(${effectiveAgentId}) → ${status ?? "non-auth error"}; trying legacy networks.get next`);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
} // close: if (!resolved) — wrapping step 1 (added with step 0 above)
|
|
194
273
|
// 2) Fall back: treat the id as a legacy network_id.
|
|
195
274
|
if (!resolved) {
|
|
196
275
|
try {
|
|
@@ -1035,55 +1114,72 @@ knownAgentInfo) {
|
|
|
1035
1114
|
}
|
|
1036
1115
|
}
|
|
1037
1116
|
}
|
|
1038
|
-
// ───
|
|
1117
|
+
// ─── Mode dispatch (with pure-legacy short-circuit) ─────────────
|
|
1118
|
+
//
|
|
1119
|
+
// Three layers, in order:
|
|
1120
|
+
//
|
|
1121
|
+
// 1. No agent_management_id at all (pure legacy)
|
|
1122
|
+
// → The agent exists in `networks` (step 2 of resolution) but
|
|
1123
|
+
// not in agent-management. It predates the agent-management
|
|
1124
|
+
// rollout entirely, which means it predates `bundle_mode`,
|
|
1125
|
+
// which means it can only be records-mode. Skip the
|
|
1126
|
+
// `detectAgentBundleMode` call (it'd need an
|
|
1127
|
+
// agent_management_id we don't have) and force-route to
|
|
1128
|
+
// records-mode dispatch. `exportAgent(...)` is happy with
|
|
1129
|
+
// scope filters alone — no agent_management_id needed.
|
|
1039
1130
|
//
|
|
1040
|
-
//
|
|
1041
|
-
//
|
|
1042
|
-
//
|
|
1043
|
-
//
|
|
1044
|
-
//
|
|
1045
|
-
//
|
|
1046
|
-
// Pushed via the new endpoint yet, and may be re-enabled later if a
|
|
1047
|
-
// migration adapter is needed.
|
|
1131
|
+
// Concrete repro (2026-05-26): `aui import 6a0cb854...` (a
|
|
1132
|
+
// legacy `test-v15` network) found the agent via
|
|
1133
|
+
// `networks.get` but `listAgents(network_id=…)` returned
|
|
1134
|
+
// nothing. Without this branch, the import bailed with
|
|
1135
|
+
// "Could not resolve agent_management_id for this agent"
|
|
1136
|
+
// even though `exportAgent` would have worked.
|
|
1048
1137
|
//
|
|
1049
|
-
//
|
|
1050
|
-
//
|
|
1051
|
-
//
|
|
1052
|
-
//
|
|
1053
|
-
//
|
|
1054
|
-
//
|
|
1055
|
-
//
|
|
1056
|
-
//
|
|
1057
|
-
|
|
1058
|
-
if (!
|
|
1138
|
+
// 2. Agent_management_id present → call `detectAgentBundleMode`
|
|
1139
|
+
// to read the agent's `bundle_mode` flag. Routes to /pull
|
|
1140
|
+
// (bundle) or per-entity /view (records) accordingly.
|
|
1141
|
+
//
|
|
1142
|
+
// 3. Bundle mode + no version_id → hard error. /pull is keyed
|
|
1143
|
+
// on version_id in the URL and can't fall back to scope
|
|
1144
|
+
// filters. Records-mode + no version_id is fine —
|
|
1145
|
+
// `exportAgent` handles it via scope-level filters.
|
|
1146
|
+
let importModeResolution;
|
|
1147
|
+
if (!effectiveAgentMgmtId) {
|
|
1148
|
+
// (1) Pure legacy — force records mode, skip the dispatcher call
|
|
1149
|
+
// entirely (it'd throw since we have no id to pass it).
|
|
1150
|
+
importModeResolution = { mode: "records", source: "no_agent_management_id" };
|
|
1151
|
+
if (process.env.AUI_DEBUG) {
|
|
1152
|
+
console.log(`[debug] doImport: no agent_management_id for network ${networkId} — forcing records-mode dispatch (pure-legacy agent)`);
|
|
1153
|
+
}
|
|
1154
|
+
}
|
|
1155
|
+
else {
|
|
1156
|
+
// (2) Normal dispatch path — agent_management_id resolved, ask
|
|
1157
|
+
// the server which mode to use. Reuses `knownAgentInfo` so we
|
|
1158
|
+
// don't pay an extra `GET /v1/agents/{id}` round-trip.
|
|
1159
|
+
importModeResolution = await detectAgentBundleMode(client, effectiveAgentMgmtId, knownAgentInfo);
|
|
1160
|
+
}
|
|
1161
|
+
// (3) Bundle mode requires version_id. Records mode doesn't —
|
|
1162
|
+
// `exportAgent` falls back to scope filters when versionId is
|
|
1163
|
+
// undefined (the legacy contract that's been in the CLI since
|
|
1164
|
+
// before version management existed).
|
|
1165
|
+
if (importModeResolution.mode === "bundle" && !versionId) {
|
|
1059
1166
|
throw new ConfigError("No version_id available for the new /pull endpoint.", {
|
|
1060
|
-
suggestion: "Pass --version <versionId>, or re-run `aui import` interactively so a version can be selected.
|
|
1167
|
+
suggestion: "Pass --version <versionId>, or re-run `aui import` interactively so a version can be selected. " +
|
|
1168
|
+
"Bundle-mode agents must have at least one push (creates v{N}.1) before they can be imported via /pull. " +
|
|
1169
|
+
"If this is a fresh bundle-mode agent, run `aui push` from the source project first, then re-import.",
|
|
1061
1170
|
});
|
|
1062
1171
|
}
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1172
|
+
// Bundle mode ALSO requires an agent_management_id (it's in the
|
|
1173
|
+
// /pull URL path). This was implicit before — `detectAgentBundleMode`
|
|
1174
|
+
// would have thrown — but now that we short-circuit to records when
|
|
1175
|
+
// agent_management_id is missing, we should only ever reach this
|
|
1176
|
+
// branch when bundle mode was a real positive detection. Keep the
|
|
1177
|
+
// guard for defensive symmetry with the records path above.
|
|
1178
|
+
if (importModeResolution.mode === "bundle" && !effectiveAgentMgmtId) {
|
|
1179
|
+
throw new ConfigError("Could not resolve agent_management_id for this bundle-mode agent.", {
|
|
1180
|
+
suggestion: "Pass the agent_management_id directly as the positional arg, or verify the agent exists in agent-management (`listAgents(network_id=…)`).",
|
|
1066
1181
|
});
|
|
1067
1182
|
}
|
|
1068
|
-
// ─── Mode dispatch ────────────────────────────────────────────────
|
|
1069
|
-
// Restored 2026-05-24. Detect `Agent.bundle_mode` once via the agent
|
|
1070
|
-
// record we already resolved, then either:
|
|
1071
|
-
//
|
|
1072
|
-
// - bundle mode → call new `/pull` endpoint (existing logic
|
|
1073
|
-
// below; strict 404 → "run aui push first")
|
|
1074
|
-
// - records mode → fall back to per-entity `/view` endpoints via
|
|
1075
|
-
// `client.exportAgent(...)` and reconstruct
|
|
1076
|
-
// canonical .aui.json files locally
|
|
1077
|
-
//
|
|
1078
|
-
// The two surfaces are mutually exclusive at the API layer; calling
|
|
1079
|
-
// the wrong one returns 422 (or empty payload for legacy reads
|
|
1080
|
-
// against blob-mode), which the user can't recover from at the
|
|
1081
|
-
// CLI level. We dispatch BEFORE any /pull or /view call so the
|
|
1082
|
-
// first attempt is always the right surface.
|
|
1083
|
-
// Reuse the AgentInfo from step 1 / selectAgentFromList when we have
|
|
1084
|
-
// it — saves one `GET /v1/agents/{id}` and avoids the duplicate-fetch
|
|
1085
|
-
// observed in the 2026-05-24 trace.
|
|
1086
|
-
const importModeResolution = await detectAgentBundleMode(client, effectiveAgentMgmtId, knownAgentInfo);
|
|
1087
1183
|
if (span) {
|
|
1088
1184
|
span.setAttribute("import.dispatch.mode", importModeResolution.mode);
|
|
1089
1185
|
span.setAttribute("import.dispatch.mode_source", importModeResolution.source);
|
|
@@ -1203,6 +1299,13 @@ knownAgentInfo) {
|
|
|
1203
1299
|
}
|
|
1204
1300
|
else {
|
|
1205
1301
|
// ─── Blob-mode (new /pull endpoint) ─────────────────────────
|
|
1302
|
+
//
|
|
1303
|
+
// `versionId!` assertion: we reach this branch only when
|
|
1304
|
+
// `useLegacyImport === false` (bundle mode), and the conditional
|
|
1305
|
+
// throw above ("No version_id available for the new /pull
|
|
1306
|
+
// endpoint.") already guarantees `versionId` is defined in
|
|
1307
|
+
// that case. TS can't narrow across the throw, so the
|
|
1308
|
+
// assertion is documented intent rather than a hand-wave.
|
|
1206
1309
|
let pullData = null;
|
|
1207
1310
|
try {
|
|
1208
1311
|
pullData = await tryPullViaBlobEndpoint(client, effectiveAgentMgmtId, versionId, options.tag);
|