pilotswarm-sdk 0.5.63 → 0.5.64

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 (81) 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/cms-migrations.d.ts.map +1 -1
  6. package/dist/cms-migrations.js +4 -0
  7. package/dist/cms-migrations.js.map +1 -1
  8. package/dist/cms.d.ts +3 -0
  9. package/dist/cms.d.ts.map +1 -1
  10. package/dist/cms.js +7 -0
  11. package/dist/cms.js.map +1 -1
  12. package/dist/feature-flag-cache.d.ts +40 -0
  13. package/dist/feature-flag-cache.d.ts.map +1 -0
  14. package/dist/feature-flag-cache.js +125 -0
  15. package/dist/feature-flag-cache.js.map +1 -0
  16. package/dist/feature-flags.d.ts +68 -0
  17. package/dist/feature-flags.d.ts.map +1 -0
  18. package/dist/feature-flags.js +45 -0
  19. package/dist/feature-flags.js.map +1 -0
  20. package/dist/feature-store.d.ts +55 -0
  21. package/dist/feature-store.d.ts.map +1 -0
  22. package/dist/feature-store.js +106 -0
  23. package/dist/feature-store.js.map +1 -0
  24. package/dist/feature-tools.d.ts +94 -0
  25. package/dist/feature-tools.d.ts.map +1 -0
  26. package/dist/feature-tools.js +60 -0
  27. package/dist/feature-tools.js.map +1 -0
  28. package/dist/index.d.ts +6 -0
  29. package/dist/index.d.ts.map +1 -1
  30. package/dist/index.js +4 -0
  31. package/dist/index.js.map +1 -1
  32. package/dist/managed-session.d.ts +4 -0
  33. package/dist/managed-session.d.ts.map +1 -1
  34. package/dist/managed-session.js +99 -10
  35. package/dist/managed-session.js.map +1 -1
  36. package/dist/management-client.d.ts +18 -0
  37. package/dist/management-client.d.ts.map +1 -1
  38. package/dist/management-client.js +19 -0
  39. package/dist/management-client.js.map +1 -1
  40. package/dist/migrations/feature-flags-0077.d.ts +3 -0
  41. package/dist/migrations/feature-flags-0077.d.ts.map +1 -0
  42. package/dist/migrations/feature-flags-0077.js +271 -0
  43. package/dist/migrations/feature-flags-0077.js.map +1 -0
  44. package/dist/migrations/native-tasks-default-policy-0078.d.ts +3 -0
  45. package/dist/migrations/native-tasks-default-policy-0078.d.ts.map +1 -0
  46. package/dist/migrations/native-tasks-default-policy-0078.js +21 -0
  47. package/dist/migrations/native-tasks-default-policy-0078.js.map +1 -0
  48. package/dist/native-subagents.d.ts +25 -0
  49. package/dist/native-subagents.d.ts.map +1 -0
  50. package/dist/native-subagents.js +186 -0
  51. package/dist/native-subagents.js.map +1 -0
  52. package/dist/native-task-observer.d.ts +87 -0
  53. package/dist/native-task-observer.d.ts.map +1 -0
  54. package/dist/native-task-observer.js +268 -0
  55. package/dist/native-task-observer.js.map +1 -0
  56. package/dist/session-manager.d.ts +6 -0
  57. package/dist/session-manager.d.ts.map +1 -1
  58. package/dist/session-manager.js +68 -9
  59. package/dist/session-manager.js.map +1 -1
  60. package/dist/session-proxy.d.ts.map +1 -1
  61. package/dist/session-proxy.js +18 -1
  62. package/dist/session-proxy.js.map +1 -1
  63. package/dist/types.d.ts +8 -0
  64. package/dist/types.d.ts.map +1 -1
  65. package/dist/types.js.map +1 -1
  66. package/dist/web/generated-op-methods.d.ts +96 -0
  67. package/dist/web/generated-op-methods.d.ts.map +1 -1
  68. package/dist/web/generated-op-methods.js +24 -0
  69. package/dist/web/generated-op-methods.js.map +1 -1
  70. package/dist/web/web-management-client.d.ts +13 -0
  71. package/dist/web/web-management-client.d.ts.map +1 -1
  72. package/dist/web/web-management-client.js +12 -0
  73. package/dist/web/web-management-client.js.map +1 -1
  74. package/dist/worker.d.ts +4 -0
  75. package/dist/worker.d.ts.map +1 -1
  76. package/dist/worker.js +40 -11
  77. package/dist/worker.js.map +1 -1
  78. package/package.json +3 -3
  79. package/plugins/mgmt/agents/pilotswarm.agent.md +18 -1
  80. package/plugins/mgmt/agents/resourcemgr.agent.md +18 -1
  81. package/plugins/system/agents/default.agent.md +15 -7
