@agentfield/sdk 0.1.77-rc.3 → 0.1.77-rc.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -641,6 +641,15 @@ declare class ReasonerContext<TInput = any> {
641
641
  readonly memory: MemoryInterface;
642
642
  readonly workflow: WorkflowReporter;
643
643
  readonly did: DidInterface;
644
+ /**
645
+ * AbortSignal that fires when the control plane cancels this execution
646
+ * (per-execution cancel, the bottom-up cancel-tree endpoint, or any
647
+ * future source that flips the bus). Pass it through to `fetch`, the
648
+ * @anthropic-ai/sdk, the openai SDK, or anywhere that accepts
649
+ * `{ signal }` to short-circuit in-flight work mid-call. For pure-JS
650
+ * CPU loops, check `ctx.signal.aborted` periodically and throw.
651
+ */
652
+ readonly signal: AbortSignal;
644
653
  constructor(params: {
645
654
  input: TInput;
646
655
  executionId: string;
@@ -662,6 +671,7 @@ declare class ReasonerContext<TInput = any> {
662
671
  memory: MemoryInterface;
663
672
  workflow: WorkflowReporter;
664
673
  did: DidInterface;
674
+ signal?: AbortSignal;
665
675
  });
666
676
  ai<T>(prompt: string, options: AIRequestOptions & {
667
677
  schema: ZodSchema<T>;
@@ -719,6 +729,8 @@ declare class SkillContext<TInput = any> {
719
729
  readonly memory: MemoryInterface;
720
730
  readonly workflow: WorkflowReporter;
721
731
  readonly did: DidInterface;
732
+ /** AbortSignal — see ReasonerContext for usage. */
733
+ readonly signal: AbortSignal;
722
734
  constructor(params: {
723
735
  input: TInput;
724
736
  executionId: string;
@@ -735,6 +747,7 @@ declare class SkillContext<TInput = any> {
735
747
  memory: MemoryInterface;
736
748
  workflow: WorkflowReporter;
737
749
  did: DidInterface;
750
+ signal?: AbortSignal;
738
751
  });
739
752
  discover(options?: DiscoveryOptions): Promise<DiscoveryResult>;
740
753
  }
@@ -1086,6 +1099,11 @@ declare class Agent {
1086
1099
  private readonly realtimeValidationFunctions;
1087
1100
  private readonly processLogRing;
1088
1101
  private readonly executionLogger;
1102
+ /** Tracks an AbortController per in-flight execution_id so the
1103
+ * `/_internal/executions/:id/cancel` route can short-circuit reasoner
1104
+ * code that respects `signal.aborted` (fetch, anthropic SDK, openai
1105
+ * SDK, etc.). See ./cancel.ts. */
1106
+ private readonly cancelRegistry;
1089
1107
  constructor(config: AgentConfig);
1090
1108
  reasoner<TInput = any, TOutput = any>(name: string, handler: ReasonerHandler<TInput, TOutput>, options?: ReasonerOptions): this;
1091
1109
  skill<TInput = any, TOutput = any>(name: string, handler: SkillHandler<TInput, TOutput>, options?: SkillOptions): this;
package/dist/index.js CHANGED
@@ -877,6 +877,86 @@ var SkillRegistry = class {
877
877
  return Array.from(this.skills.values());
878
878
  }
879
879
  };
880
+
881
+ // src/agent/cancel.ts
882
+ var CancelRegistry = class {
883
+ controllers = /* @__PURE__ */ new Map();
884
+ /**
885
+ * Register a fresh AbortController against an execution_id. Returns the
886
+ * controller and a `release()` cleanup function that must be called on
887
+ * completion (success, failure, or cancellation) to drop the entry.
888
+ * Empty `executionId` produces a controller that is NOT registered,
889
+ * so callers always get a usable signal even outside the control-plane
890
+ * dispatch path (e.g. local manual invocations).
891
+ */
892
+ register(executionId) {
893
+ const controller = new AbortController();
894
+ if (!executionId) {
895
+ return { controller, release: () => {
896
+ } };
897
+ }
898
+ this.controllers.set(executionId, controller);
899
+ let released = false;
900
+ const release = () => {
901
+ if (released) return;
902
+ released = true;
903
+ const current = this.controllers.get(executionId);
904
+ if (current === controller) {
905
+ this.controllers.delete(executionId);
906
+ }
907
+ };
908
+ return { controller, release };
909
+ }
910
+ /**
911
+ * Cancel the AbortController registered for `executionId`. Returns
912
+ * true if a matching controller was found and aborted, false if there
913
+ * was no active execution (already finished, or never dispatched here).
914
+ */
915
+ cancel(executionId, reason) {
916
+ if (!executionId) return false;
917
+ const controller = this.controllers.get(executionId);
918
+ if (!controller) return false;
919
+ if (controller.signal.aborted) {
920
+ return true;
921
+ }
922
+ controller.abort(reason ?? "cancelled_by_control_plane");
923
+ this.controllers.delete(executionId);
924
+ return true;
925
+ }
926
+ /** Number of in-flight registrations. Useful for tests. */
927
+ size() {
928
+ return this.controllers.size;
929
+ }
930
+ };
931
+ function installCancelRoute(app, registry, logger) {
932
+ app.post(
933
+ "/_internal/executions/:executionId/cancel",
934
+ (req, res) => {
935
+ const executionId = (req.params.executionId ?? "").trim();
936
+ if (!executionId) {
937
+ res.status(404).json({ error: "invalid execution_id" });
938
+ return;
939
+ }
940
+ const cancelled = registry.cancel(
941
+ executionId,
942
+ typeof req.body?.reason === "string" ? req.body.reason : void 0
943
+ );
944
+ if (cancelled) {
945
+ logger?.info("cancel-callback fired", {
946
+ executionId,
947
+ source: req.headers["x-agentfield-source"] ?? "unknown"
948
+ });
949
+ res.status(200).json({ cancelled: true, execution_id: executionId });
950
+ } else {
951
+ res.status(200).json({
952
+ cancelled: false,
953
+ execution_id: executionId,
954
+ reason: "execution_not_active"
955
+ });
956
+ }
957
+ }
958
+ );
959
+ }
880
960
  var store = new AsyncLocalStorage();
881
961
  var ExecutionContext = class {
882
962
  input;
@@ -1217,6 +1297,15 @@ var ReasonerContext = class {
1217
1297
  memory;
1218
1298
  workflow;
1219
1299
  did;
1300
+ /**
1301
+ * AbortSignal that fires when the control plane cancels this execution
1302
+ * (per-execution cancel, the bottom-up cancel-tree endpoint, or any
1303
+ * future source that flips the bus). Pass it through to `fetch`, the
1304
+ * @anthropic-ai/sdk, the openai SDK, or anywhere that accepts
1305
+ * `{ signal }` to short-circuit in-flight work mid-call. For pure-JS
1306
+ * CPU loops, check `ctx.signal.aborted` periodically and throw.
1307
+ */
1308
+ signal;
1220
1309
  constructor(params) {
1221
1310
  this.input = params.input;
1222
1311
  this.executionId = params.executionId;
@@ -1238,6 +1327,7 @@ var ReasonerContext = class {
1238
1327
  this.memory = params.memory;
1239
1328
  this.workflow = params.workflow;
1240
1329
  this.did = params.did;
1330
+ this.signal = params.signal ?? new AbortController().signal;
1241
1331
  }
1242
1332
  ai(prompt, options) {
1243
1333
  if (options?.tools) {
@@ -1341,6 +1431,8 @@ var SkillContext = class {
1341
1431
  memory;
1342
1432
  workflow;
1343
1433
  did;
1434
+ /** AbortSignal — see ReasonerContext for usage. */
1435
+ signal;
1344
1436
  constructor(params) {
1345
1437
  this.input = params.input;
1346
1438
  this.executionId = params.executionId;
@@ -1357,6 +1449,7 @@ var SkillContext = class {
1357
1449
  this.memory = params.memory;
1358
1450
  this.workflow = params.workflow;
1359
1451
  this.did = params.did;
1452
+ this.signal = params.signal ?? new AbortController().signal;
1360
1453
  }
1361
1454
  discover(options) {
1362
1455
  return this.agent.discover(options);
@@ -3613,6 +3706,11 @@ var Agent = class {
3613
3706
  realtimeValidationFunctions = /* @__PURE__ */ new Set();
3614
3707
  processLogRing = new ProcessLogRing();
3615
3708
  executionLogger;
3709
+ /** Tracks an AbortController per in-flight execution_id so the
3710
+ * `/_internal/executions/:id/cancel` route can short-circuit reasoner
3711
+ * code that respects `signal.aborted` (fetch, anthropic SDK, openai
3712
+ * SDK, etc.). See ./cancel.ts. */
3713
+ cancelRegistry = new CancelRegistry();
3616
3714
  constructor(config) {
3617
3715
  this.config = {
3618
3716
  port: 8001,
@@ -3648,6 +3746,9 @@ var Agent = class {
3648
3746
  this.registerDefaultRoutes();
3649
3747
  installStdioLogCapture(this.processLogRing);
3650
3748
  registerAgentfieldLogsRoute(this.app, this.processLogRing);
3749
+ installCancelRoute(this.app, this.cancelRegistry, {
3750
+ info: (message, meta) => this.executionLogger.system("execution.cancel.received", message, meta ?? {})
3751
+ });
3651
3752
  }
3652
3753
  reasoner(name, handler, options) {
3653
3754
  this.reasoners.register(name, handler, options);
@@ -4500,6 +4601,9 @@ var Agent = class {
4500
4601
  res,
4501
4602
  agent: this
4502
4603
  });
4604
+ const { controller, release } = this.cancelRegistry.register(
4605
+ executionMetadata.executionId
4606
+ );
4503
4607
  return ExecutionContext.run(execCtx, async () => {
4504
4608
  this.executionLogger.system("execution.started", "Execution started", {
4505
4609
  target: params.targetName,
@@ -4538,7 +4642,8 @@ var Agent = class {
4538
4642
  aiClient: this.aiClient,
4539
4643
  memory: this.getMemoryInterface(executionMetadata),
4540
4644
  workflow: this.getWorkflowReporter(executionMetadata),
4541
- did: this.getDidInterface(executionMetadata, params.input, params.targetName)
4645
+ did: this.getDidInterface(executionMetadata, params.input, params.targetName),
4646
+ signal: controller.signal
4542
4647
  });
4543
4648
  const result = await reasoner.handler(ctx);
4544
4649
  this.executionLogger.system("reasoner.completed", "Reasoner execution completed", {
@@ -4597,6 +4702,8 @@ var Agent = class {
4597
4702
  return;
4598
4703
  }
4599
4704
  throw err;
4705
+ } finally {
4706
+ release();
4600
4707
  }
4601
4708
  });
4602
4709
  }
@@ -4615,6 +4722,9 @@ var Agent = class {
4615
4722
  res,
4616
4723
  agent: this
4617
4724
  });
4725
+ const { controller, release } = this.cancelRegistry.register(
4726
+ executionMetadata.executionId
4727
+ );
4618
4728
  return ExecutionContext.run(execCtx, async () => {
4619
4729
  this.executionLogger.system("execution.started", "Execution started", {
4620
4730
  target: params.targetName,
@@ -4646,7 +4756,8 @@ var Agent = class {
4646
4756
  logger: this.executionLogger,
4647
4757
  memory: this.getMemoryInterface(executionMetadata),
4648
4758
  workflow: this.getWorkflowReporter(executionMetadata),
4649
- did: this.getDidInterface(executionMetadata, params.input, params.targetName)
4759
+ did: this.getDidInterface(executionMetadata, params.input, params.targetName),
4760
+ signal: controller.signal
4650
4761
  });
4651
4762
  const result = await skill.handler(ctx);
4652
4763
  this.executionLogger.system("skill.completed", "Skill execution completed", {
@@ -4705,6 +4816,8 @@ var Agent = class {
4705
4816
  return;
4706
4817
  }
4707
4818
  throw err;
4819
+ } finally {
4820
+ release();
4708
4821
  }
4709
4822
  });
4710
4823
  }