pilotswarm-sdk 0.5.63 → 0.5.65
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/api/src/admin-diagnostics.d.ts +12 -0
- package/api/src/admin-diagnostics.js +38 -1
- package/api/src/http-api-transport.js +26 -0
- package/api/src/protocol.js +15 -0
- package/dist/activity-routing.d.ts +21 -0
- package/dist/activity-routing.d.ts.map +1 -0
- package/dist/activity-routing.js +32 -0
- package/dist/activity-routing.js.map +1 -0
- package/dist/agent-discovery.d.ts +35 -0
- package/dist/agent-discovery.d.ts.map +1 -0
- package/dist/agent-discovery.js +107 -0
- package/dist/agent-discovery.js.map +1 -0
- package/dist/client.d.ts +9 -1
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +94 -12
- package/dist/client.js.map +1 -1
- package/dist/cms-migrations.d.ts.map +1 -1
- package/dist/cms-migrations.js +4 -0
- package/dist/cms-migrations.js.map +1 -1
- package/dist/cms.d.ts +3 -0
- package/dist/cms.d.ts.map +1 -1
- package/dist/cms.js +7 -0
- package/dist/cms.js.map +1 -1
- package/dist/feature-flag-cache.d.ts +40 -0
- package/dist/feature-flag-cache.d.ts.map +1 -0
- package/dist/feature-flag-cache.js +125 -0
- package/dist/feature-flag-cache.js.map +1 -0
- package/dist/feature-flags.d.ts +68 -0
- package/dist/feature-flags.d.ts.map +1 -0
- package/dist/feature-flags.js +45 -0
- package/dist/feature-flags.js.map +1 -0
- package/dist/feature-store.d.ts +55 -0
- package/dist/feature-store.d.ts.map +1 -0
- package/dist/feature-store.js +106 -0
- package/dist/feature-store.js.map +1 -0
- package/dist/feature-tools.d.ts +94 -0
- package/dist/feature-tools.d.ts.map +1 -0
- package/dist/feature-tools.js +60 -0
- package/dist/feature-tools.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/managed-session.d.ts +4 -0
- package/dist/managed-session.d.ts.map +1 -1
- package/dist/managed-session.js +120 -23
- package/dist/managed-session.js.map +1 -1
- package/dist/management-client.d.ts +18 -0
- package/dist/management-client.d.ts.map +1 -1
- package/dist/management-client.js +19 -0
- package/dist/management-client.js.map +1 -1
- package/dist/migrations/feature-flags-0077.d.ts +3 -0
- package/dist/migrations/feature-flags-0077.d.ts.map +1 -0
- package/dist/migrations/feature-flags-0077.js +271 -0
- package/dist/migrations/feature-flags-0077.js.map +1 -0
- package/dist/migrations/native-tasks-default-policy-0078.d.ts +3 -0
- package/dist/migrations/native-tasks-default-policy-0078.d.ts.map +1 -0
- package/dist/migrations/native-tasks-default-policy-0078.js +21 -0
- package/dist/migrations/native-tasks-default-policy-0078.js.map +1 -0
- package/dist/native-subagents.d.ts +25 -0
- package/dist/native-subagents.d.ts.map +1 -0
- package/dist/native-subagents.js +191 -0
- package/dist/native-subagents.js.map +1 -0
- package/dist/native-task-observer.d.ts +87 -0
- package/dist/native-task-observer.d.ts.map +1 -0
- package/dist/native-task-observer.js +268 -0
- package/dist/native-task-observer.js.map +1 -0
- package/dist/orchestration/agents.d.ts +8 -3
- package/dist/orchestration/agents.d.ts.map +1 -1
- package/dist/orchestration/agents.js +87 -36
- package/dist/orchestration/agents.js.map +1 -1
- package/dist/orchestration/index.d.ts +2 -2
- package/dist/orchestration/index.js +1 -1
- package/dist/orchestration/lifecycle.js +1 -1
- package/dist/orchestration/lifecycle.js.map +1 -1
- package/dist/orchestration/runtime.d.ts +1 -1
- package/dist/orchestration/runtime.d.ts.map +1 -1
- package/dist/orchestration/runtime.js +18 -4
- package/dist/orchestration/runtime.js.map +1 -1
- package/dist/orchestration/turn.d.ts.map +1 -1
- package/dist/orchestration/turn.js +3 -5
- package/dist/orchestration/turn.js.map +1 -1
- package/dist/orchestration-registry.d.ts.map +1 -1
- package/dist/orchestration-registry.js +12 -2
- package/dist/orchestration-registry.js.map +1 -1
- package/dist/orchestration-version.d.ts +1 -1
- package/dist/orchestration-version.js +1 -1
- package/dist/orchestration.d.ts +2 -2
- package/dist/orchestration.js +1 -1
- package/dist/orchestration_1_0_46.d.ts +1 -1
- package/dist/orchestration_1_0_47.d.ts +1 -1
- package/dist/orchestration_1_0_48.d.ts +1 -1
- package/dist/orchestration_1_0_49.d.ts +1 -1
- package/dist/orchestration_1_0_50.d.ts +1 -1
- package/dist/orchestration_1_0_73/agents.d.ts +61 -0
- package/dist/orchestration_1_0_73/agents.d.ts.map +1 -0
- package/dist/orchestration_1_0_73/agents.js +843 -0
- package/dist/orchestration_1_0_73/agents.js.map +1 -0
- package/dist/orchestration_1_0_73/index.d.ts +24 -0
- package/dist/orchestration_1_0_73/index.d.ts.map +1 -0
- package/dist/orchestration_1_0_73/index.js +13 -0
- package/dist/orchestration_1_0_73/index.js.map +1 -0
- package/dist/orchestration_1_0_73/lifecycle.d.ts +51 -0
- package/dist/orchestration_1_0_73/lifecycle.d.ts.map +1 -0
- package/dist/orchestration_1_0_73/lifecycle.js +981 -0
- package/dist/orchestration_1_0_73/lifecycle.js.map +1 -0
- package/dist/orchestration_1_0_73/queue.d.ts +20 -0
- package/dist/orchestration_1_0_73/queue.d.ts.map +1 -0
- package/dist/orchestration_1_0_73/queue.js +894 -0
- package/dist/orchestration_1_0_73/queue.js.map +1 -0
- package/dist/orchestration_1_0_73/runtime.d.ts +31 -0
- package/dist/orchestration_1_0_73/runtime.d.ts.map +1 -0
- package/dist/orchestration_1_0_73/runtime.js +230 -0
- package/dist/orchestration_1_0_73/runtime.js.map +1 -0
- package/dist/orchestration_1_0_73/state.d.ts +214 -0
- package/dist/orchestration_1_0_73/state.d.ts.map +1 -0
- package/dist/orchestration_1_0_73/state.js +178 -0
- package/dist/orchestration_1_0_73/state.js.map +1 -0
- package/dist/orchestration_1_0_73/turn.d.ts +34 -0
- package/dist/orchestration_1_0_73/turn.d.ts.map +1 -0
- package/dist/orchestration_1_0_73/turn.js +1435 -0
- package/dist/orchestration_1_0_73/turn.js.map +1 -0
- package/dist/orchestration_1_0_73/utils.d.ts +39 -0
- package/dist/orchestration_1_0_73/utils.d.ts.map +1 -0
- package/dist/orchestration_1_0_73/utils.js +322 -0
- package/dist/orchestration_1_0_73/utils.js.map +1 -0
- package/dist/orchestration_1_0_74/agents.d.ts +61 -0
- package/dist/orchestration_1_0_74/agents.d.ts.map +1 -0
- package/dist/orchestration_1_0_74/agents.js +889 -0
- package/dist/orchestration_1_0_74/agents.js.map +1 -0
- package/dist/orchestration_1_0_74/index.d.ts +24 -0
- package/dist/orchestration_1_0_74/index.d.ts.map +1 -0
- package/dist/orchestration_1_0_74/index.js +13 -0
- package/dist/orchestration_1_0_74/index.js.map +1 -0
- package/dist/orchestration_1_0_74/lifecycle.d.ts +51 -0
- package/dist/orchestration_1_0_74/lifecycle.d.ts.map +1 -0
- package/dist/orchestration_1_0_74/lifecycle.js +981 -0
- package/dist/orchestration_1_0_74/lifecycle.js.map +1 -0
- package/dist/orchestration_1_0_74/queue.d.ts +20 -0
- package/dist/orchestration_1_0_74/queue.d.ts.map +1 -0
- package/dist/orchestration_1_0_74/queue.js +894 -0
- package/dist/orchestration_1_0_74/queue.js.map +1 -0
- package/dist/orchestration_1_0_74/runtime.d.ts +31 -0
- package/dist/orchestration_1_0_74/runtime.d.ts.map +1 -0
- package/dist/orchestration_1_0_74/runtime.js +232 -0
- package/dist/orchestration_1_0_74/runtime.js.map +1 -0
- package/dist/orchestration_1_0_74/state.d.ts +214 -0
- package/dist/orchestration_1_0_74/state.d.ts.map +1 -0
- package/dist/orchestration_1_0_74/state.js +178 -0
- package/dist/orchestration_1_0_74/state.js.map +1 -0
- package/dist/orchestration_1_0_74/turn.d.ts +34 -0
- package/dist/orchestration_1_0_74/turn.d.ts.map +1 -0
- package/dist/orchestration_1_0_74/turn.js +1435 -0
- package/dist/orchestration_1_0_74/turn.js.map +1 -0
- package/dist/orchestration_1_0_74/utils.d.ts +39 -0
- package/dist/orchestration_1_0_74/utils.d.ts.map +1 -0
- package/dist/orchestration_1_0_74/utils.js +322 -0
- package/dist/orchestration_1_0_74/utils.js.map +1 -0
- package/dist/orchestration_1_0_75/agents.d.ts +61 -0
- package/dist/orchestration_1_0_75/agents.d.ts.map +1 -0
- package/dist/orchestration_1_0_75/agents.js +887 -0
- package/dist/orchestration_1_0_75/agents.js.map +1 -0
- package/dist/orchestration_1_0_75/index.d.ts +24 -0
- package/dist/orchestration_1_0_75/index.d.ts.map +1 -0
- package/dist/orchestration_1_0_75/index.js +13 -0
- package/dist/orchestration_1_0_75/index.js.map +1 -0
- package/dist/orchestration_1_0_75/lifecycle.d.ts +51 -0
- package/dist/orchestration_1_0_75/lifecycle.d.ts.map +1 -0
- package/dist/orchestration_1_0_75/lifecycle.js +981 -0
- package/dist/orchestration_1_0_75/lifecycle.js.map +1 -0
- package/dist/orchestration_1_0_75/queue.d.ts +20 -0
- package/dist/orchestration_1_0_75/queue.d.ts.map +1 -0
- package/dist/orchestration_1_0_75/queue.js +894 -0
- package/dist/orchestration_1_0_75/queue.js.map +1 -0
- package/dist/orchestration_1_0_75/runtime.d.ts +31 -0
- package/dist/orchestration_1_0_75/runtime.d.ts.map +1 -0
- package/dist/orchestration_1_0_75/runtime.js +239 -0
- package/dist/orchestration_1_0_75/runtime.js.map +1 -0
- package/dist/orchestration_1_0_75/state.d.ts +214 -0
- package/dist/orchestration_1_0_75/state.d.ts.map +1 -0
- package/dist/orchestration_1_0_75/state.js +178 -0
- package/dist/orchestration_1_0_75/state.js.map +1 -0
- package/dist/orchestration_1_0_75/turn.d.ts +34 -0
- package/dist/orchestration_1_0_75/turn.d.ts.map +1 -0
- package/dist/orchestration_1_0_75/turn.js +1435 -0
- package/dist/orchestration_1_0_75/turn.js.map +1 -0
- package/dist/orchestration_1_0_75/utils.d.ts +39 -0
- package/dist/orchestration_1_0_75/utils.d.ts.map +1 -0
- package/dist/orchestration_1_0_75/utils.js +322 -0
- package/dist/orchestration_1_0_75/utils.js.map +1 -0
- package/dist/orchestration_1_0_76/agents.d.ts +61 -0
- package/dist/orchestration_1_0_76/agents.d.ts.map +1 -0
- package/dist/orchestration_1_0_76/agents.js +865 -0
- package/dist/orchestration_1_0_76/agents.js.map +1 -0
- package/dist/orchestration_1_0_76/index.d.ts +24 -0
- package/dist/orchestration_1_0_76/index.d.ts.map +1 -0
- package/dist/orchestration_1_0_76/index.js +13 -0
- package/dist/orchestration_1_0_76/index.js.map +1 -0
- package/dist/orchestration_1_0_76/lifecycle.d.ts +51 -0
- package/dist/orchestration_1_0_76/lifecycle.d.ts.map +1 -0
- package/dist/orchestration_1_0_76/lifecycle.js +981 -0
- package/dist/orchestration_1_0_76/lifecycle.js.map +1 -0
- package/dist/orchestration_1_0_76/queue.d.ts +20 -0
- package/dist/orchestration_1_0_76/queue.d.ts.map +1 -0
- package/dist/orchestration_1_0_76/queue.js +894 -0
- package/dist/orchestration_1_0_76/queue.js.map +1 -0
- package/dist/orchestration_1_0_76/runtime.d.ts +31 -0
- package/dist/orchestration_1_0_76/runtime.d.ts.map +1 -0
- package/dist/orchestration_1_0_76/runtime.js +239 -0
- package/dist/orchestration_1_0_76/runtime.js.map +1 -0
- package/dist/orchestration_1_0_76/state.d.ts +214 -0
- package/dist/orchestration_1_0_76/state.d.ts.map +1 -0
- package/dist/orchestration_1_0_76/state.js +178 -0
- package/dist/orchestration_1_0_76/state.js.map +1 -0
- package/dist/orchestration_1_0_76/turn.d.ts +34 -0
- package/dist/orchestration_1_0_76/turn.d.ts.map +1 -0
- package/dist/orchestration_1_0_76/turn.js +1435 -0
- package/dist/orchestration_1_0_76/turn.js.map +1 -0
- package/dist/orchestration_1_0_76/utils.d.ts +39 -0
- package/dist/orchestration_1_0_76/utils.d.ts.map +1 -0
- package/dist/orchestration_1_0_76/utils.js +322 -0
- package/dist/orchestration_1_0_76/utils.js.map +1 -0
- package/dist/orchestration_1_0_77/agents.d.ts +66 -0
- package/dist/orchestration_1_0_77/agents.d.ts.map +1 -0
- package/dist/orchestration_1_0_77/agents.js +895 -0
- package/dist/orchestration_1_0_77/agents.js.map +1 -0
- package/dist/orchestration_1_0_77/index.d.ts +24 -0
- package/dist/orchestration_1_0_77/index.d.ts.map +1 -0
- package/dist/orchestration_1_0_77/index.js +13 -0
- package/dist/orchestration_1_0_77/index.js.map +1 -0
- package/dist/orchestration_1_0_77/lifecycle.d.ts +51 -0
- package/dist/orchestration_1_0_77/lifecycle.d.ts.map +1 -0
- package/dist/orchestration_1_0_77/lifecycle.js +981 -0
- package/dist/orchestration_1_0_77/lifecycle.js.map +1 -0
- package/dist/orchestration_1_0_77/queue.d.ts +20 -0
- package/dist/orchestration_1_0_77/queue.d.ts.map +1 -0
- package/dist/orchestration_1_0_77/queue.js +894 -0
- package/dist/orchestration_1_0_77/queue.js.map +1 -0
- package/dist/orchestration_1_0_77/runtime.d.ts +31 -0
- package/dist/orchestration_1_0_77/runtime.d.ts.map +1 -0
- package/dist/orchestration_1_0_77/runtime.js +239 -0
- package/dist/orchestration_1_0_77/runtime.js.map +1 -0
- package/dist/orchestration_1_0_77/state.d.ts +214 -0
- package/dist/orchestration_1_0_77/state.d.ts.map +1 -0
- package/dist/orchestration_1_0_77/state.js +178 -0
- package/dist/orchestration_1_0_77/state.js.map +1 -0
- package/dist/orchestration_1_0_77/turn.d.ts +34 -0
- package/dist/orchestration_1_0_77/turn.d.ts.map +1 -0
- package/dist/orchestration_1_0_77/turn.js +1433 -0
- package/dist/orchestration_1_0_77/turn.js.map +1 -0
- package/dist/orchestration_1_0_77/utils.d.ts +39 -0
- package/dist/orchestration_1_0_77/utils.d.ts.map +1 -0
- package/dist/orchestration_1_0_77/utils.js +322 -0
- package/dist/orchestration_1_0_77/utils.js.map +1 -0
- package/dist/reserved-tool-names.d.ts +5 -0
- package/dist/reserved-tool-names.d.ts.map +1 -0
- package/dist/reserved-tool-names.js +102 -0
- package/dist/reserved-tool-names.js.map +1 -0
- package/dist/session-manager.d.ts +31 -1
- package/dist/session-manager.d.ts.map +1 -1
- package/dist/session-manager.js +343 -102
- package/dist/session-manager.js.map +1 -1
- package/dist/session-proxy.d.ts +28 -3
- package/dist/session-proxy.d.ts.map +1 -1
- package/dist/session-proxy.js +192 -71
- package/dist/session-proxy.js.map +1 -1
- package/dist/session-store.d.ts +2 -0
- package/dist/session-store.d.ts.map +1 -1
- package/dist/session-store.js +18 -2
- package/dist/session-store.js.map +1 -1
- package/dist/types.d.ts +25 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/web/generated-op-methods.d.ts +96 -0
- package/dist/web/generated-op-methods.d.ts.map +1 -1
- package/dist/web/generated-op-methods.js +24 -0
- package/dist/web/generated-op-methods.js.map +1 -1
- package/dist/web/web-management-client.d.ts +13 -0
- package/dist/web/web-management-client.d.ts.map +1 -1
- package/dist/web/web-management-client.js +12 -0
- package/dist/web/web-management-client.js.map +1 -1
- package/dist/worker.d.ts +13 -3
- package/dist/worker.d.ts.map +1 -1
- package/dist/worker.js +150 -110
- package/dist/worker.js.map +1 -1
- package/package.json +4 -3
- package/plugins/mgmt/agents/pilotswarm.agent.md +18 -1
- package/plugins/mgmt/agents/resourcemgr.agent.md +18 -1
- package/plugins/system/agents/default.agent.md +16 -7
package/dist/worker.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
+
import { AGENT_HANDOFF_CAPABILITY } from "./activity-routing.js";
|
|
2
|
+
import { resolveNativeSubagents } from "./native-subagents.js";
|
|
3
|
+
import { FeatureFlagCache } from "./feature-flag-cache.js";
|
|
1
4
|
import { SessionManager, packageAgentKey, agentOwnerKey } from "./session-manager.js";
|
|
2
5
|
import { loadAdminScope, ADMIN_SCOPE_POLICY_VERSION } from "../api/src/admin-scope.js";
|
|
3
6
|
import { createSessionBlobStore } from "./blob-store.js";
|
|
4
7
|
import { FilesystemArtifactStore, FilesystemSessionStore } from "./session-store.js";
|
|
5
8
|
import { registerActivities } from "./session-proxy.js";
|
|
6
9
|
import { DURABLE_SESSION_ORCHESTRATION_NAME, DURABLE_SESSION_ORCHESTRATION_REGISTRY, } from "./orchestration-registry.js";
|
|
7
|
-
import { PgSessionCatalog } from "./cms.js";
|
|
10
|
+
import { PgSessionCatalog, resolveEffectiveSpawnOwner } from "./cms.js";
|
|
11
|
+
import { createAgentDiscoveryTool } from "./agent-discovery.js";
|
|
8
12
|
import { loadAgentFiles, validateAgentDefinition } from "./agent-loader.js";
|
|
9
13
|
import { clipDescription, composeDeclaredSkillsPrompt, loadSkillsSync } from "./skills.js";
|
|
10
14
|
import { resolveSystemAgentSessionPlans, startSystemAgents } from "./system-agents.js";
|
|
@@ -20,8 +24,8 @@ import { createSweeperTools } from "./sweeper-tools.js";
|
|
|
20
24
|
import { createResourceManagerTools } from "./resourcemgr-tools.js";
|
|
21
25
|
import { composeSystemPrompt, mergePromptSections } from "./prompt-layering.js";
|
|
22
26
|
import { buildSchemaIdentifier } from "./prompt-layers.js";
|
|
23
|
-
import { DEFAULT_TURN_TIMEOUT_MS } from "./managed-session.js";
|
|
24
|
-
import {
|
|
27
|
+
import { DEFAULT_TURN_TIMEOUT_MS, ManagedSession } from "./managed-session.js";
|
|
28
|
+
import { findReservedPackageToolName } from "./reserved-tool-names.js";
|
|
25
29
|
import { installAgentPackages, loadAgentPackageTools } from "./agent-package-installer.js";
|
|
26
30
|
import fs from "node:fs";
|
|
27
31
|
import os from "node:os";
|
|
@@ -183,6 +187,9 @@ export class PilotSwarmWorker {
|
|
|
183
187
|
/** Mtime watcher that re-loads model_providers.json on file change. */
|
|
184
188
|
_modelProvidersReloader = null;
|
|
185
189
|
_modelProvidersReloadTimer = null;
|
|
190
|
+
/** Close admission when drain begins; _started stays true until teardown ends. */
|
|
191
|
+
_providerReconciliationEnabled = false;
|
|
192
|
+
_providerReconciliation = null;
|
|
186
193
|
/** Embedded PilotSwarm framework prompt. */
|
|
187
194
|
_frameworkBasePrompt = null;
|
|
188
195
|
/** Tool names declared by the embedded PilotSwarm framework default agent. */
|
|
@@ -234,6 +241,8 @@ export class PilotSwarmWorker {
|
|
|
234
241
|
_eventLoopHist = null;
|
|
235
242
|
/** Last refresh failure — carried in heartbeat state until a clean pass. */
|
|
236
243
|
_agentPackagesRefreshError = null;
|
|
244
|
+
_featureFlags = null;
|
|
245
|
+
_registryReporting = false;
|
|
237
246
|
constructor(options) {
|
|
238
247
|
this.config = {
|
|
239
248
|
...options,
|
|
@@ -297,6 +306,7 @@ export class PilotSwarmWorker {
|
|
|
297
306
|
appDefaultDescriptor: this._appDefaultDescriptor ?? undefined,
|
|
298
307
|
skillDirectories: this._loadedSkillDirs,
|
|
299
308
|
customAgents: this._loadedAgents,
|
|
309
|
+
nativeSubagents: resolveNativeSubagents(options.nativeSubagents),
|
|
300
310
|
// The `load_skill` catalog, BY REFERENCE (cleared and refilled
|
|
301
311
|
// in place on reload): deployment + shared-package skills.
|
|
302
312
|
skills: this._loadableSkills,
|
|
@@ -317,12 +327,34 @@ export class PilotSwarmWorker {
|
|
|
317
327
|
turnInactivityTimeoutMs: options.turnInactivityTimeoutMs,
|
|
318
328
|
}, effectiveSessionStateDir);
|
|
319
329
|
this.sessionManager.setModelProvidersRefresher(() => this._refreshProviderRegistry());
|
|
330
|
+
}
|
|
331
|
+
_startProviderPolling() {
|
|
332
|
+
this._providerReconciliationEnabled = true;
|
|
320
333
|
// Poll for model_providers.json changes (30s, unref'd so it never
|
|
321
334
|
// holds the process open). On reload, swap the worker's registry AND
|
|
322
335
|
// the SessionManager's — new sessions and per-turn model resolution
|
|
323
336
|
// pick up the fresh catalog immediately.
|
|
324
|
-
if (this._modelProvidersReloader?.path || this._modelProviders) {
|
|
337
|
+
if (!this._modelProvidersReloadTimer && (this._modelProvidersReloader?.path || this._modelProviders)) {
|
|
325
338
|
this._modelProvidersReloadTimer = setInterval(() => {
|
|
339
|
+
this._reconcileProvidersAndSystemAgents(true);
|
|
340
|
+
}, 30_000);
|
|
341
|
+
this._modelProvidersReloadTimer.unref?.();
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
_stopProviderPolling() {
|
|
345
|
+
this._providerReconciliationEnabled = false;
|
|
346
|
+
if (this._modelProvidersReloadTimer) {
|
|
347
|
+
clearInterval(this._modelProvidersReloadTimer);
|
|
348
|
+
this._modelProvidersReloadTimer = null;
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
_reconcileProvidersAndSystemAgents(refreshProviders) {
|
|
352
|
+
// Initial bootstrap and periodic reconciliation share one task. A slow
|
|
353
|
+
// catalog must not accumulate overlapping refreshes or agent starts.
|
|
354
|
+
if (!this._providerReconciliationEnabled || this._providerReconciliation)
|
|
355
|
+
return;
|
|
356
|
+
this._providerReconciliation = (async () => {
|
|
357
|
+
if (refreshProviders) {
|
|
326
358
|
if (this._modelProvidersReloader?.checkAndReload()) {
|
|
327
359
|
this._modelProviders = this._modelProvidersReloader.current;
|
|
328
360
|
this._modelProviderTypes = this._modelProvidersReloader.types;
|
|
@@ -333,12 +365,13 @@ export class PilotSwarmWorker {
|
|
|
333
365
|
// catalog is re-read on the same tick as the file. Without
|
|
334
366
|
// it a provider somebody just added would resolve no
|
|
335
367
|
// credential until the worker restarted.
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
368
|
+
await this._refreshProviderRegistry();
|
|
369
|
+
}
|
|
370
|
+
if (this._providerReconciliationEnabled)
|
|
371
|
+
await this._startSystemAgents();
|
|
372
|
+
})()
|
|
373
|
+
.catch((err) => console.warn(`[PilotSwarmWorker] provider/system reconciliation failed: ${String(err?.message ?? err)}`))
|
|
374
|
+
.finally(() => { this._providerReconciliation = null; });
|
|
342
375
|
}
|
|
343
376
|
/**
|
|
344
377
|
* Rebuild what the SessionManager resolves models against: the TYPES
|
|
@@ -539,6 +572,11 @@ export class PilotSwarmWorker {
|
|
|
539
572
|
throw new Error(`CMS initialization failed after ${attempts} attempts — refusing to run a degraded worker without catalog-gated tools: ${String(lastErr?.message ?? lastErr)}`);
|
|
540
573
|
}
|
|
541
574
|
}
|
|
575
|
+
if (this._catalog?.features) {
|
|
576
|
+
this._featureFlags = new FeatureFlagCache(this._catalog.features);
|
|
577
|
+
this.sessionManager.setFeatureFlagCache(this._featureFlags);
|
|
578
|
+
await this._featureFlags.pollRevisionsAndRefresh();
|
|
579
|
+
}
|
|
542
580
|
// ── Provider budgets: the one-time deployment seed ──────────────
|
|
543
581
|
//
|
|
544
582
|
// A fresh cluster holds no providers, and the credentials in the
|
|
@@ -658,6 +696,7 @@ export class PilotSwarmWorker {
|
|
|
658
696
|
const inspectClient = new Client(this._provider);
|
|
659
697
|
this.sessionManager.setDuroxideClient(inspectClient);
|
|
660
698
|
const runtimeOptions = {
|
|
699
|
+
workerTagFilter: { defaultAnd: [AGENT_HANDOFF_CAPABILITY] },
|
|
661
700
|
orchestrationConcurrency,
|
|
662
701
|
workerConcurrency,
|
|
663
702
|
dispatcherPollIntervalMs: 10,
|
|
@@ -739,65 +778,18 @@ export class PilotSwarmWorker {
|
|
|
739
778
|
});
|
|
740
779
|
this.registerTools(rmTools);
|
|
741
780
|
}
|
|
742
|
-
//
|
|
743
|
-
//
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
parameters: {
|
|
755
|
-
type: "object",
|
|
756
|
-
properties: {
|
|
757
|
-
systemOnly: {
|
|
758
|
-
type: "boolean",
|
|
759
|
-
description: "If true, only return system agents. Default: false",
|
|
760
|
-
},
|
|
761
|
-
creatableOnly: {
|
|
762
|
-
type: "boolean",
|
|
763
|
-
description: "If true, only return user-creatable (non-system) agents. This matches the default behavior.",
|
|
764
|
-
},
|
|
765
|
-
},
|
|
766
|
-
},
|
|
767
|
-
handler: async (args) => {
|
|
768
|
-
const allAgents = [
|
|
769
|
-
...this._loadedAgents.map(a => ({
|
|
770
|
-
name: a.name,
|
|
771
|
-
namespace: a.namespace || "custom",
|
|
772
|
-
qualifiedName: `${a.namespace || "custom"}:${a.name}`,
|
|
773
|
-
description: a.description || null,
|
|
774
|
-
tools: a.tools || [],
|
|
775
|
-
skills: a.skills || [],
|
|
776
|
-
system: false,
|
|
777
|
-
creatable: true,
|
|
778
|
-
id: null,
|
|
779
|
-
parent: null,
|
|
780
|
-
})),
|
|
781
|
-
...this._loadedSystemAgents.map(a => ({
|
|
782
|
-
name: a.name,
|
|
783
|
-
namespace: a.namespace || "pilotswarm",
|
|
784
|
-
qualifiedName: `${a.namespace || "pilotswarm"}:${a.name}`,
|
|
785
|
-
description: a.description || null,
|
|
786
|
-
tools: a.tools || [],
|
|
787
|
-
system: true,
|
|
788
|
-
creatable: false,
|
|
789
|
-
id: a.id || null,
|
|
790
|
-
parent: a.parent || null,
|
|
791
|
-
})),
|
|
792
|
-
];
|
|
793
|
-
let filtered = allAgents.filter(a => !a.system);
|
|
794
|
-
if (args.systemOnly) {
|
|
795
|
-
filtered = allAgents.filter(a => a.system);
|
|
796
|
-
}
|
|
797
|
-
else if (args.creatableOnly) {
|
|
798
|
-
filtered = allAgents.filter(a => !a.system);
|
|
799
|
-
}
|
|
800
|
-
return JSON.stringify({ agents: filtered, total: filtered.length }, null, 2);
|
|
781
|
+
// ps_ avoids the Copilot CLI's native list_agents task-status tool.
|
|
782
|
+
// Listing uses the same owner and copy resolution as spawn_agent.
|
|
783
|
+
const listAgentsTool = createAgentDiscoveryTool({
|
|
784
|
+
// Same identities/owners/order as the raw spawn definitions,
|
|
785
|
+
// with MCP references already reduced to their admitted grants.
|
|
786
|
+
getUserAgents: () => this._loadedAgents,
|
|
787
|
+
getSystemAgents: () => this._loadedSystemAgents,
|
|
788
|
+
getCallerOwnerKey: async (sessionId) => {
|
|
789
|
+
if (!this._catalog || !sessionId)
|
|
790
|
+
return null;
|
|
791
|
+
const owner = await resolveEffectiveSpawnOwner((id) => this._catalog.getSession(id), sessionId);
|
|
792
|
+
return owner?.provider && owner?.subject ? `${owner.provider}\u0001${owner.subject}` : null;
|
|
801
793
|
},
|
|
802
794
|
});
|
|
803
795
|
this.registerTools([listAgentsTool]);
|
|
@@ -805,6 +797,7 @@ export class PilotSwarmWorker {
|
|
|
805
797
|
console.error("[PilotSwarmWorker] Runtime error:", err);
|
|
806
798
|
});
|
|
807
799
|
this._started = true;
|
|
800
|
+
this._startProviderPolling();
|
|
808
801
|
// Autonomous eviction clock (lifecycle protocol §3.4): local session
|
|
809
802
|
// state is a cache. Sessions idle past the hold window + margin are
|
|
810
803
|
// reclaimed locally (committed → delete; legacy → dehydrate) with no
|
|
@@ -825,24 +818,18 @@ export class PilotSwarmWorker {
|
|
|
825
818
|
}, Math.min(evictAfterMs, 300_000));
|
|
826
819
|
this._evictionTimer.unref?.();
|
|
827
820
|
}
|
|
828
|
-
//
|
|
829
|
-
//
|
|
830
|
-
|
|
831
|
-
if (this._agentPackagesCacheDir && this._agentPackagesRefreshMs > 0) {
|
|
832
|
-
this._agentPackagesTimer = setInterval(() => {
|
|
833
|
-
void this.refreshAgentPackages();
|
|
834
|
-
}, this._agentPackagesRefreshMs);
|
|
835
|
-
this._agentPackagesTimer.unref?.();
|
|
836
|
-
}
|
|
821
|
+
// One configuration timer for every CMS worker. Zero still disables
|
|
822
|
+
// package refresh, but cannot disable feature-policy convergence.
|
|
823
|
+
this._startConfigurationPolling();
|
|
837
824
|
await new Promise(r => setTimeout(r, 200));
|
|
838
825
|
// Auto-start system agents defined in plugins (idempotent), but do not
|
|
839
826
|
// block worker.start() on the bootstrap race. The TUI should become
|
|
840
827
|
// interactive even if first-run system-agent startup is slow.
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
});
|
|
828
|
+
// Provider routing was refreshed above, before the runtime started.
|
|
829
|
+
this._reconcileProvidersAndSystemAgents(false);
|
|
844
830
|
}
|
|
845
831
|
async stop() {
|
|
832
|
+
this._stopProviderPolling();
|
|
846
833
|
if (this._evictionTimer) {
|
|
847
834
|
clearInterval(this._evictionTimer);
|
|
848
835
|
this._evictionTimer = null;
|
|
@@ -851,6 +838,7 @@ export class PilotSwarmWorker {
|
|
|
851
838
|
clearInterval(this._agentPackagesTimer);
|
|
852
839
|
this._agentPackagesTimer = null;
|
|
853
840
|
}
|
|
841
|
+
await this._featureFlags?.stop();
|
|
854
842
|
if (this._eventLoopHist) {
|
|
855
843
|
this._eventLoopHist.disable();
|
|
856
844
|
this._eventLoopHist = null;
|
|
@@ -863,6 +851,9 @@ export class PilotSwarmWorker {
|
|
|
863
851
|
await this.runtime.shutdown(shutdownTimeoutMs);
|
|
864
852
|
this.runtime = null;
|
|
865
853
|
}
|
|
854
|
+
// Stop fetching first, then let any already-admitted bootstrap finish
|
|
855
|
+
// while the catalog/provider it uses are still open.
|
|
856
|
+
await this._providerReconciliation;
|
|
866
857
|
await this.sessionManager.shutdown();
|
|
867
858
|
if (this._catalog) {
|
|
868
859
|
try {
|
|
@@ -910,6 +901,7 @@ export class PilotSwarmWorker {
|
|
|
910
901
|
* lock timeout.
|
|
911
902
|
*/
|
|
912
903
|
async gracefulShutdown() {
|
|
904
|
+
this._stopProviderPolling();
|
|
913
905
|
const rawDrainMs = Number.parseInt(process.env.PILOTSWARM_WORKER_SHUTDOWN_TIMEOUT_MS || "", 10);
|
|
914
906
|
const drainBudgetMs = Number.isFinite(rawDrainMs) && rawDrainMs >= 0 ? rawDrainMs : 60_000;
|
|
915
907
|
// Advertise draining before the runtime drain so operators see the
|
|
@@ -1009,10 +1001,28 @@ export class PilotSwarmWorker {
|
|
|
1009
1001
|
* a broken package degrades to "packages unchanged/quarantined", never
|
|
1010
1002
|
* to a dead worker.
|
|
1011
1003
|
*
|
|
1012
|
-
*
|
|
1013
|
-
*
|
|
1014
|
-
*
|
|
1004
|
+
* SessionManager adopts one package snapshot per turn. Handler-only changes
|
|
1005
|
+
* re-register in place; changed prompts, declarations or MCP grants recreate
|
|
1006
|
+
* the warm CLI handle at the next turn boundary.
|
|
1015
1007
|
*/
|
|
1008
|
+
_startConfigurationPolling() {
|
|
1009
|
+
if (!this._catalog || this._agentPackagesTimer)
|
|
1010
|
+
return;
|
|
1011
|
+
void this._reportAgentWorkerState();
|
|
1012
|
+
this._agentPackagesTimer = setInterval(() => {
|
|
1013
|
+
void this.refreshWorkerConfiguration();
|
|
1014
|
+
}, this._agentPackagesRefreshMs > 0 ? this._agentPackagesRefreshMs : 20_000);
|
|
1015
|
+
this._agentPackagesTimer.unref?.();
|
|
1016
|
+
}
|
|
1017
|
+
async refreshWorkerConfiguration() {
|
|
1018
|
+
await Promise.allSettled([
|
|
1019
|
+
(async () => {
|
|
1020
|
+
await this._featureFlags?.pollRevisionsAndRefresh();
|
|
1021
|
+
await this._reportAgentWorkerState();
|
|
1022
|
+
})(),
|
|
1023
|
+
this._agentPackagesRefreshMs > 0 ? this.refreshAgentPackages() : Promise.resolve(),
|
|
1024
|
+
]);
|
|
1025
|
+
}
|
|
1016
1026
|
async refreshAgentPackages(opts = {}) {
|
|
1017
1027
|
if (!this._agentPackagesCacheDir || !this._catalog || !this.artifactStore)
|
|
1018
1028
|
return;
|
|
@@ -1046,6 +1056,15 @@ export class PilotSwarmWorker {
|
|
|
1046
1056
|
continue;
|
|
1047
1057
|
try {
|
|
1048
1058
|
const tools = await loadAgentPackageTools(pkg, { workerNodeId: this.config.workerNodeId });
|
|
1059
|
+
const collision = findReservedPackageToolName(tools.map((tool) => String(tool?.name || "")), [
|
|
1060
|
+
...ManagedSession.systemToolDefs().map((tool) => String(tool.name)),
|
|
1061
|
+
...ManagedSession.subAgentToolDefs().map((tool) => String(tool.name)),
|
|
1062
|
+
...this._frameworkBaseToolNames,
|
|
1063
|
+
...this._appDefaultToolNames,
|
|
1064
|
+
], this.toolRegistry.keys());
|
|
1065
|
+
if (collision) {
|
|
1066
|
+
throw new Error(`package tool "${collision}" conflicts with a reserved platform or deployment tool`);
|
|
1067
|
+
}
|
|
1049
1068
|
const ownMap = new Map();
|
|
1050
1069
|
for (const tool of tools) {
|
|
1051
1070
|
packageTools.set(tool.name, tool);
|
|
@@ -1146,7 +1165,7 @@ export class PilotSwarmWorker {
|
|
|
1146
1165
|
sdkVersion,
|
|
1147
1166
|
authz: { adminScope: loadAdminScope(), policyVersion: ADMIN_SCOPE_POLICY_VERSION },
|
|
1148
1167
|
orchestrationVersions: DURABLE_SESSION_ORCHESTRATION_REGISTRY.map((r) => r.version),
|
|
1149
|
-
consumes: this._agentPackagesCacheDir ? ["agent-packages"] : [],
|
|
1168
|
+
consumes: [...(this._agentPackagesCacheDir ? ["agent-packages"] : []), "feature-flags"],
|
|
1150
1169
|
capabilities: {
|
|
1151
1170
|
blobStore: Boolean(this.blobStore),
|
|
1152
1171
|
enhancedFacts: Boolean(this.factStore && isEnhancedFactStore(this.factStore)),
|
|
@@ -1191,8 +1210,9 @@ export class PilotSwarmWorker {
|
|
|
1191
1210
|
* actuated domains are inert by protocol. Never throws.
|
|
1192
1211
|
*/
|
|
1193
1212
|
async _reportAgentWorkerState() {
|
|
1194
|
-
if (!this._catalog)
|
|
1213
|
+
if (!this._catalog || this._registryReporting)
|
|
1195
1214
|
return;
|
|
1215
|
+
this._registryReporting = true;
|
|
1196
1216
|
try {
|
|
1197
1217
|
await this._catalog.workerHeartbeat({
|
|
1198
1218
|
workerNodeId: this._registryWorkerId,
|
|
@@ -1202,6 +1222,8 @@ export class PilotSwarmWorker {
|
|
|
1202
1222
|
info: this._buildRegistrarInfo(),
|
|
1203
1223
|
health: this._collectWorkerHealth(),
|
|
1204
1224
|
state: {
|
|
1225
|
+
"feature-flags": { ...this._featureFlags?.state,
|
|
1226
|
+
nativeCapability: resolveNativeSubagents(this.config.nativeSubagents) },
|
|
1205
1227
|
"agent-packages": {
|
|
1206
1228
|
epoch: this._agentPackagesEpoch,
|
|
1207
1229
|
installed: this._agentPackagesInstalled,
|
|
@@ -1213,6 +1235,9 @@ export class PilotSwarmWorker {
|
|
|
1213
1235
|
catch (error) {
|
|
1214
1236
|
console.warn(`[PilotSwarmWorker] worker-registry heartbeat failed: ${error?.message ?? error}`);
|
|
1215
1237
|
}
|
|
1238
|
+
finally {
|
|
1239
|
+
this._registryReporting = false;
|
|
1240
|
+
}
|
|
1216
1241
|
}
|
|
1217
1242
|
_loadPlugins() {
|
|
1218
1243
|
// ── Tier 1: SDK system plugins (always loaded) ───────────────
|
|
@@ -1290,7 +1315,7 @@ export class PilotSwarmWorker {
|
|
|
1290
1315
|
const { mcpServers: _refs, inheritDefaultMcpServers: _inherit, ...rest } = agent;
|
|
1291
1316
|
const mcpKey = agent.packageId
|
|
1292
1317
|
? packageAgentKey(agent.packageId, agent.name)
|
|
1293
|
-
: agent.name;
|
|
1318
|
+
: agent.namespace ? `${agent.namespace}:${agent.name}` : agent.name;
|
|
1294
1319
|
return {
|
|
1295
1320
|
...rest,
|
|
1296
1321
|
// The agent's OWN prompt (skills already composed in), never
|
|
@@ -1301,8 +1326,8 @@ export class PilotSwarmWorker {
|
|
|
1301
1326
|
appDefault: this._appDefaultPrompt,
|
|
1302
1327
|
activeAgentPrompt: agent.prompt,
|
|
1303
1328
|
}) ?? agent.prompt,
|
|
1304
|
-
//
|
|
1305
|
-
//
|
|
1329
|
+
// MCP uses the exact same copy as the authored prompt, even
|
|
1330
|
+
// when two static namespaces declare the same agent name.
|
|
1306
1331
|
...(this._agentMcpServers[mcpKey]
|
|
1307
1332
|
? { mcpServers: this._agentMcpServers[mcpKey] }
|
|
1308
1333
|
: {}),
|
|
@@ -1448,19 +1473,11 @@ export class PilotSwarmWorker {
|
|
|
1448
1473
|
console.warn(`[PilotSwarmWorker] Direct worker-config mcpServers (${this._directConfigMcpNames.join(", ")}) ` +
|
|
1449
1474
|
`apply to every session (legacy). Prefer per-agent frontmatter declarations or tagging catalog servers "default": true.`);
|
|
1450
1475
|
}
|
|
1451
|
-
//
|
|
1452
|
-
//
|
|
1453
|
-
//
|
|
1454
|
-
//
|
|
1455
|
-
|
|
1456
|
-
// A PACKAGE agent registers ONLY under a package-qualified key, never
|
|
1457
|
-
// the bare name. With scope shadowing two copies share the bare name,
|
|
1458
|
-
// and a bare-name entry is last-write-wins — a session resolving one
|
|
1459
|
-
// copy could read the other's grants (or a user package could strip a
|
|
1460
|
-
// deployment agent's grants fleet-wide). The bare name is therefore
|
|
1461
|
-
// reserved for deployment/inline agents, which have no packageId; the
|
|
1462
|
-
// session-manager reads the qualified key for package copies and the
|
|
1463
|
-
// bare key only for non-package agents.
|
|
1476
|
+
// Published agents use package-qualified keys. Static definitions use
|
|
1477
|
+
// namespace-qualified keys; the bare alias retains the first static
|
|
1478
|
+
// definition, matching the prompt lookup's deployment default. Never
|
|
1479
|
+
// let a same-name package or another namespace replace these grants.
|
|
1480
|
+
const assignedStaticKeys = new Set();
|
|
1464
1481
|
for (const agent of [...this._rawLoadedAgents, ...this._loadedSystemAgents]) {
|
|
1465
1482
|
const resolved = {};
|
|
1466
1483
|
if (agent.inheritDefaultMcpServers === true) {
|
|
@@ -1472,14 +1489,21 @@ export class PilotSwarmWorker {
|
|
|
1472
1489
|
packageId: agent.packageId ?? null,
|
|
1473
1490
|
packageScope: agent.packageScope ?? null,
|
|
1474
1491
|
});
|
|
1475
|
-
const
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1492
|
+
const packageId = agent.packageId;
|
|
1493
|
+
const keys = packageId
|
|
1494
|
+
? [packageAgentKey(packageId, agent.name)]
|
|
1495
|
+
: [...new Set([agent.name, ...(agent.namespace ? [`${agent.namespace}:${agent.name}`] : [])])];
|
|
1496
|
+
for (const key of keys) {
|
|
1497
|
+
if (!packageId && assignedStaticKeys.has(key))
|
|
1498
|
+
continue;
|
|
1499
|
+
if (!packageId)
|
|
1500
|
+
assignedStaticKeys.add(key);
|
|
1501
|
+
if (Object.keys(resolved).length > 0) {
|
|
1502
|
+
this._agentMcpServers[key] = resolved;
|
|
1503
|
+
}
|
|
1504
|
+
else {
|
|
1505
|
+
delete this._agentMcpServers[key];
|
|
1506
|
+
}
|
|
1483
1507
|
}
|
|
1484
1508
|
}
|
|
1485
1509
|
}
|
|
@@ -1634,6 +1658,7 @@ export class PilotSwarmWorker {
|
|
|
1634
1658
|
const winner = [...agents].sort((a, b) => rank(a) - rank(b))[0];
|
|
1635
1659
|
const copyOf = (agent) => ({
|
|
1636
1660
|
prompt: agent.prompt,
|
|
1661
|
+
toolNames: [...(agent.tools ?? [])],
|
|
1637
1662
|
kind: agent.promptLayerKind ?? "app-agent",
|
|
1638
1663
|
descriptor: agent.layerDescriptor,
|
|
1639
1664
|
...(agent.packageId ? {
|
|
@@ -1646,6 +1671,19 @@ export class PilotSwarmWorker {
|
|
|
1646
1671
|
...copyOf(winner),
|
|
1647
1672
|
...(agents.length > 1 ? { copies: agents.map(copyOf) } : {}),
|
|
1648
1673
|
};
|
|
1674
|
+
// Persisted static bindings use this exact namespace key. The
|
|
1675
|
+
// alias carries the composed prompt, declarations and descriptor
|
|
1676
|
+
// of that copy, never the bare-name winner from another namespace.
|
|
1677
|
+
const assignedAliases = new Set();
|
|
1678
|
+
for (const agent of agents) {
|
|
1679
|
+
if (agent.packageId || !agent.namespace)
|
|
1680
|
+
continue;
|
|
1681
|
+
const key = `${agent.namespace}:${agent.name}`;
|
|
1682
|
+
if (assignedAliases.has(key))
|
|
1683
|
+
continue;
|
|
1684
|
+
assignedAliases.add(key);
|
|
1685
|
+
this._agentPromptLookup[key] = copyOf(agent);
|
|
1686
|
+
}
|
|
1649
1687
|
if (agents.length > 1) {
|
|
1650
1688
|
console.warn(`[PilotSwarmWorker] agent name "${name}" is served by ${agents.length} loaded copies `
|
|
1651
1689
|
+ `(${agents.map((a) => a.packageId ? `${a.packageScope ?? "shared"} package` : "deployment").join(", ")}); `
|
|
@@ -1887,6 +1925,8 @@ export class PilotSwarmWorker {
|
|
|
1887
1925
|
}
|
|
1888
1926
|
const overrideByAgent = new Map(overrides.map((override) => [override.agentId, override]));
|
|
1889
1927
|
for (const plan of resolveSystemAgentSessionPlans(this._loadedSystemAgents)) {
|
|
1928
|
+
if (!this._providerReconciliationEnabled)
|
|
1929
|
+
return;
|
|
1890
1930
|
const override = overrideByAgent.get(plan.agent.id);
|
|
1891
1931
|
const route = override ?? systemDefault;
|
|
1892
1932
|
if (!route.model || !this._modelProviders?.hasModel(route.model)) {
|