@@ -1,3 +1,4 @@
1
+ import { isNativeChildEvent, settleNativeSubagents, guardNativeExternalTools } from "./native-subagents.js";
1
2
  import { defineTool } from "@github/copilot-sdk";
2
3
  import { normalizeCanvasResponseContract as normalizeCanvasContractShared } from "./canvas-app-manifest.js";
3
4
  // One list gates BOTH halves of every manager tool: the declaration in the
@@ -7,6 +8,7 @@ import { holdsManagerBundle } from "./agent-manager-tools.js";
7
8
  // the declarations in systemToolDefs() and the handlers in runTurn().
8
9
  import { holdsProviderTools, providerToolDefs, providerToolsUnavailable } from "./provider-tools.js";
9
10
  import { LiveTurnCoalescer } from "./live-turn.js";
11
+ import { NativeTaskObserver } from "./native-task-observer.js";
10
12
  const DEFAULT_WAIT_TOOL_DESCRIPTION = "The ONLY way to wait, pause, delay, or pause-before-retry inside a turn: a durable timer that survives " +
11
13
  "restarts and may resume on a different worker (set preserveWorkerAffinity=true for node-local work). " +
12
14
  "NEVER use bash sleep, setTimeout, setInterval, or any other external timing mechanism. " +
@@ -615,6 +617,16 @@ export class ManagedSession {
615
617
  }
616
618
  /** Set for the duration of runTurn(); read by the lock-bypassing stop path. */
617
619
  activeTurn = null;
620
+ nativeFeatureRevoked = false;
621
+ canAdmitNativeTask() {
622
+ return this.config.nativeSubagents === "sync" && !this.nativeFeatureRevoked
623
+ && (this.config.nativeFeatureAllowed?.() ?? false);
624
+ }
625
+ /** A cached OFF is sticky for this turn, even if the next poll is ON. */
626
+ refreshNativeFeaturePolicy() {
627
+ if (this.activeTurn && !this.canAdmitNativeTask())
628
+ this.nativeFeatureRevoked = true;
629
+ }
618
630
  /** Set only by requestStop(); classifies the turn unwind as "stopped". */
619
631
  stopRequest = null;
620
632
  /** Resolver for the current turn's completion promise — hang escalation hook. */
