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.
Files changed (289) hide show
  1. package/api/src/admin-diagnostics.d.ts +12 -0
  2. package/api/src/admin-diagnostics.js +38 -1
  3. package/api/src/http-api-transport.js +26 -0
  4. package/api/src/protocol.js +15 -0
  5. package/dist/activity-routing.d.ts +21 -0
  6. package/dist/activity-routing.d.ts.map +1 -0
  7. package/dist/activity-routing.js +32 -0
  8. package/dist/activity-routing.js.map +1 -0
  9. package/dist/agent-discovery.d.ts +35 -0
  10. package/dist/agent-discovery.d.ts.map +1 -0
  11. package/dist/agent-discovery.js +107 -0
  12. package/dist/agent-discovery.js.map +1 -0
  13. package/dist/client.d.ts +9 -1
  14. package/dist/client.d.ts.map +1 -1
  15. package/dist/client.js +94 -12
  16. package/dist/client.js.map +1 -1
  17. package/dist/cms-migrations.d.ts.map +1 -1
  18. package/dist/cms-migrations.js +4 -0
  19. package/dist/cms-migrations.js.map +1 -1
  20. package/dist/cms.d.ts +3 -0
  21. package/dist/cms.d.ts.map +1 -1
  22. package/dist/cms.js +7 -0
  23. package/dist/cms.js.map +1 -1
  24. package/dist/feature-flag-cache.d.ts +40 -0
  25. package/dist/feature-flag-cache.d.ts.map +1 -0
  26. package/dist/feature-flag-cache.js +125 -0
  27. package/dist/feature-flag-cache.js.map +1 -0
  28. package/dist/feature-flags.d.ts +68 -0
  29. package/dist/feature-flags.d.ts.map +1 -0
  30. package/dist/feature-flags.js +45 -0
  31. package/dist/feature-flags.js.map +1 -0
  32. package/dist/feature-store.d.ts +55 -0
  33. package/dist/feature-store.d.ts.map +1 -0
  34. package/dist/feature-store.js +106 -0
  35. package/dist/feature-store.js.map +1 -0
  36. package/dist/feature-tools.d.ts +94 -0
  37. package/dist/feature-tools.d.ts.map +1 -0
  38. package/dist/feature-tools.js +60 -0
  39. package/dist/feature-tools.js.map +1 -0
  40. package/dist/index.d.ts +6 -0
  41. package/dist/index.d.ts.map +1 -1
  42. package/dist/index.js +4 -0
  43. package/dist/index.js.map +1 -1
  44. package/dist/managed-session.d.ts +4 -0
  45. package/dist/managed-session.d.ts.map +1 -1
  46. package/dist/managed-session.js +120 -23
  47. package/dist/managed-session.js.map +1 -1
  48. package/dist/management-client.d.ts +18 -0
  49. package/dist/management-client.d.ts.map +1 -1
  50. package/dist/management-client.js +19 -0
  51. package/dist/management-client.js.map +1 -1
  52. package/dist/migrations/feature-flags-0077.d.ts +3 -0
  53. package/dist/migrations/feature-flags-0077.d.ts.map +1 -0
  54. package/dist/migrations/feature-flags-0077.js +271 -0
  55. package/dist/migrations/feature-flags-0077.js.map +1 -0
  56. package/dist/migrations/native-tasks-default-policy-0078.d.ts +3 -0
  57. package/dist/migrations/native-tasks-default-policy-0078.d.ts.map +1 -0
  58. package/dist/migrations/native-tasks-default-policy-0078.js +21 -0
  59. package/dist/migrations/native-tasks-default-policy-0078.js.map +1 -0
  60. package/dist/native-subagents.d.ts +25 -0
  61. package/dist/native-subagents.d.ts.map +1 -0
  62. package/dist/native-subagents.js +191 -0
  63. package/dist/native-subagents.js.map +1 -0
  64. package/dist/native-task-observer.d.ts +87 -0
  65. package/dist/native-task-observer.d.ts.map +1 -0
  66. package/dist/native-task-observer.js +268 -0
  67. package/dist/native-task-observer.js.map +1 -0
  68. package/dist/orchestration/agents.d.ts +8 -3
  69. package/dist/orchestration/agents.d.ts.map +1 -1
  70. package/dist/orchestration/agents.js +87 -36
  71. package/dist/orchestration/agents.js.map +1 -1
  72. package/dist/orchestration/index.d.ts +2 -2
  73. package/dist/orchestration/index.js +1 -1
  74. package/dist/orchestration/lifecycle.js +1 -1
  75. package/dist/orchestration/lifecycle.js.map +1 -1
  76. package/dist/orchestration/runtime.d.ts +1 -1
  77. package/dist/orchestration/runtime.d.ts.map +1 -1
  78. package/dist/orchestration/runtime.js +18 -4
  79. package/dist/orchestration/runtime.js.map +1 -1
  80. package/dist/orchestration/turn.d.ts.map +1 -1
  81. package/dist/orchestration/turn.js +3 -5
  82. package/dist/orchestration/turn.js.map +1 -1
  83. package/dist/orchestration-registry.d.ts.map +1 -1
  84. package/dist/orchestration-registry.js +12 -2
  85. package/dist/orchestration-registry.js.map +1 -1
  86. package/dist/orchestration-version.d.ts +1 -1
  87. package/dist/orchestration-version.js +1 -1
  88. package/dist/orchestration.d.ts +2 -2
  89. package/dist/orchestration.js +1 -1
  90. package/dist/orchestration_1_0_46.d.ts +1 -1
  91. package/dist/orchestration_1_0_47.d.ts +1 -1
  92. package/dist/orchestration_1_0_48.d.ts +1 -1
  93. package/dist/orchestration_1_0_49.d.ts +1 -1
  94. package/dist/orchestration_1_0_50.d.ts +1 -1
  95. package/dist/orchestration_1_0_73/agents.d.ts +61 -0
  96. package/dist/orchestration_1_0_73/agents.d.ts.map +1 -0
  97. package/dist/orchestration_1_0_73/agents.js +843 -0
  98. package/dist/orchestration_1_0_73/agents.js.map +1 -0
  99. package/dist/orchestration_1_0_73/index.d.ts +24 -0
  100. package/dist/orchestration_1_0_73/index.d.ts.map +1 -0
  101. package/dist/orchestration_1_0_73/index.js +13 -0
  102. package/dist/orchestration_1_0_73/index.js.map +1 -0
  103. package/dist/orchestration_1_0_73/lifecycle.d.ts +51 -0
  104. package/dist/orchestration_1_0_73/lifecycle.d.ts.map +1 -0
  105. package/dist/orchestration_1_0_73/lifecycle.js +981 -0
  106. package/dist/orchestration_1_0_73/lifecycle.js.map +1 -0
  107. package/dist/orchestration_1_0_73/queue.d.ts +20 -0
  108. package/dist/orchestration_1_0_73/queue.d.ts.map +1 -0
  109. package/dist/orchestration_1_0_73/queue.js +894 -0
  110. package/dist/orchestration_1_0_73/queue.js.map +1 -0
  111. package/dist/orchestration_1_0_73/runtime.d.ts +31 -0
  112. package/dist/orchestration_1_0_73/runtime.d.ts.map +1 -0
  113. package/dist/orchestration_1_0_73/runtime.js +230 -0
  114. package/dist/orchestration_1_0_73/runtime.js.map +1 -0
  115. package/dist/orchestration_1_0_73/state.d.ts +214 -0
  116. package/dist/orchestration_1_0_73/state.d.ts.map +1 -0
  117. package/dist/orchestration_1_0_73/state.js +178 -0
  118. package/dist/orchestration_1_0_73/state.js.map +1 -0
  119. package/dist/orchestration_1_0_73/turn.d.ts +34 -0
  120. package/dist/orchestration_1_0_73/turn.d.ts.map +1 -0
  121. package/dist/orchestration_1_0_73/turn.js +1435 -0
  122. package/dist/orchestration_1_0_73/turn.js.map +1 -0
  123. package/dist/orchestration_1_0_73/utils.d.ts +39 -0
  124. package/dist/orchestration_1_0_73/utils.d.ts.map +1 -0
  125. package/dist/orchestration_1_0_73/utils.js +322 -0
  126. package/dist/orchestration_1_0_73/utils.js.map +1 -0
  127. package/dist/orchestration_1_0_74/agents.d.ts +61 -0
  128. package/dist/orchestration_1_0_74/agents.d.ts.map +1 -0
  129. package/dist/orchestration_1_0_74/agents.js +889 -0
  130. package/dist/orchestration_1_0_74/agents.js.map +1 -0
  131. package/dist/orchestration_1_0_74/index.d.ts +24 -0
  132. package/dist/orchestration_1_0_74/index.d.ts.map +1 -0
  133. package/dist/orchestration_1_0_74/index.js +13 -0
  134. package/dist/orchestration_1_0_74/index.js.map +1 -0
  135. package/dist/orchestration_1_0_74/lifecycle.d.ts +51 -0
  136. package/dist/orchestration_1_0_74/lifecycle.d.ts.map +1 -0
  137. package/dist/orchestration_1_0_74/lifecycle.js +981 -0
  138. package/dist/orchestration_1_0_74/lifecycle.js.map +1 -0
  139. package/dist/orchestration_1_0_74/queue.d.ts +20 -0
  140. package/dist/orchestration_1_0_74/queue.d.ts.map +1 -0
  141. package/dist/orchestration_1_0_74/queue.js +894 -0
  142. package/dist/orchestration_1_0_74/queue.js.map +1 -0
  143. package/dist/orchestration_1_0_74/runtime.d.ts +31 -0
  144. package/dist/orchestration_1_0_74/runtime.d.ts.map +1 -0
  145. package/dist/orchestration_1_0_74/runtime.js +232 -0
  146. package/dist/orchestration_1_0_74/runtime.js.map +1 -0
  147. package/dist/orchestration_1_0_74/state.d.ts +214 -0
  148. package/dist/orchestration_1_0_74/state.d.ts.map +1 -0
  149. package/dist/orchestration_1_0_74/state.js +178 -0
  150. package/dist/orchestration_1_0_74/state.js.map +1 -0
  151. package/dist/orchestration_1_0_74/turn.d.ts +34 -0
  152. package/dist/orchestration_1_0_74/turn.d.ts.map +1 -0
  153. package/dist/orchestration_1_0_74/turn.js +1435 -0
  154. package/dist/orchestration_1_0_74/turn.js.map +1 -0
  155. package/dist/orchestration_1_0_74/utils.d.ts +39 -0
  156. package/dist/orchestration_1_0_74/utils.d.ts.map +1 -0
  157. package/dist/orchestration_1_0_74/utils.js +322 -0
  158. package/dist/orchestration_1_0_74/utils.js.map +1 -0
  159. package/dist/orchestration_1_0_75/agents.d.ts +61 -0
  160. package/dist/orchestration_1_0_75/agents.d.ts.map +1 -0
  161. package/dist/orchestration_1_0_75/agents.js +887 -0
  162. package/dist/orchestration_1_0_75/agents.js.map +1 -0
  163. package/dist/orchestration_1_0_75/index.d.ts +24 -0
  164. package/dist/orchestration_1_0_75/index.d.ts.map +1 -0
  165. package/dist/orchestration_1_0_75/index.js +13 -0
  166. package/dist/orchestration_1_0_75/index.js.map +1 -0
  167. package/dist/orchestration_1_0_75/lifecycle.d.ts +51 -0
  168. package/dist/orchestration_1_0_75/lifecycle.d.ts.map +1 -0
  169. package/dist/orchestration_1_0_75/lifecycle.js +981 -0
  170. package/dist/orchestration_1_0_75/lifecycle.js.map +1 -0
  171. package/dist/orchestration_1_0_75/queue.d.ts +20 -0
  172. package/dist/orchestration_1_0_75/queue.d.ts.map +1 -0
  173. package/dist/orchestration_1_0_75/queue.js +894 -0
  174. package/dist/orchestration_1_0_75/queue.js.map +1 -0
  175. package/dist/orchestration_1_0_75/runtime.d.ts +31 -0
  176. package/dist/orchestration_1_0_75/runtime.d.ts.map +1 -0
  177. package/dist/orchestration_1_0_75/runtime.js +239 -0
  178. package/dist/orchestration_1_0_75/runtime.js.map +1 -0
  179. package/dist/orchestration_1_0_75/state.d.ts +214 -0
  180. package/dist/orchestration_1_0_75/state.d.ts.map +1 -0
  181. package/dist/orchestration_1_0_75/state.js +178 -0
  182. package/dist/orchestration_1_0_75/state.js.map +1 -0
  183. package/dist/orchestration_1_0_75/turn.d.ts +34 -0
  184. package/dist/orchestration_1_0_75/turn.d.ts.map +1 -0
  185. package/dist/orchestration_1_0_75/turn.js +1435 -0
  186. package/dist/orchestration_1_0_75/turn.js.map +1 -0
  187. package/dist/orchestration_1_0_75/utils.d.ts +39 -0
  188. package/dist/orchestration_1_0_75/utils.d.ts.map +1 -0
  189. package/dist/orchestration_1_0_75/utils.js +322 -0
  190. package/dist/orchestration_1_0_75/utils.js.map +1 -0
  191. package/dist/orchestration_1_0_76/agents.d.ts +61 -0
  192. package/dist/orchestration_1_0_76/agents.d.ts.map +1 -0
  193. package/dist/orchestration_1_0_76/agents.js +865 -0
  194. package/dist/orchestration_1_0_76/agents.js.map +1 -0
  195. package/dist/orchestration_1_0_76/index.d.ts +24 -0
  196. package/dist/orchestration_1_0_76/index.d.ts.map +1 -0
  197. package/dist/orchestration_1_0_76/index.js +13 -0
  198. package/dist/orchestration_1_0_76/index.js.map +1 -0
  199. package/dist/orchestration_1_0_76/lifecycle.d.ts +51 -0
  200. package/dist/orchestration_1_0_76/lifecycle.d.ts.map +1 -0
  201. package/dist/orchestration_1_0_76/lifecycle.js +981 -0
  202. package/dist/orchestration_1_0_76/lifecycle.js.map +1 -0
  203. package/dist/orchestration_1_0_76/queue.d.ts +20 -0
  204. package/dist/orchestration_1_0_76/queue.d.ts.map +1 -0
  205. package/dist/orchestration_1_0_76/queue.js +894 -0
  206. package/dist/orchestration_1_0_76/queue.js.map +1 -0
  207. package/dist/orchestration_1_0_76/runtime.d.ts +31 -0
  208. package/dist/orchestration_1_0_76/runtime.d.ts.map +1 -0
  209. package/dist/orchestration_1_0_76/runtime.js +239 -0
  210. package/dist/orchestration_1_0_76/runtime.js.map +1 -0
  211. package/dist/orchestration_1_0_76/state.d.ts +214 -0
  212. package/dist/orchestration_1_0_76/state.d.ts.map +1 -0
  213. package/dist/orchestration_1_0_76/state.js +178 -0
  214. package/dist/orchestration_1_0_76/state.js.map +1 -0
  215. package/dist/orchestration_1_0_76/turn.d.ts +34 -0
  216. package/dist/orchestration_1_0_76/turn.d.ts.map +1 -0
  217. package/dist/orchestration_1_0_76/turn.js +1435 -0
  218. package/dist/orchestration_1_0_76/turn.js.map +1 -0
  219. package/dist/orchestration_1_0_76/utils.d.ts +39 -0
  220. package/dist/orchestration_1_0_76/utils.d.ts.map +1 -0
  221. package/dist/orchestration_1_0_76/utils.js +322 -0
  222. package/dist/orchestration_1_0_76/utils.js.map +1 -0
  223. package/dist/orchestration_1_0_77/agents.d.ts +66 -0
  224. package/dist/orchestration_1_0_77/agents.d.ts.map +1 -0
  225. package/dist/orchestration_1_0_77/agents.js +895 -0
  226. package/dist/orchestration_1_0_77/agents.js.map +1 -0
  227. package/dist/orchestration_1_0_77/index.d.ts +24 -0
  228. package/dist/orchestration_1_0_77/index.d.ts.map +1 -0
  229. package/dist/orchestration_1_0_77/index.js +13 -0
  230. package/dist/orchestration_1_0_77/index.js.map +1 -0
  231. package/dist/orchestration_1_0_77/lifecycle.d.ts +51 -0
  232. package/dist/orchestration_1_0_77/lifecycle.d.ts.map +1 -0
  233. package/dist/orchestration_1_0_77/lifecycle.js +981 -0
  234. package/dist/orchestration_1_0_77/lifecycle.js.map +1 -0
  235. package/dist/orchestration_1_0_77/queue.d.ts +20 -0
  236. package/dist/orchestration_1_0_77/queue.d.ts.map +1 -0
  237. package/dist/orchestration_1_0_77/queue.js +894 -0
  238. package/dist/orchestration_1_0_77/queue.js.map +1 -0
  239. package/dist/orchestration_1_0_77/runtime.d.ts +31 -0
  240. package/dist/orchestration_1_0_77/runtime.d.ts.map +1 -0
  241. package/dist/orchestration_1_0_77/runtime.js +239 -0
  242. package/dist/orchestration_1_0_77/runtime.js.map +1 -0
  243. package/dist/orchestration_1_0_77/state.d.ts +214 -0
  244. package/dist/orchestration_1_0_77/state.d.ts.map +1 -0
  245. package/dist/orchestration_1_0_77/state.js +178 -0
  246. package/dist/orchestration_1_0_77/state.js.map +1 -0
  247. package/dist/orchestration_1_0_77/turn.d.ts +34 -0
  248. package/dist/orchestration_1_0_77/turn.d.ts.map +1 -0
  249. package/dist/orchestration_1_0_77/turn.js +1433 -0
  250. package/dist/orchestration_1_0_77/turn.js.map +1 -0
  251. package/dist/orchestration_1_0_77/utils.d.ts +39 -0
  252. package/dist/orchestration_1_0_77/utils.d.ts.map +1 -0
  253. package/dist/orchestration_1_0_77/utils.js +322 -0
  254. package/dist/orchestration_1_0_77/utils.js.map +1 -0
  255. package/dist/reserved-tool-names.d.ts +5 -0
  256. package/dist/reserved-tool-names.d.ts.map +1 -0
  257. package/dist/reserved-tool-names.js +102 -0
  258. package/dist/reserved-tool-names.js.map +1 -0
  259. package/dist/session-manager.d.ts +31 -1
  260. package/dist/session-manager.d.ts.map +1 -1
  261. package/dist/session-manager.js +343 -102
  262. package/dist/session-manager.js.map +1 -1
  263. package/dist/session-proxy.d.ts +28 -3
  264. package/dist/session-proxy.d.ts.map +1 -1
  265. package/dist/session-proxy.js +192 -71
  266. package/dist/session-proxy.js.map +1 -1
  267. package/dist/session-store.d.ts +2 -0
  268. package/dist/session-store.d.ts.map +1 -1
  269. package/dist/session-store.js +18 -2
  270. package/dist/session-store.js.map +1 -1
  271. package/dist/types.d.ts +25 -3
  272. package/dist/types.d.ts.map +1 -1
  273. package/dist/types.js.map +1 -1
  274. package/dist/web/generated-op-methods.d.ts +96 -0
  275. package/dist/web/generated-op-methods.d.ts.map +1 -1
  276. package/dist/web/generated-op-methods.js +24 -0
  277. package/dist/web/generated-op-methods.js.map +1 -1
  278. package/dist/web/web-management-client.d.ts +13 -0
  279. package/dist/web/web-management-client.d.ts.map +1 -1
  280. package/dist/web/web-management-client.js +12 -0
  281. package/dist/web/web-management-client.js.map +1 -1
  282. package/dist/worker.d.ts +13 -3
  283. package/dist/worker.d.ts.map +1 -1
  284. package/dist/worker.js +150 -110
  285. package/dist/worker.js.map +1 -1
  286. package/package.json +4 -3
  287. package/plugins/mgmt/agents/pilotswarm.agent.md +18 -1
  288. package/plugins/mgmt/agents/resourcemgr.agent.md +18 -1
  289. 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 { defineTool } from "@github/copilot-sdk";
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
- void this._refreshProviderRegistry()
337
- .then(() => this._startSystemAgents())
338
- .catch((err) => console.warn(`[PilotSwarmWorker] provider/system reconciliation failed: ${String(err?.message ?? err)}`));
339
- }, 30_000);
340
- this._modelProvidersReloadTimer.unref?.();
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
- // ps_list_agents tool — exposes user-creatable agents by default.
743
- // NOTE: prefixed with `ps_` to avoid collision with the Copilot SDK's
744
- // built-in `list_agents` tool (introduced in @github/copilot 1.0.32),
745
- // which lists live background-agent task instances rather than blueprints.
746
- const listAgentsTool = defineTool("ps_list_agents", {
747
- description: "List all available agent BLUEPRINTS (definitions loaded from .agent.md files). " +
748
- "By default this returns only user-creatable named agents. " +
749
- "Worker-managed system agents are hidden from the default list because they are NOT valid spawn_agent targets. " +
750
- "Pass systemOnly=true only when you need to inspect system-agent definitions for diagnostics. " +
751
- "Use this to discover what agents CAN be spawned. To check status of sub-agents you ALREADY spawned, use check_agents instead. " +
752
- "IMPORTANT: Do NOT call this unless you actually need to spawn an agent and don't know its name. " +
753
- "Seeing an agent in this list does NOT mean you should spawn it.",
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
- // Agent-package epoch poll (model-providers-reloader pattern): one
829
- // single-row SELECT per interval; a changed epoch triggers the full
830
- // install + in-place swap. 0 disables.
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
- void this._startSystemAgents().catch((err) => {
842
- console.warn(`[PilotSwarmWorker] background system agent startup failed: ${err?.message ?? err}`);
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
- * Hot-swap semantics (existing runtime behavior, relied on, not added):
1013
- * prompts re-read per turn, tool HANDLERS re-register per turn, tool
1014
- * DECLARATIONS and MCP configs reach the CLI only on cold create/resume.
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
- // mcpKey is the qualified key for a package agent, the bare
1305
- // name for a deployment/inline one — the only keys registered.
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
- // Per-agent maps. Agents merge by name with later definitions
1452
- // overriding earlier ones (same contract as prompt resolution), so
1453
- // ALWAYS assign: a later definition with no MCP declarations must
1454
- // clear a shadowed definition's grants, never inherit them.
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 key = agent.packageId
1476
- ? packageAgentKey(agent.packageId, agent.name)
1477
- : agent.name;
1478
- if (Object.keys(resolved).length > 0) {
1479
- this._agentMcpServers[key] = resolved;
1480
- }
1481
- else {
1482
- delete this._agentMcpServers[key];
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)) {