@economic/agents 3.0.0 → 3.1.0-alpha.41659660763.1.0

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/README.md CHANGED
@@ -385,15 +385,12 @@ const send_invoice = tool<ToolContext>({
385
385
  inputSchema: z.object({ invoiceId: z.string() }),
386
386
  executeTask: async ({ invoiceId }, { step }) => {
387
387
  const invoice = await step.do("load", () => loadInvoice(invoiceId));
388
- const approved = await step.requestApproval("send", {
388
+ await step.requestApproval("send", {
389
389
  summary: `Send invoice ${invoice.number} to ${invoice.customer}`,
390
390
  risk: "high",
391
+ required: true,
391
392
  });
392
393
 
393
- if (!approved) {
394
- return { sent: false };
395
- }
396
-
397
394
  return step.do("send", () => sendInvoice(invoiceId));
398
395
  },
399
396
  });
@@ -401,6 +398,8 @@ const send_invoice = tool<ToolContext>({
401
398
 
402
399
  `step.requestApproval(name, { summary, risk })` stops the call until a person answers, and resolves to their decision. An approval nobody answers within `expiresAfterMs` (a day by default) counts as rejected. With `useChat` or `useAssistant` from `@economic/agents-react`, a client sees and answers it as it does a tool's approval: its part has the same `state` and `approval`, and `chat.addToolApprovalResponse` answers it. Other clients use the `pendingApprovals`, `approveExecution` and `rejectExecution` callables.
403
400
 
401
+ Set `required: true` to end the tool call with the SDK's rejected result when the approval is rejected or expires. The rejection remains terminal even if the tool catches its signal or uses branches. `required` defaults to `false`: callers receive `true` or `false` and decide how to proceed. An approved request always resolves to `true`.
402
+
404
403
  `step.runAgent(name, Agent, input, { inheritAuth })` runs another agent and returns its answer; see [migration](./MIGRATION.md#agents-you-run-can-act-as-your-caller) for `inheritAuth`.
405
404
 
406
405
  ### MCP tools
@@ -0,0 +1,114 @@
1
+ // ../../node_modules/@cloudflare/think/dist/hook-proxy-DY2sBNa0.js
2
+ /**
3
+ * Best-effort JSON-safe normalization. Strips functions, AbortSignals,
4
+ * symbols, and replaces `Error` instances with `{ name, message, stack }`.
5
+ * Falls back to `String(value)` for anything that won't round-trip.
6
+ */
7
+ function jsonSafe(value, depth = 0) {
8
+ if (depth > 6) return void 0;
9
+ if (value === null || value === void 0) return value;
10
+ const t = typeof value;
11
+ if (t === "string" || t === "number" || t === "boolean") return value;
12
+ if (t === "bigint") return String(value);
13
+ if (t === "function" || t === "symbol") return void 0;
14
+ if (value instanceof Error) return {
15
+ name: value.name,
16
+ message: value.message,
17
+ stack: value.stack
18
+ };
19
+ if (Array.isArray(value)) return value.map((v) => jsonSafe(v, depth + 1));
20
+ if (t === "object") {
21
+ const out = {};
22
+ for (const [k, v] of Object.entries(value)) {
23
+ if (v instanceof AbortSignal) continue;
24
+ const safe = jsonSafe(v, depth + 1);
25
+ if (safe !== void 0) out[k] = safe;
26
+ }
27
+ return out;
28
+ }
29
+ try {
30
+ return String(value);
31
+ } catch {
32
+ return;
33
+ }
34
+ }
35
+ /**
36
+ * Create a serializable snapshot from a TurnContext.
37
+ *
38
+ * Pass `model` when `beforeTurn` already overrode it: `ctx.model` lazily
39
+ * resolves the default model, which may need an AI binding the turn never uses.
40
+ */
41
+ function createTurnContextSnapshot(ctx, model = ctx.model) {
42
+ return {
43
+ system: ctx.system,
44
+ toolNames: Object.keys(ctx.tools),
45
+ messageCount: ctx.messages.length,
46
+ continuation: ctx.continuation,
47
+ body: ctx.body,
48
+ modelId: typeof model === "string" ? model : model.modelId ?? "unknown",
49
+ ...ctx.requestId !== void 0 && { requestId: ctx.requestId },
50
+ ...ctx.trigger !== void 0 && { trigger: ctx.trigger }
51
+ };
52
+ }
53
+ /**
54
+ * Parse a hook result from the extension Worker's JSON response.
55
+ * Returns a TurnConfig or null if the extension skipped/errored.
56
+ */
57
+ function parseHookResult(json) {
58
+ try {
59
+ const parsed = JSON.parse(json);
60
+ if (parsed.skipped) return { skipped: true };
61
+ if (parsed.error) return { error: parsed.error };
62
+ return { config: parsed.result ?? {} };
63
+ } catch {
64
+ return { error: "Failed to parse hook result" };
65
+ }
66
+ }
67
+ function createToolCallStartSnapshot(event) {
68
+ return {
69
+ toolName: event.toolCall.toolName,
70
+ toolCallId: event.toolCall.toolCallId,
71
+ input: jsonSafe(event.toolCall.input),
72
+ stepNumber: event.stepNumber,
73
+ ...event.toolCall.dynamic !== void 0 ? { dynamic: event.toolCall.dynamic } : {}
74
+ };
75
+ }
76
+ function createToolCallFinishSnapshot(event) {
77
+ return {
78
+ toolName: event.toolCall.toolName,
79
+ toolCallId: event.toolCall.toolCallId,
80
+ input: jsonSafe(event.toolCall.input),
81
+ stepNumber: event.stepNumber,
82
+ durationMs: event.durationMs,
83
+ success: event.success,
84
+ ...event.success ? { output: jsonSafe(event.output) } : { error: jsonSafe(event.error) },
85
+ ...event.toolCall.dynamic !== void 0 ? { dynamic: event.toolCall.dynamic } : {}
86
+ };
87
+ }
88
+ function createStepFinishSnapshot(event) {
89
+ return {
90
+ stepNumber: event.stepNumber,
91
+ finishReason: event.finishReason,
92
+ text: event.text,
93
+ reasoningText: event.reasoningText,
94
+ toolCallCount: event.toolCalls.length,
95
+ toolResultCount: event.toolResults.length,
96
+ usage: event.usage ? {
97
+ inputTokens: event.usage.inputTokens,
98
+ outputTokens: event.usage.outputTokens,
99
+ totalTokens: event.usage.totalTokens,
100
+ reasoningTokens: event.usage.outputTokenDetails?.reasoningTokens ?? event.usage.reasoningTokens,
101
+ cachedInputTokens: event.usage.inputTokenDetails?.cacheReadTokens ?? event.usage.cachedInputTokens
102
+ } : void 0,
103
+ providerMetadata: event.providerMetadata
104
+ };
105
+ }
106
+ function createChunkSnapshot(event) {
107
+ const c = event.chunk;
108
+ const snapshot = { type: c.type };
109
+ if (typeof c.text === "string") snapshot.text = c.text;
110
+ if (typeof c.toolName === "string") snapshot.toolName = c.toolName;
111
+ if (typeof c.toolCallId === "string") snapshot.toolCallId = c.toolCallId;
112
+ return snapshot;
113
+ }
114
+ export { createChunkSnapshot, createStepFinishSnapshot, createToolCallFinishSnapshot, createToolCallStartSnapshot, createTurnContextSnapshot, parseHookResult };