@@ -1124,9 +1136,29 @@ export class ManagedSession {
1124
1136
  * misclassified as a retryable error.
1125
1137
  */
1126
1138
  async runTurn(prompt, opts) {
1139
+ this.nativeFeatureRevoked = false;
1127
1140
  this.activeTurn = { turnIndex: opts?.turnIndex ?? -1, startedAt: Date.now() };
1141
+ let result;
1142
+ let turnError;
1143
+ let failed = false;
1128
1144
  try {
1129
- const result = await this._runTurnInner(prompt, opts);
1145
+ try {
1146
+ // Also retire native tasks restored from an interrupted worker.
1147
+ if (this.config.nativeSubagents === "sync")
1148
+ await settleNativeSubagents(this.copilotSession);
1149
+ result = await this._runTurnInner(prompt, opts);
1150
+ }
1151
+ catch (err) {
1152
+ failed = true;
1153
+ turnError = err;
1154
+ }
1155
+ // Cleanup failures must escape stop/error classification: the
1156
+ // activity cannot commit a snapshot with native work still live.
1157
+ if (this.config.nativeSubagents === "sync")
1158
+ await settleNativeSubagents(this.copilotSession, {
1159
+ rejectRunning: result?.type === "completed" && !this.stopRequest,
1160
+ });
1161
+ // A stop can arrive DURING cleanup. Classify only after it settles.
1130
1162
  if (this.stopRequest) {
1131
1163
  return {
1132
1164
  type: "stopped",
@@ -1134,14 +1166,10 @@ export class ManagedSession {
1134
1166
  ...(result?.events ? { events: result.events } : {}),
1135
1167
  };
1136
1168
  }
1169
+ if (failed)
1170
+ throw turnError;
1137
1171
  return result;
1138
1172
  }
1139
- catch (err) {
1140
- if (this.stopRequest) {
1141
- return { type: "stopped", reason: this.stopRequest.reason };
1142
- }
1143
- throw err;
1144
- }
1145
1173
  finally {
1146
1174
  this.activeTurn = null;
1147
1175
  this.stopRequest = null;
@@ -2500,7 +2528,8 @@ export class ManagedSession {
2500
2528
  // registerTools from the public types (it was always @internal) but
2501
2529
  // ships it unchanged in dist/session.js — cast until a public
2502
2530
  // handler-refresh API exists.
2503
- this.copilotSession.registerTools(allTools);
2531
+ this.copilotSession.registerTools(this.config.nativeSubagents === "sync"
2532
+ ? guardNativeExternalTools(allTools, this.copilotSession.sessionId) : allTools);
2504
2533
  // Collect the final assistant content and all events via on()
2505
2534
  let finalContent;
2506
2535
  const collectedEvents = [];
@@ -2531,6 +2560,19 @@ export class ManagedSession {
2531
2560
  catch { }
2532
2561
  })
2533
2562
  : null;
2563
+ const nativeTasks = this.config.nativeSubagents === "sync"
2564
+ ? new NativeTaskObserver(this.copilotSession, {
2565
+ turnIndex: opts?.turnIndex,
2566
+ emit: (event) => {
2567
+ if (event.eventType !== "session.native_tasks_tick")
2568
+ collectedEvents.push(event);
2569
+ try {
2570
+ opts?.onEvent?.(event);
2571
+ }
2572
+ catch { }
2573
+ },
2574
+ })
2575
+ : null;
2534
2576
  // Note: we used to emit a synthetic `assistant.streaming_progress`
2535
2577
  // heartbeat into CMS for the activity pane. The user found those
2536
2578
  // rows noisy compared to the actual reasoning snapshots, so the
@@ -2657,6 +2699,30 @@ export class ManagedSession {
2657
2699
  eventData.durableSessionId = durableSessionId;
2658
2700
  }
2659
2701
  }
2702
+ nativeTasks?.observe({ ...event, data: eventData });
2703
+ // This empty ephemeral event only invalidates the CLI task
2704
+ // registry. It is neither activity nor durable history.
2705
+ if (eventType === "session.background_tasks_changed")
2706
+ return;
2707
+ if (isNativeChildEvent(event)) {
2708
+ // Child events share the parent subscription. Keep usage
2709
+ // in the existing accounting stream, but namespace child
2710
+ // transcript/tools so they cannot settle parent state or
2711
+ // satisfy a required parent tool invocation.
2712
+ if (/delta|streaming/.test(eventType))
2713
+ return;
2714
+ const nativeEvent = {
2715
+ eventType: eventType === "assistant.usage" || eventType.startsWith("subagent.")
2716
+ ? eventType : `native.${eventType}`,
2717
+ data: { ...eventData, nativeAgentId: event.agentId ?? eventData.nativeAgentId ?? eventData.parentToolCallId },
2718
+ };
2719
+ collectedEvents.push(nativeEvent);
2720
+ try {
2721
+ opts?.onEvent?.(nativeEvent);
2722
+ }
2723
+ catch { }
2724
+ return;
2725
+ }
2660
2726
  const captured = { eventType, data: eventData };
2661
2727
  if (eventType === "session.error" && isBenignPostCompletionQueryError(eventData)) {
2662
2728
  deferredSessionError = captured;
@@ -2782,6 +2848,8 @@ export class ManagedSession {
2782
2848
  }
2783
2849
  }));
2784
2850
  unsubscribers.push(this.copilotSession.on("assistant.reasoning", (event) => {
2851
+ if (isNativeChildEvent(event))
2852
+ return;
2785
2853
  currentReasoning = String(extractReasoningText(event?.data ?? event) || "").trim();
2786
2854
  if (currentReasoning) {
2787
2855
  lastPublishedReasoning = currentReasoning;
@@ -2790,6 +2858,8 @@ export class ManagedSession {
2790
2858
  }));
2791
2859
  for (const eventType of ["assistant.reasoning_delta", "reasoning_delta"]) {
2792
2860
  unsubscribers.push(this.copilotSession.on(eventType, (event) => {
2861
+ if (isNativeChildEvent(event))
2862
+ return;
2793
2863
  currentReasoning = mergeReasoningText(currentReasoning, extractReasoningText(event?.data ?? event));
2794
2864
  publishReasoningSnapshot(eventType);
2795
2865
  }));
@@ -2797,6 +2867,8 @@ export class ManagedSession {
2797
2867
  // Stream deltas to the caller if requested
2798
2868
  if (opts?.onDelta) {
2799
2869
  unsubscribers.push(this.copilotSession.on("assistant.message_delta", (event) => {
2870
+ if (isNativeChildEvent(event))
2871
+ return;
2800
2872
  if (opts.requiredTool && !hasInvokedTool(collectedEvents, opts.requiredTool))
2801
2873
  return;
2802
2874
  if (event.data?.deltaContent) {
@@ -2807,11 +2879,15 @@ export class ManagedSession {
2807
2879
  // Notify caller of tool execution starts
2808
2880
  if (opts?.onToolStart) {
2809
2881
  unsubscribers.push(this.copilotSession.on("tool.execution_start", (event) => {
2882
+ if (isNativeChildEvent(event))
2883
+ return;
2810
2884
  opts.onToolStart(event.data?.toolName ?? "unknown", event.data?.toolArgs);
2811
2885
  }));
2812
2886
  }
2813
2887
  // session.idle = turn finished (normal completion or post-abort)
2814
- unsubscribers.push(this.copilotSession.on("session.idle", () => {
2888
+ unsubscribers.push(this.copilotSession.on("session.idle", (event) => {
2889
+ if (isNativeChildEvent(event))
2890
+ return;
2815
2891
  flushStreamingProgress(true);
2816
2892
  publishReasoningSnapshot("session.idle", true);
2817
2893
  liveTurn?.finishTurn();
@@ -2862,7 +2938,9 @@ export class ManagedSession {
2862
2938
  // the model's response to a mid-turn correction without tearing down the
2863
2939
  // event subscriptions set up above.
2864
2940
  const waitForNextIdle = () => new Promise((resolve) => {
2865
- const unsub = this.copilotSession.on("session.idle", () => {
2941
+ const unsub = this.copilotSession.on("session.idle", (event) => {
2942
+ if (isNativeChildEvent(event))
2943
+ return;
2866
2944
  flushStreamingProgress(true);
2867
2945
  publishReasoningSnapshot("session.idle", true);
2868
2946
  liveTurn?.finishTurn();
@@ -3062,6 +3140,7 @@ export class ManagedSession {
3062
3140
  // live row anyway so reconnecting viewers cannot see stale text.
3063
3141
  liveTurn?.finishTurn();
3064
3142
  liveTurn?.dispose();
3143
+ nativeTasks?.finish(this.stopRequest ? "cancelled" : "interrupted");
3065
3144
  // Always clean up subscriptions
3066
3145
  for (const unsub of unsubscribers)
3067
3146
  unsub();
@@ -3149,6 +3228,10 @@ export class ManagedSession {
3149
3228
  * Update configuration for the next turn.
3150
3229
  */
3151
3230
  updateConfig(config) {
3231
+ if (config.nativeFeatureAllowed !== undefined)
3232
+ this.config.nativeFeatureAllowed = config.nativeFeatureAllowed;
3233
+ if (config.featureToolFingerprint !== undefined)
3234
+ this.config.featureToolFingerprint = config.featureToolFingerprint;
3152
3235
  if (config.model !== undefined)
3153
3236
  this.config.model = config.model;
3154
3237
  if (Object.prototype.hasOwnProperty.call(config, "reasoningEffort"))
@@ -3183,6 +3266,12 @@ export class ManagedSession {
3183
3266
  const nextProviderFingerprint = config.providerFingerprint !== undefined
3184
3267
  ? config.providerFingerprint ?? null
3185
3268
  : currentProviderFingerprint;
3269
+ if (config.nativeSubagents !== undefined
3270
+ && config.nativeSubagents !== (this.config.nativeSubagents ?? "off"))
3271
+ return true;
3272
+ if (config.featureToolFingerprint !== undefined
3273
+ && config.featureToolFingerprint !== this.config.featureToolFingerprint)
3274
+ return true;
3186
3275
  return Boolean((currentModel || nextModel)
3187
3276
  && (currentModel !== nextModel
3188
3277
  || currentReasoningEffort !== nextReasoningEffort