@minpeter/pss-runtime 0.1.0-next.0 → 0.1.0-next.2
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 +223 -191
- package/dist/agent-child-runs.js +16 -0
- package/dist/agent-child-runs.js.map +1 -0
- package/dist/agent-host-capabilities.js +9 -0
- package/dist/agent-host-capabilities.js.map +1 -0
- package/dist/agent-host-session-store.js +12 -0
- package/dist/agent-host-session-store.js.map +1 -0
- package/dist/agent-loop.js +59 -35
- package/dist/agent-loop.js.map +1 -1
- package/dist/agent-namespace.js +24 -0
- package/dist/agent-namespace.js.map +1 -0
- package/dist/agent-options.d.ts +35 -0
- package/dist/agent-options.js +16 -0
- package/dist/agent-options.js.map +1 -0
- package/dist/agent-resume.js +143 -0
- package/dist/agent-resume.js.map +1 -0
- package/dist/agent-session-entry.d.ts +13 -0
- package/dist/agent-validation.js +35 -0
- package/dist/agent-validation.js.map +1 -0
- package/dist/agent.d.ts +8 -33
- package/dist/agent.js +131 -55
- package/dist/agent.js.map +1 -1
- package/dist/child-session-cleanups.js +61 -0
- package/dist/child-session-cleanups.js.map +1 -0
- package/dist/execution/host.js +14 -0
- package/dist/execution/host.js.map +1 -0
- package/dist/execution/index.d.ts +4 -0
- package/dist/execution/index.js +3 -0
- package/dist/execution/memory-notifications.js +54 -0
- package/dist/execution/memory-notifications.js.map +1 -0
- package/dist/execution/memory-state.js +34 -0
- package/dist/execution/memory-state.js.map +1 -0
- package/dist/execution/memory-store.js +203 -0
- package/dist/execution/memory-store.js.map +1 -0
- package/dist/execution/memory.d.ts +7 -0
- package/dist/execution/memory.js +28 -0
- package/dist/execution/memory.js.map +1 -0
- package/dist/execution/run.js +55 -0
- package/dist/execution/run.js.map +1 -0
- package/dist/execution/types.d.ts +155 -0
- package/dist/index.d.ts +9 -10
- package/dist/index.js +1 -6
- package/dist/llm-tool-execution.d.ts +35 -0
- package/dist/llm-tool-execution.js +126 -0
- package/dist/llm-tool-execution.js.map +1 -0
- package/dist/llm.d.ts +11 -15
- package/dist/llm.js +5 -9
- package/dist/llm.js.map +1 -1
- package/dist/plugins.d.ts +20 -0
- package/dist/plugins.js +14 -0
- package/dist/plugins.js.map +1 -0
- package/dist/session/events.d.ts +26 -20
- package/dist/session/input-normalization.js +66 -0
- package/dist/session/input-normalization.js.map +1 -0
- package/dist/session/input.d.ts +0 -4
- package/dist/session/mapping.js +1 -2
- package/dist/session/mapping.js.map +1 -1
- package/dist/session/run.js +1 -0
- package/dist/session/run.js.map +1 -1
- package/dist/session/runtime-input.js +20 -58
- package/dist/session/runtime-input.js.map +1 -1
- package/dist/session/session-errors.js +18 -0
- package/dist/session/session-errors.js.map +1 -0
- package/dist/session/session-events.js +59 -0
- package/dist/session/session-events.js.map +1 -0
- package/dist/session/session-execution.js +88 -0
- package/dist/session/session-execution.js.map +1 -0
- package/dist/session/session-kill.js +23 -0
- package/dist/session/session-kill.js.map +1 -0
- package/dist/session/session-notification.js +58 -0
- package/dist/session/session-notification.js.map +1 -0
- package/dist/session/session-runtime-drain.js +22 -0
- package/dist/session/session-runtime-drain.js.map +1 -0
- package/dist/session/session-state.js +102 -0
- package/dist/session/session-state.js.map +1 -0
- package/dist/session/session-turn-error.js +35 -0
- package/dist/session/session-turn-error.js.map +1 -0
- package/dist/session/session-turn-processor.js +135 -0
- package/dist/session/session-turn-processor.js.map +1 -0
- package/dist/session/session.js +125 -335
- package/dist/session/session.js.map +1 -1
- package/dist/session/snapshot.js +5 -31
- package/dist/session/snapshot.js.map +1 -1
- package/dist/session/store/file.d.ts +1 -0
- package/dist/session/store/file.js +14 -0
- package/dist/session/store/file.js.map +1 -1
- package/dist/session/store/memory.d.ts +1 -0
- package/dist/session/store/memory.js +5 -0
- package/dist/session/store/memory.js.map +1 -1
- package/dist/session/store/types.d.ts +1 -0
- package/dist/subagent-background-child-run-state.js +51 -0
- package/dist/subagent-background-child-run-state.js.map +1 -0
- package/dist/subagent-background-child-run.js +103 -0
- package/dist/subagent-background-child-run.js.map +1 -0
- package/dist/subagent-background-in-process.js +98 -0
- package/dist/subagent-background-in-process.js.map +1 -0
- package/dist/subagent-background-notification-inbox.js +106 -0
- package/dist/subagent-background-notification-inbox.js.map +1 -0
- package/dist/subagent-background-notify.js +136 -0
- package/dist/subagent-background-notify.js.map +1 -0
- package/dist/subagent-background-resume-group.js +99 -0
- package/dist/subagent-background-resume-group.js.map +1 -0
- package/dist/subagent-background-runner.js +115 -0
- package/dist/subagent-background-runner.js.map +1 -0
- package/dist/subagent-background-schedule.js +43 -0
- package/dist/subagent-background-schedule.js.map +1 -0
- package/dist/subagent-child-run.js +68 -0
- package/dist/subagent-child-run.js.map +1 -0
- package/dist/subagent-job-cancel.js +84 -0
- package/dist/subagent-job-cancel.js.map +1 -0
- package/dist/subagent-job-observer.js +19 -0
- package/dist/subagent-job-observer.js.map +1 -0
- package/dist/subagent-job-output.js +87 -0
- package/dist/subagent-job-output.js.map +1 -0
- package/dist/subagent-job-state.js +66 -0
- package/dist/subagent-job-state.js.map +1 -0
- package/dist/subagent-jobs.js +96 -0
- package/dist/subagent-jobs.js.map +1 -0
- package/dist/subagent-prompt-schema.js +114 -0
- package/dist/subagent-prompt-schema.js.map +1 -0
- package/dist/subagent-run.js +111 -0
- package/dist/subagent-run.js.map +1 -0
- package/dist/subagents.js +125 -0
- package/dist/subagents.js.map +1 -0
- package/package.json +11 -6
- package/dist/plugins/compaction.d.ts +0 -15
- package/dist/plugins/compaction.js +0 -98
- package/dist/plugins/compaction.js.map +0 -1
- package/dist/plugins/index.d.ts +0 -5
- package/dist/plugins/index.js +0 -5
- package/dist/plugins/memory.d.ts +0 -11
- package/dist/plugins/memory.js +0 -146
- package/dist/plugins/memory.js.map +0 -1
- package/dist/plugins/runner.d.ts +0 -1
- package/dist/plugins/runner.js +0 -83
- package/dist/plugins/runner.js.map +0 -1
- package/dist/plugins/scope.js +0 -13
- package/dist/plugins/scope.js.map +0 -1
- package/dist/plugins/sessions.d.ts +0 -12
- package/dist/plugins/sessions.js +0 -34
- package/dist/plugins/sessions.js.map +0 -1
- package/dist/plugins/tool-hook-handlers.js +0 -77
- package/dist/plugins/tool-hook-handlers.js.map +0 -1
- package/dist/plugins/tool-hook-results.js +0 -64
- package/dist/plugins/tool-hook-results.js.map +0 -1
- package/dist/plugins/tool-hooks.js +0 -111
- package/dist/plugins/tool-hooks.js.map +0 -1
- package/dist/plugins/types.d.ts +0 -105
- package/dist/plugins/types.js +0 -20
- package/dist/plugins/types.js.map +0 -1
- package/dist/session/lifecycle.d.ts +0 -12
- package/dist/session/lifecycle.js +0 -126
- package/dist/session/lifecycle.js.map +0 -1
- package/dist/session/overlay-anchor.js +0 -151
- package/dist/session/overlay-anchor.js.map +0 -1
- package/dist/session/overlay.js +0 -141
- package/dist/session/overlay.js.map +0 -1
- package/dist/session/snapshot.d.ts +0 -1
- /package/dist/{agent-loop.d.ts → session/history.d.ts} +0 -0
- /package/dist/session/{runtime-input.d.ts → session-execution.d.ts} +0 -0
- /package/dist/{plugins/scope.d.ts → session/session-state.d.ts} +0 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
//#region src/llm-tool-execution.ts
|
|
2
|
+
const toolCallIdPrefix = "call_";
|
|
3
|
+
const publicToolCallIdPattern = /^call[-_]/;
|
|
4
|
+
var ToolExecutionNeedsRecoveryError = class extends Error {
|
|
5
|
+
idempotencyKey;
|
|
6
|
+
status = "needs-recovery";
|
|
7
|
+
toolCallId;
|
|
8
|
+
toolName;
|
|
9
|
+
constructor(checkpoint) {
|
|
10
|
+
super(`Tool ${checkpoint.toolName} requires manual recovery for ${checkpoint.idempotencyKey}`);
|
|
11
|
+
this.idempotencyKey = checkpoint.idempotencyKey;
|
|
12
|
+
this.name = "ToolExecutionNeedsRecoveryError";
|
|
13
|
+
this.toolCallId = checkpoint.toolCallId;
|
|
14
|
+
this.toolName = checkpoint.toolName;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
function persistedToolExecutionCheckpoint(checkpoint) {
|
|
18
|
+
return {
|
|
19
|
+
attempt: checkpoint.attempt,
|
|
20
|
+
idempotencyKey: checkpoint.idempotencyKey,
|
|
21
|
+
policy: checkpoint.policy,
|
|
22
|
+
toolCallId: checkpoint.toolCallId,
|
|
23
|
+
toolName: checkpoint.toolName
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function normalizeToolCallIds(tools, toolCallIds, toolExecution) {
|
|
27
|
+
if (!tools) return;
|
|
28
|
+
return Object.fromEntries(Object.entries(tools).map(([name, candidate]) => [name, wrapToolExecute(name, candidate, toolCallIds, toolExecution)]));
|
|
29
|
+
}
|
|
30
|
+
function rewriteMessageToolCallIds(message, toolCallIds) {
|
|
31
|
+
if (message.role === "assistant") return rewriteAssistantToolCallIds(message, toolCallIds);
|
|
32
|
+
if (message.role === "tool") return rewriteToolResultCallIds(message, toolCallIds);
|
|
33
|
+
return message;
|
|
34
|
+
}
|
|
35
|
+
function wrapToolExecute(toolName, toolDefinition, toolCallIds, toolExecution) {
|
|
36
|
+
if (!isExecutableToolDefinition(toolDefinition)) return toolDefinition;
|
|
37
|
+
const { execute } = toolDefinition;
|
|
38
|
+
if (!toolExecution) return {
|
|
39
|
+
...toolDefinition,
|
|
40
|
+
execute: (input, options) => execute(input, {
|
|
41
|
+
...options,
|
|
42
|
+
toolCallId: publicToolCallId(options.toolCallId, toolCallIds)
|
|
43
|
+
})
|
|
44
|
+
};
|
|
45
|
+
return {
|
|
46
|
+
...toolDefinition,
|
|
47
|
+
execute: async (input, options) => {
|
|
48
|
+
const toolCallId = publicToolCallId(options.toolCallId, toolCallIds);
|
|
49
|
+
const checkpoint = toolCheckpoint({
|
|
50
|
+
input,
|
|
51
|
+
policy: toolRetryPolicy(toolDefinition),
|
|
52
|
+
toolCallId,
|
|
53
|
+
toolExecution,
|
|
54
|
+
toolName
|
|
55
|
+
});
|
|
56
|
+
if ((await toolExecution.beforeTool?.(checkpoint))?.status === "needs-recovery") throw new ToolExecutionNeedsRecoveryError(checkpoint);
|
|
57
|
+
const output = await execute(input, {
|
|
58
|
+
...options,
|
|
59
|
+
attempt: checkpoint.attempt,
|
|
60
|
+
idempotencyKey: checkpoint.idempotencyKey,
|
|
61
|
+
retryPolicy: checkpoint.policy,
|
|
62
|
+
...options.abortSignal === void 0 ? {} : { signal: options.abortSignal },
|
|
63
|
+
toolCallId
|
|
64
|
+
});
|
|
65
|
+
await toolExecution.afterTool?.({
|
|
66
|
+
...checkpoint,
|
|
67
|
+
output
|
|
68
|
+
});
|
|
69
|
+
return output;
|
|
70
|
+
}
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
function isExecutableToolDefinition(value) {
|
|
74
|
+
return typeof value === "object" && value !== null && "execute" in value && typeof value.execute === "function";
|
|
75
|
+
}
|
|
76
|
+
function toolCheckpoint({ input, policy, toolCallId, toolExecution, toolName }) {
|
|
77
|
+
return {
|
|
78
|
+
attempt: toolExecution.attempt,
|
|
79
|
+
idempotencyKey: `${toolExecution.runId}:${toolCallId}`,
|
|
80
|
+
input,
|
|
81
|
+
policy,
|
|
82
|
+
toolCallId,
|
|
83
|
+
toolName
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function toolRetryPolicy(toolDefinition) {
|
|
87
|
+
if (typeof toolDefinition === "object" && toolDefinition !== null && "retryPolicy" in toolDefinition && isToolRetryPolicy(toolDefinition.retryPolicy)) return toolDefinition.retryPolicy;
|
|
88
|
+
return "manual-recovery";
|
|
89
|
+
}
|
|
90
|
+
function isToolRetryPolicy(value) {
|
|
91
|
+
return value === "idempotent" || value === "manual-recovery" || value === "pure";
|
|
92
|
+
}
|
|
93
|
+
function rewriteAssistantToolCallIds(message, toolCallIds) {
|
|
94
|
+
if (typeof message.content === "string") return message;
|
|
95
|
+
return {
|
|
96
|
+
...message,
|
|
97
|
+
content: message.content.map((part) => "toolCallId" in part ? {
|
|
98
|
+
...part,
|
|
99
|
+
toolCallId: publicToolCallId(part.toolCallId, toolCallIds)
|
|
100
|
+
} : part)
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function rewriteToolResultCallIds(message, toolCallIds) {
|
|
104
|
+
return {
|
|
105
|
+
...message,
|
|
106
|
+
content: message.content.map((part) => "toolCallId" in part ? {
|
|
107
|
+
...part,
|
|
108
|
+
toolCallId: publicToolCallId(part.toolCallId, toolCallIds)
|
|
109
|
+
} : part)
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
function publicToolCallId(toolCallId, toolCallIds) {
|
|
113
|
+
if (publicToolCallIdPattern.test(toolCallId)) return toolCallId;
|
|
114
|
+
const existing = toolCallIds.get(toolCallId);
|
|
115
|
+
if (existing) return existing;
|
|
116
|
+
const generated = createToolCallId();
|
|
117
|
+
toolCallIds.set(toolCallId, generated);
|
|
118
|
+
return generated;
|
|
119
|
+
}
|
|
120
|
+
function createToolCallId() {
|
|
121
|
+
return `${toolCallIdPrefix}${crypto.randomUUID().replaceAll("-", "")}`;
|
|
122
|
+
}
|
|
123
|
+
//#endregion
|
|
124
|
+
export { ToolExecutionNeedsRecoveryError, normalizeToolCallIds, persistedToolExecutionCheckpoint, rewriteMessageToolCallIds };
|
|
125
|
+
|
|
126
|
+
//# sourceMappingURL=llm-tool-execution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-tool-execution.js","names":[],"sources":["../src/llm-tool-execution.ts"],"sourcesContent":["import type { AssistantModelMessage, ToolModelMessage, ToolSet } from \"ai\";\nimport type { RuntimeLlmOutput } from \"./llm\";\n\nconst toolCallIdPrefix = \"call_\";\nconst publicToolCallIdPattern = /^call[-_]/;\n\ntype RuntimeLlmMessage = RuntimeLlmOutput[number];\n\nexport type RuntimeToolRetryPolicy = \"idempotent\" | \"manual-recovery\" | \"pure\";\n\nexport interface RuntimeToolExecutionCheckpointMetadata {\n readonly attempt: number;\n readonly idempotencyKey: string;\n readonly policy: RuntimeToolRetryPolicy;\n readonly toolCallId: string;\n readonly toolName: string;\n}\n\nexport interface RuntimeToolExecutionCheckpoint\n extends RuntimeToolExecutionCheckpointMetadata {\n readonly input: unknown;\n}\n\nexport type RuntimePersistedToolExecutionCheckpoint =\n RuntimeToolExecutionCheckpointMetadata;\n\nexport type RuntimeToolExecutionDecision =\n | { readonly status: \"needs-recovery\" }\n | undefined;\n\nexport interface RuntimeToolExecutionContext {\n readonly afterTool?: (\n checkpoint: RuntimeToolExecutionCheckpoint & { readonly output: unknown }\n ) => Promise<void> | void;\n readonly attempt: number;\n readonly beforeTool?: (\n checkpoint: RuntimeToolExecutionCheckpoint\n ) => Promise<RuntimeToolExecutionDecision> | RuntimeToolExecutionDecision;\n readonly runId: string;\n}\n\nexport class ToolExecutionNeedsRecoveryError extends Error {\n readonly idempotencyKey: string;\n readonly status = \"needs-recovery\";\n readonly toolCallId: string;\n readonly toolName: string;\n\n constructor(checkpoint: RuntimeToolExecutionCheckpointMetadata) {\n super(\n `Tool ${checkpoint.toolName} requires manual recovery for ${checkpoint.idempotencyKey}`\n );\n this.idempotencyKey = checkpoint.idempotencyKey;\n this.name = \"ToolExecutionNeedsRecoveryError\";\n this.toolCallId = checkpoint.toolCallId;\n this.toolName = checkpoint.toolName;\n }\n}\n\nexport function persistedToolExecutionCheckpoint(\n checkpoint: RuntimeToolExecutionCheckpointMetadata\n): RuntimePersistedToolExecutionCheckpoint {\n return {\n attempt: checkpoint.attempt,\n idempotencyKey: checkpoint.idempotencyKey,\n policy: checkpoint.policy,\n toolCallId: checkpoint.toolCallId,\n toolName: checkpoint.toolName,\n };\n}\n\nexport function normalizeToolCallIds(\n tools: ToolSet | undefined,\n toolCallIds: Map<string, string>,\n toolExecution: RuntimeToolExecutionContext | undefined\n): ToolSet | undefined {\n if (!tools) {\n return;\n }\n\n return Object.fromEntries(\n Object.entries(tools).map(([name, candidate]) => [\n name,\n wrapToolExecute(name, candidate, toolCallIds, toolExecution),\n ])\n ) as ToolSet;\n}\n\nexport function rewriteMessageToolCallIds(\n message: RuntimeLlmMessage,\n toolCallIds: Map<string, string>\n): RuntimeLlmMessage {\n if (message.role === \"assistant\") {\n return rewriteAssistantToolCallIds(message, toolCallIds);\n }\n\n if (message.role === \"tool\") {\n return rewriteToolResultCallIds(message, toolCallIds);\n }\n\n return message;\n}\n\nfunction wrapToolExecute(\n toolName: string,\n toolDefinition: unknown,\n toolCallIds: Map<string, string>,\n toolExecution: RuntimeToolExecutionContext | undefined\n): unknown {\n if (!isExecutableToolDefinition(toolDefinition)) {\n return toolDefinition;\n }\n\n const { execute } = toolDefinition;\n if (!toolExecution) {\n return {\n ...toolDefinition,\n execute: (input: unknown, options: ToolExecutionOptionsLike) =>\n execute(input, {\n ...options,\n toolCallId: publicToolCallId(options.toolCallId, toolCallIds),\n }),\n };\n }\n\n return {\n ...toolDefinition,\n execute: async (input: unknown, options: ToolExecutionOptionsLike) => {\n const toolCallId = publicToolCallId(options.toolCallId, toolCallIds);\n const checkpoint = toolCheckpoint({\n input,\n policy: toolRetryPolicy(toolDefinition),\n toolCallId,\n toolExecution,\n toolName,\n });\n const decision = await toolExecution.beforeTool?.(checkpoint);\n if (decision?.status === \"needs-recovery\") {\n throw new ToolExecutionNeedsRecoveryError(checkpoint);\n }\n\n const output = await execute(input, {\n ...options,\n attempt: checkpoint.attempt,\n idempotencyKey: checkpoint.idempotencyKey,\n retryPolicy: checkpoint.policy,\n ...(options.abortSignal === undefined\n ? {}\n : { signal: options.abortSignal }),\n toolCallId,\n });\n await toolExecution.afterTool?.({ ...checkpoint, output });\n return output;\n },\n };\n}\n\nfunction isExecutableToolDefinition(value: unknown): value is {\n readonly execute: (\n input: unknown,\n options: RuntimeToolExecutionOptionsLike | ToolExecutionOptionsLike\n ) => unknown;\n} {\n return (\n typeof value === \"object\" &&\n value !== null &&\n \"execute\" in value &&\n typeof value.execute === \"function\"\n );\n}\n\ninterface ToolExecutionOptionsLike {\n readonly abortSignal?: AbortSignal;\n readonly toolCallId: string;\n}\n\ninterface RuntimeToolExecutionOptionsLike extends ToolExecutionOptionsLike {\n readonly attempt: number;\n readonly idempotencyKey: string;\n readonly retryPolicy: RuntimeToolRetryPolicy;\n readonly signal?: AbortSignal;\n}\n\nfunction toolCheckpoint({\n input,\n policy,\n toolCallId,\n toolExecution,\n toolName,\n}: {\n readonly input: unknown;\n readonly policy: RuntimeToolRetryPolicy;\n readonly toolCallId: string;\n readonly toolExecution: RuntimeToolExecutionContext;\n readonly toolName: string;\n}): RuntimeToolExecutionCheckpoint {\n return {\n attempt: toolExecution.attempt,\n idempotencyKey: `${toolExecution.runId}:${toolCallId}`,\n input,\n policy,\n toolCallId,\n toolName,\n };\n}\n\nfunction toolRetryPolicy(toolDefinition: unknown): RuntimeToolRetryPolicy {\n if (\n typeof toolDefinition === \"object\" &&\n toolDefinition !== null &&\n \"retryPolicy\" in toolDefinition &&\n isToolRetryPolicy(toolDefinition.retryPolicy)\n ) {\n return toolDefinition.retryPolicy;\n }\n\n return \"manual-recovery\";\n}\n\nfunction isToolRetryPolicy(value: unknown): value is RuntimeToolRetryPolicy {\n return (\n value === \"idempotent\" || value === \"manual-recovery\" || value === \"pure\"\n );\n}\n\nfunction rewriteAssistantToolCallIds(\n message: AssistantModelMessage,\n toolCallIds: Map<string, string>\n): AssistantModelMessage {\n if (typeof message.content === \"string\") {\n return message;\n }\n\n return {\n ...message,\n content: message.content.map((part) =>\n \"toolCallId\" in part\n ? {\n ...part,\n toolCallId: publicToolCallId(part.toolCallId, toolCallIds),\n }\n : part\n ),\n };\n}\n\nfunction rewriteToolResultCallIds(\n message: ToolModelMessage,\n toolCallIds: Map<string, string>\n): ToolModelMessage {\n return {\n ...message,\n content: message.content.map((part) =>\n \"toolCallId\" in part\n ? {\n ...part,\n toolCallId: publicToolCallId(part.toolCallId, toolCallIds),\n }\n : part\n ),\n };\n}\n\nfunction publicToolCallId(\n toolCallId: string,\n toolCallIds: Map<string, string>\n): string {\n if (publicToolCallIdPattern.test(toolCallId)) {\n return toolCallId;\n }\n\n const existing = toolCallIds.get(toolCallId);\n if (existing) {\n return existing;\n }\n\n const generated = createToolCallId();\n toolCallIds.set(toolCallId, generated);\n return generated;\n}\n\nfunction createToolCallId(): string {\n return `${toolCallIdPrefix}${crypto.randomUUID().replaceAll(\"-\", \"\")}`;\n}\n"],"mappings":"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"}
|
package/dist/llm.d.ts
CHANGED
|
@@ -1,32 +1,28 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { RuntimeToolExecutionCheckpoint, RuntimeToolExecutionCheckpointMetadata, RuntimeToolExecutionContext, RuntimeToolExecutionDecision, RuntimeToolRetryPolicy } from "./llm-tool-execution.js";
|
|
2
|
+
import { LanguageModel, ModelMessage, ToolChoice, ToolSet, generateText } from "ai";
|
|
2
3
|
|
|
3
4
|
//#region src/llm.d.ts
|
|
4
|
-
type
|
|
5
|
-
type
|
|
6
|
-
type
|
|
7
|
-
|
|
8
|
-
type LlmOutputPart = LlmOutput[number];
|
|
9
|
-
interface LlmContext {
|
|
5
|
+
type AgentToolChoice = ToolChoice<ToolSet>;
|
|
6
|
+
type RuntimeLlmOutput = Awaited<ReturnType<typeof generateText>>["responseMessages"];
|
|
7
|
+
type RuntimeLlmOutputPart = RuntimeLlmOutput[number];
|
|
8
|
+
interface RuntimeLlmContext {
|
|
10
9
|
history: readonly ModelMessage[];
|
|
11
10
|
signal: AbortSignal;
|
|
11
|
+
toolExecution?: RuntimeToolExecutionContext;
|
|
12
12
|
}
|
|
13
|
-
type
|
|
14
|
-
interface
|
|
13
|
+
type RuntimeLlm = (context: RuntimeLlmContext) => Promise<RuntimeLlmOutput>;
|
|
14
|
+
interface RuntimeCreateLlmOptions {
|
|
15
15
|
instructions?: string;
|
|
16
16
|
model: LanguageModel;
|
|
17
17
|
toolChoice?: AgentToolChoice;
|
|
18
18
|
tools?: ToolSet;
|
|
19
19
|
}
|
|
20
|
-
type RuntimeCreateLlmOptions = CreateLlmOptions;
|
|
21
|
-
type RuntimeLlm = Llm;
|
|
22
|
-
type RuntimeLlmContext = LlmContext;
|
|
23
|
-
type RuntimeLlmOutput = LlmOutput;
|
|
24
20
|
declare function createLlm({
|
|
25
21
|
model,
|
|
26
22
|
instructions,
|
|
27
23
|
toolChoice,
|
|
28
24
|
tools
|
|
29
|
-
}:
|
|
25
|
+
}: RuntimeCreateLlmOptions): RuntimeLlm;
|
|
30
26
|
//#endregion
|
|
31
|
-
export { AgentToolChoice,
|
|
27
|
+
export { AgentToolChoice, RuntimeCreateLlmOptions, RuntimeLlm, RuntimeLlmContext, RuntimeLlmOutput, RuntimeLlmOutputPart, createLlm };
|
|
32
28
|
//# sourceMappingURL=llm.d.ts.map
|
package/dist/llm.js
CHANGED
|
@@ -1,22 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { normalizeToolCallIds, rewriteMessageToolCallIds } from "./llm-tool-execution.js";
|
|
2
2
|
import { generateText } from "ai";
|
|
3
3
|
//#region src/llm.ts
|
|
4
4
|
function createLlm({ model, instructions, toolChoice, tools }) {
|
|
5
|
-
return async ({ history, signal }) => {
|
|
6
|
-
const
|
|
7
|
-
history,
|
|
8
|
-
signal,
|
|
9
|
-
tools
|
|
10
|
-
});
|
|
5
|
+
return async ({ history, signal, toolExecution }) => {
|
|
6
|
+
const toolCallIds = /* @__PURE__ */ new Map();
|
|
11
7
|
const { responseMessages } = await generateText({
|
|
12
8
|
abortSignal: signal,
|
|
13
9
|
instructions,
|
|
14
10
|
messages: [...history],
|
|
15
11
|
model,
|
|
16
12
|
toolChoice,
|
|
17
|
-
tools:
|
|
13
|
+
tools: normalizeToolCallIds(tools, toolCallIds, toolExecution)
|
|
18
14
|
});
|
|
19
|
-
return responseMessages;
|
|
15
|
+
return responseMessages.map((message) => rewriteMessageToolCallIds(message, toolCallIds));
|
|
20
16
|
};
|
|
21
17
|
}
|
|
22
18
|
//#endregion
|
package/dist/llm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"llm.js","names":[],"sources":["../src/llm.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"llm.js","names":[],"sources":["../src/llm.ts"],"sourcesContent":["import type { LanguageModel, ModelMessage, ToolChoice, ToolSet } from \"ai\";\nimport { generateText } from \"ai\";\nimport type { RuntimeToolExecutionContext } from \"./llm-tool-execution\";\nimport {\n normalizeToolCallIds,\n rewriteMessageToolCallIds,\n} from \"./llm-tool-execution\";\n\nexport type {\n RuntimePersistedToolExecutionCheckpoint,\n RuntimeToolExecutionCheckpoint,\n RuntimeToolExecutionCheckpointMetadata,\n RuntimeToolExecutionContext,\n RuntimeToolExecutionDecision,\n RuntimeToolRetryPolicy,\n} from \"./llm-tool-execution\";\n\nexport type AgentToolChoice = ToolChoice<ToolSet>;\nexport type RuntimeLlmOutput = Awaited<\n ReturnType<typeof generateText>\n>[\"responseMessages\"];\nexport type RuntimeLlmOutputPart = RuntimeLlmOutput[number];\n\nexport interface RuntimeLlmContext {\n history: readonly ModelMessage[];\n signal: AbortSignal;\n toolExecution?: RuntimeToolExecutionContext;\n}\n\nexport type RuntimeLlm = (\n context: RuntimeLlmContext\n) => Promise<RuntimeLlmOutput>;\n\nexport interface RuntimeCreateLlmOptions {\n instructions?: string;\n model: LanguageModel;\n toolChoice?: AgentToolChoice;\n tools?: ToolSet;\n}\n\nexport function createLlm({\n model,\n instructions,\n toolChoice,\n tools,\n}: RuntimeCreateLlmOptions): RuntimeLlm {\n return async ({ history, signal, toolExecution }) => {\n const toolCallIds = new Map<string, string>();\n const { responseMessages } = await generateText({\n abortSignal: signal,\n instructions,\n messages: [...history],\n model,\n toolChoice,\n tools: normalizeToolCallIds(tools, toolCallIds, toolExecution),\n });\n\n return responseMessages.map((message) =>\n rewriteMessageToolCallIds(message, toolCallIds)\n );\n };\n}\n"],"mappings":";;;AAwCA,SAAgB,UAAU,EACxB,OACA,cACA,YACA,SACsC;CACtC,OAAO,OAAO,EAAE,SAAS,QAAQ,oBAAoB;EACnD,MAAM,8BAAc,IAAI,IAAoB;EAC5C,MAAM,EAAE,qBAAqB,MAAM,aAAa;GAC9C,aAAa;GACb;GACA,UAAU,CAAC,GAAG,OAAO;GACrB;GACA;GACA,OAAO,qBAAqB,OAAO,aAAa,aAAa;EAC/D,CAAC;EAED,OAAO,iBAAiB,KAAK,YAC3B,0BAA0B,SAAS,WAAW,CAChD;CACF;AACF"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { RuntimeLlmContext } from "./llm.js";
|
|
2
|
+
import { AgentEvent } from "./session/events.js";
|
|
3
|
+
|
|
4
|
+
//#region src/plugins.d.ts
|
|
5
|
+
type MaybePromise<T> = PromiseLike<T> | T;
|
|
6
|
+
type AgentEventHistory = RuntimeLlmContext["history"];
|
|
7
|
+
interface AgentEventContext {
|
|
8
|
+
readonly event: AgentEvent;
|
|
9
|
+
readonly history: AgentEventHistory;
|
|
10
|
+
readonly signal?: AbortSignal;
|
|
11
|
+
}
|
|
12
|
+
interface AgentPlugin {
|
|
13
|
+
readonly events?: {
|
|
14
|
+
readonly on?: (context: AgentEventContext) => MaybePromise<void>;
|
|
15
|
+
};
|
|
16
|
+
readonly name?: string;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
export { AgentEventContext, AgentPlugin };
|
|
20
|
+
//# sourceMappingURL=plugins.d.ts.map
|
package/dist/plugins.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/plugins.ts
|
|
2
|
+
function runEventPlugins(plugins, context) {
|
|
3
|
+
return runPluginHandlers(plugins, (plugin) => plugin.events?.on, context);
|
|
4
|
+
}
|
|
5
|
+
async function runPluginHandlers(plugins, handlerFor, context) {
|
|
6
|
+
for (const plugin of plugins) {
|
|
7
|
+
const handler = handlerFor(plugin);
|
|
8
|
+
if (handler) await handler(context);
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { runEventPlugins };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=plugins.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugins.js","names":[],"sources":["../src/plugins.ts"],"sourcesContent":["import type { RuntimeLlmContext } from \"./llm\";\nimport type { AgentEvent } from \"./session/events\";\n\ntype MaybePromise<T> = PromiseLike<T> | T;\ntype AgentEventHistory = RuntimeLlmContext[\"history\"];\n\nexport interface AgentEventContext {\n readonly event: AgentEvent;\n readonly history: AgentEventHistory;\n readonly signal?: AbortSignal;\n}\n\nexport interface AgentPlugin {\n readonly events?: {\n readonly on?: (context: AgentEventContext) => MaybePromise<void>;\n };\n readonly name?: string;\n}\n\nexport function runEventPlugins(\n plugins: readonly AgentPlugin[],\n context: AgentEventContext\n): Promise<void> {\n return runPluginHandlers(plugins, (plugin) => plugin.events?.on, context);\n}\n\nasync function runPluginHandlers<Context>(\n plugins: readonly AgentPlugin[],\n handlerFor: (\n plugin: AgentPlugin\n ) => ((context: Context) => MaybePromise<void>) | undefined,\n context: Context\n): Promise<void> {\n for (const plugin of plugins) {\n const handler = handlerFor(plugin);\n if (handler) {\n await handler(context);\n }\n }\n}\n"],"mappings":";AAmBA,SAAgB,gBACd,SACA,SACe;CACf,OAAO,kBAAkB,UAAU,WAAW,OAAO,QAAQ,IAAI,OAAO;AAC1E;AAEA,eAAe,kBACb,SACA,YAGA,SACe;CACf,KAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,UAAU,WAAW,MAAM;EACjC,IAAI,SACF,MAAM,QAAQ,OAAO;CAEzB;AACF"}
|
package/dist/session/events.d.ts
CHANGED
|
@@ -10,23 +10,6 @@ interface RuntimeInput {
|
|
|
10
10
|
placement: "turn-start" | "step-start" | "step-end";
|
|
11
11
|
type: "runtime-input";
|
|
12
12
|
}
|
|
13
|
-
type OverlayPlacement = "idle" | "step-end" | "step-start" | "turn-start";
|
|
14
|
-
interface OverlayInputSummary {
|
|
15
|
-
partCount?: number;
|
|
16
|
-
preview: string;
|
|
17
|
-
textLength?: number;
|
|
18
|
-
type: UserInput["type"];
|
|
19
|
-
}
|
|
20
|
-
interface OverlayAccepted {
|
|
21
|
-
input: OverlayInputSummary;
|
|
22
|
-
placement: OverlayPlacement;
|
|
23
|
-
type: "overlay-accepted";
|
|
24
|
-
}
|
|
25
|
-
interface OverlayExpired {
|
|
26
|
-
count: number;
|
|
27
|
-
reason: "kill" | "turn-abort" | "turn-end" | "turn-error";
|
|
28
|
-
type: "overlay-expired";
|
|
29
|
-
}
|
|
30
13
|
interface AssistantText {
|
|
31
14
|
text: string;
|
|
32
15
|
type: "assistant-text";
|
|
@@ -47,7 +30,8 @@ interface ToolResult {
|
|
|
47
30
|
toolName: string;
|
|
48
31
|
type: "tool-result";
|
|
49
32
|
}
|
|
50
|
-
type
|
|
33
|
+
type SubagentJobStatus = "aborted" | "cancelled" | "completed" | "error" | "pending" | "running";
|
|
34
|
+
type AgentEvent = /** User input was accepted into the session queue. */UserText /** User multipart input was accepted into the session queue. */ | UserMessage /** Runtime/API-originated input inserted into the current turn, not human input. */ | RuntimeInput /** A queued user input started running as a turn. */ | {
|
|
51
35
|
type: "turn-start";
|
|
52
36
|
} /** The active turn was interrupted before normal completion. */ | {
|
|
53
37
|
type: "turn-abort";
|
|
@@ -58,10 +42,32 @@ type AgentEvent = /** User input was accepted into the session queue. */UserText
|
|
|
58
42
|
type: "turn-end";
|
|
59
43
|
} /** One model/tool-loop iteration started within the active turn. */ | {
|
|
60
44
|
type: "step-start";
|
|
61
|
-
} /** The model produced reasoning content. */ | AssistantReasoning /** The model produced visible assistant text. */ | AssistantText /** The model requested a tool call. */ | ToolCall /** A tool call returned a result. */ | ToolResult
|
|
45
|
+
} /** The model produced reasoning content. */ | AssistantReasoning /** The model produced visible assistant text. */ | AssistantText /** The model requested a tool call. */ | ToolCall /** A tool call returned a result. */ | ToolResult | {
|
|
46
|
+
description?: string;
|
|
47
|
+
delegateToolCallId?: string;
|
|
48
|
+
run_in_background: boolean;
|
|
49
|
+
subagent: string;
|
|
50
|
+
task_id?: string;
|
|
51
|
+
type: "subagent-job-start";
|
|
52
|
+
} | {
|
|
53
|
+
eventType?: AgentEvent["type"];
|
|
54
|
+
delegateToolCallId?: string;
|
|
55
|
+
status: SubagentJobStatus;
|
|
56
|
+
subagent: string;
|
|
57
|
+
task_id: string;
|
|
58
|
+
type: "subagent-job-update";
|
|
59
|
+
} | {
|
|
60
|
+
error?: string;
|
|
61
|
+
eventCount: number;
|
|
62
|
+
delegateToolCallId?: string;
|
|
63
|
+
status: Exclude<SubagentJobStatus, "pending" | "running">;
|
|
64
|
+
subagent: string;
|
|
65
|
+
task_id?: string;
|
|
66
|
+
type: "subagent-job-end";
|
|
67
|
+
} /** One model/tool-loop iteration finished within the active turn. */ | {
|
|
62
68
|
type: "step-end";
|
|
63
69
|
};
|
|
64
70
|
type AgentEventListener = (event: AgentEvent) => void;
|
|
65
71
|
//#endregion
|
|
66
|
-
export { AgentEvent, AgentEventListener, AssistantReasoning, AssistantText,
|
|
72
|
+
export { AgentEvent, AgentEventListener, AssistantReasoning, AssistantText, RuntimeInput, ToolCall, ToolResult };
|
|
67
73
|
//# sourceMappingURL=events.d.ts.map
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
//#region src/session/input-normalization.ts
|
|
2
|
+
function normalizeAgentInput(input) {
|
|
3
|
+
if (typeof input === "string") return {
|
|
4
|
+
type: "user-text",
|
|
5
|
+
text: input
|
|
6
|
+
};
|
|
7
|
+
if (isStringArrayInput(input)) return {
|
|
8
|
+
type: "user-text",
|
|
9
|
+
text: structuredClone(input)
|
|
10
|
+
};
|
|
11
|
+
if (isArrayInput(input)) {
|
|
12
|
+
assertUserMessageContent(input);
|
|
13
|
+
return {
|
|
14
|
+
type: "user-message",
|
|
15
|
+
content: structuredClone(input)
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
if (isUserMessage(input)) {
|
|
19
|
+
assertUserMessageContent(input.content);
|
|
20
|
+
return structuredClone(input);
|
|
21
|
+
}
|
|
22
|
+
if (isUserText(input)) return structuredClone(input);
|
|
23
|
+
throw new TypeError("Agent input must be text, text parts, content parts, user-text, or user-message.");
|
|
24
|
+
}
|
|
25
|
+
function isStringArrayInput(input) {
|
|
26
|
+
return Array.isArray(input) && hasDenseItems(input, isString);
|
|
27
|
+
}
|
|
28
|
+
function isArrayInput(input) {
|
|
29
|
+
return Array.isArray(input);
|
|
30
|
+
}
|
|
31
|
+
function isUserMessage(input) {
|
|
32
|
+
return input !== null && typeof input === "object" && !isArrayInput(input) && input.type === "user-message" && "content" in input && Array.isArray(input.content);
|
|
33
|
+
}
|
|
34
|
+
function isUserText(input) {
|
|
35
|
+
return input !== null && typeof input === "object" && !isArrayInput(input) && input.type === "user-text" && (typeof input.text === "string" || isStringArrayInput(input.text));
|
|
36
|
+
}
|
|
37
|
+
function assertUserMessageContent(input) {
|
|
38
|
+
for (const part of input) if (!isUserMessageContentPart(part)) throw new TypeError("Agent input content parts must be { type: \"text\", text }, { type: \"image\", image }, or { type: \"file\", data, mediaType }.");
|
|
39
|
+
}
|
|
40
|
+
function isUserMessageContentPart(part) {
|
|
41
|
+
if (part === null || typeof part !== "object" || !("type" in part)) return false;
|
|
42
|
+
if (part.type === "text") return "text" in part && typeof part.text === "string";
|
|
43
|
+
if (part.type === "image") return "image" in part && typeof part.image === "string" && (!("mediaType" in part) || typeof part.mediaType === "string");
|
|
44
|
+
if (part.type === "file") return "data" in part && isUserMessageFileData(part.data) && "mediaType" in part && typeof part.mediaType === "string" && (!("filename" in part) || typeof part.filename === "string");
|
|
45
|
+
return false;
|
|
46
|
+
}
|
|
47
|
+
function isUserMessageFileData(data) {
|
|
48
|
+
if (typeof data === "string") return true;
|
|
49
|
+
if (data === null || typeof data !== "object" || !("type" in data)) return false;
|
|
50
|
+
if (data.type === "data") return "data" in data && typeof data.data === "string";
|
|
51
|
+
if (data.type === "reference") return "reference" in data && data.reference !== null && typeof data.reference === "object" && Object.values(data.reference).every((value) => typeof value === "string");
|
|
52
|
+
if (data.type === "text") return "text" in data && typeof data.text === "string";
|
|
53
|
+
if (data.type === "url") return "url" in data && typeof data.url === "string";
|
|
54
|
+
return false;
|
|
55
|
+
}
|
|
56
|
+
function hasDenseItems(input, predicate) {
|
|
57
|
+
for (let index = 0; index < input.length; index += 1) if (!(index in input && predicate(input[index]))) return false;
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
function isString(value) {
|
|
61
|
+
return typeof value === "string";
|
|
62
|
+
}
|
|
63
|
+
//#endregion
|
|
64
|
+
export { normalizeAgentInput };
|
|
65
|
+
|
|
66
|
+
//# sourceMappingURL=input-normalization.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"input-normalization.js","names":[],"sources":["../../src/session/input-normalization.ts"],"sourcesContent":["import type {\n AgentInput,\n UserInput,\n UserMessage,\n UserMessageContentPart,\n UserText,\n} from \"./input\";\n\nexport function normalizeAgentInput(input: AgentInput): UserInput {\n if (typeof input === \"string\") {\n return {\n type: \"user-text\",\n text: input,\n };\n }\n\n if (isStringArrayInput(input)) {\n return {\n type: \"user-text\",\n text: structuredClone(input),\n };\n }\n\n if (isArrayInput(input)) {\n assertUserMessageContent(input);\n return {\n type: \"user-message\",\n content: structuredClone(input),\n };\n }\n\n if (isUserMessage(input)) {\n assertUserMessageContent(input.content);\n return structuredClone(input);\n }\n\n if (isUserText(input)) {\n return structuredClone(input);\n }\n\n throw new TypeError(\n \"Agent input must be text, text parts, content parts, user-text, or user-message.\"\n );\n}\n\nfunction isStringArrayInput(input: unknown): input is readonly string[] {\n return Array.isArray(input) && hasDenseItems(input, isString);\n}\n\nfunction isArrayInput(\n input: AgentInput\n): input is readonly string[] | readonly UserMessageContentPart[] {\n return Array.isArray(input);\n}\n\nfunction isUserMessage(input: AgentInput): input is UserMessage {\n return (\n input !== null &&\n typeof input === \"object\" &&\n !isArrayInput(input) &&\n input.type === \"user-message\" &&\n \"content\" in input &&\n Array.isArray(input.content)\n );\n}\n\nfunction isUserText(input: AgentInput): input is UserText {\n return (\n input !== null &&\n typeof input === \"object\" &&\n !isArrayInput(input) &&\n input.type === \"user-text\" &&\n (typeof input.text === \"string\" || isStringArrayInput(input.text))\n );\n}\n\nfunction assertUserMessageContent(\n input: readonly unknown[]\n): asserts input is readonly UserMessageContentPart[] {\n for (const part of input) {\n if (!isUserMessageContentPart(part)) {\n throw new TypeError(\n 'Agent input content parts must be { type: \"text\", text }, { type: \"image\", image }, or { type: \"file\", data, mediaType }.'\n );\n }\n }\n}\n\nfunction isUserMessageContentPart(\n part: unknown\n): part is UserMessageContentPart {\n if (part === null || typeof part !== \"object\" || !(\"type\" in part)) {\n return false;\n }\n\n if (part.type === \"text\") {\n return \"text\" in part && typeof part.text === \"string\";\n }\n\n if (part.type === \"image\") {\n return (\n \"image\" in part &&\n typeof part.image === \"string\" &&\n (!(\"mediaType\" in part) || typeof part.mediaType === \"string\")\n );\n }\n\n if (part.type === \"file\") {\n return (\n \"data\" in part &&\n isUserMessageFileData(part.data) &&\n \"mediaType\" in part &&\n typeof part.mediaType === \"string\" &&\n (!(\"filename\" in part) || typeof part.filename === \"string\")\n );\n }\n\n return false;\n}\n\nfunction isUserMessageFileData(data: unknown): boolean {\n if (typeof data === \"string\") {\n return true;\n }\n\n if (data === null || typeof data !== \"object\" || !(\"type\" in data)) {\n return false;\n }\n\n if (data.type === \"data\") {\n return \"data\" in data && typeof data.data === \"string\";\n }\n\n if (data.type === \"reference\") {\n return (\n \"reference\" in data &&\n data.reference !== null &&\n typeof data.reference === \"object\" &&\n Object.values(data.reference).every((value) => typeof value === \"string\")\n );\n }\n\n if (data.type === \"text\") {\n return \"text\" in data && typeof data.text === \"string\";\n }\n\n if (data.type === \"url\") {\n return \"url\" in data && typeof data.url === \"string\";\n }\n\n return false;\n}\n\nfunction hasDenseItems<T>(\n input: readonly unknown[],\n predicate: (value: unknown) => value is T\n): input is readonly T[] {\n for (let index = 0; index < input.length; index += 1) {\n if (!(index in input && predicate(input[index]))) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction isString(value: unknown): value is string {\n return typeof value === \"string\";\n}\n"],"mappings":";AAQA,SAAgB,oBAAoB,OAA8B;CAChE,IAAI,OAAO,UAAU,UACnB,OAAO;EACL,MAAM;EACN,MAAM;CACR;CAGF,IAAI,mBAAmB,KAAK,GAC1B,OAAO;EACL,MAAM;EACN,MAAM,gBAAgB,KAAK;CAC7B;CAGF,IAAI,aAAa,KAAK,GAAG;EACvB,yBAAyB,KAAK;EAC9B,OAAO;GACL,MAAM;GACN,SAAS,gBAAgB,KAAK;EAChC;CACF;CAEA,IAAI,cAAc,KAAK,GAAG;EACxB,yBAAyB,MAAM,OAAO;EACtC,OAAO,gBAAgB,KAAK;CAC9B;CAEA,IAAI,WAAW,KAAK,GAClB,OAAO,gBAAgB,KAAK;CAG9B,MAAM,IAAI,UACR,kFACF;AACF;AAEA,SAAS,mBAAmB,OAA4C;CACtE,OAAO,MAAM,QAAQ,KAAK,KAAK,cAAc,OAAO,QAAQ;AAC9D;AAEA,SAAS,aACP,OACgE;CAChE,OAAO,MAAM,QAAQ,KAAK;AAC5B;AAEA,SAAS,cAAc,OAAyC;CAC9D,OACE,UAAU,QACV,OAAO,UAAU,YACjB,CAAC,aAAa,KAAK,KACnB,MAAM,SAAS,kBACf,aAAa,SACb,MAAM,QAAQ,MAAM,OAAO;AAE/B;AAEA,SAAS,WAAW,OAAsC;CACxD,OACE,UAAU,QACV,OAAO,UAAU,YACjB,CAAC,aAAa,KAAK,KACnB,MAAM,SAAS,gBACd,OAAO,MAAM,SAAS,YAAY,mBAAmB,MAAM,IAAI;AAEpE;AAEA,SAAS,yBACP,OACoD;CACpD,KAAK,MAAM,QAAQ,OACjB,IAAI,CAAC,yBAAyB,IAAI,GAChC,MAAM,IAAI,UACR,iIACF;AAGN;AAEA,SAAS,yBACP,MACgC;CAChC,IAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,EAAE,UAAU,OAC3D,OAAO;CAGT,IAAI,KAAK,SAAS,QAChB,OAAO,UAAU,QAAQ,OAAO,KAAK,SAAS;CAGhD,IAAI,KAAK,SAAS,SAChB,OACE,WAAW,QACX,OAAO,KAAK,UAAU,aACrB,EAAE,eAAe,SAAS,OAAO,KAAK,cAAc;CAIzD,IAAI,KAAK,SAAS,QAChB,OACE,UAAU,QACV,sBAAsB,KAAK,IAAI,KAC/B,eAAe,QACf,OAAO,KAAK,cAAc,aACzB,EAAE,cAAc,SAAS,OAAO,KAAK,aAAa;CAIvD,OAAO;AACT;AAEA,SAAS,sBAAsB,MAAwB;CACrD,IAAI,OAAO,SAAS,UAClB,OAAO;CAGT,IAAI,SAAS,QAAQ,OAAO,SAAS,YAAY,EAAE,UAAU,OAC3D,OAAO;CAGT,IAAI,KAAK,SAAS,QAChB,OAAO,UAAU,QAAQ,OAAO,KAAK,SAAS;CAGhD,IAAI,KAAK,SAAS,aAChB,OACE,eAAe,QACf,KAAK,cAAc,QACnB,OAAO,KAAK,cAAc,YAC1B,OAAO,OAAO,KAAK,SAAS,EAAE,OAAO,UAAU,OAAO,UAAU,QAAQ;CAI5E,IAAI,KAAK,SAAS,QAChB,OAAO,UAAU,QAAQ,OAAO,KAAK,SAAS;CAGhD,IAAI,KAAK,SAAS,OAChB,OAAO,SAAS,QAAQ,OAAO,KAAK,QAAQ;CAG9C,OAAO;AACT;AAEA,SAAS,cACP,OACA,WACuB;CACvB,KAAK,IAAI,QAAQ,GAAG,QAAQ,MAAM,QAAQ,SAAS,GACjD,IAAI,EAAE,SAAS,SAAS,UAAU,MAAM,MAAM,IAC5C,OAAO;CAIX,OAAO;AACT;AAEA,SAAS,SAAS,OAAiC;CACjD,OAAO,OAAO,UAAU;AAC1B"}
|
package/dist/session/input.d.ts
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { UserModelMessage } from "ai";
|
|
2
|
-
|
|
3
1
|
//#region src/session/input.d.ts
|
|
4
2
|
type UserTextContent = string | readonly string[];
|
|
5
3
|
interface UserText {
|
|
@@ -36,10 +34,8 @@ interface UserMessageFilePart {
|
|
|
36
34
|
}
|
|
37
35
|
type UserMessageContentPart = UserMessageFilePart | UserMessageImagePart | UserMessageTextPart;
|
|
38
36
|
type UserMessageContent = readonly UserMessageContentPart[];
|
|
39
|
-
type UserMessageMetadata = UserModelMessage["providerOptions"];
|
|
40
37
|
interface UserMessage {
|
|
41
38
|
content: UserMessageContent;
|
|
42
|
-
metadata?: UserMessageMetadata;
|
|
43
39
|
type: "user-message";
|
|
44
40
|
}
|
|
45
41
|
type UserInput = UserMessage | UserText;
|
package/dist/session/mapping.js
CHANGED
|
@@ -19,8 +19,7 @@ function userTextContentToUserContent(text) {
|
|
|
19
19
|
function userMessageToModelMessage(input) {
|
|
20
20
|
return {
|
|
21
21
|
role: "user",
|
|
22
|
-
content: userMessageContentToUserContent(input.content)
|
|
23
|
-
...input.metadata === void 0 ? {} : { providerOptions: structuredClone(input.metadata) }
|
|
22
|
+
content: userMessageContentToUserContent(input.content)
|
|
24
23
|
};
|
|
25
24
|
}
|
|
26
25
|
function userMessageContentToUserContent(content) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"mapping.js","names":[],"sources":["../../src/session/mapping.ts"],"sourcesContent":["import type {\n AssistantContent,\n AssistantModelMessage,\n ModelMessage,\n ToolModelMessage,\n UserModelMessage,\n} from \"ai\";\nimport type {\n AssistantReasoning,\n AssistantText,\n ToolCall,\n ToolResult,\n UserMessage,\n UserMessageContent,\n UserMessageContentPart,\n UserMessageFileData,\n UserText,\n UserTextContent,\n} from \"./events\";\nimport type { UserInput } from \"./input\";\n\ntype AssistantContentPart = Exclude<AssistantContent, string>[number];\ntype ToolContentPart = ToolModelMessage[\"content\"][number];\ntype ModelEvent = AssistantReasoning | AssistantText | ToolCall | ToolResult;\n\n// UserInput -> AI SDK UserModelMessage\nexport function userInputToModelMessage(input: UserInput): UserModelMessage {\n if (input.type === \"user-message\") {\n return userMessageToModelMessage(input);\n }\n\n return userTextToModelMessage(input);\n}\n\nexport function userTextToModelMessage(input: UserText): UserModelMessage {\n return { role: \"user\", content: userTextContentToUserContent(input.text) };\n}\n\nfunction userTextContentToUserContent(\n text: UserTextContent\n): UserModelMessage[\"content\"] {\n if (typeof text === \"string\") {\n return text;\n }\n\n return text.map((part) => ({ type: \"text\", text: part }));\n}\n\nexport function userMessageToModelMessage(\n input: UserMessage\n): UserModelMessage {\n return {\n role: \"user\",\n content: userMessageContentToUserContent(input.content),\n
|
|
1
|
+
{"version":3,"file":"mapping.js","names":[],"sources":["../../src/session/mapping.ts"],"sourcesContent":["import type {\n AssistantContent,\n AssistantModelMessage,\n ModelMessage,\n ToolModelMessage,\n UserModelMessage,\n} from \"ai\";\nimport type {\n AssistantReasoning,\n AssistantText,\n ToolCall,\n ToolResult,\n UserMessage,\n UserMessageContent,\n UserMessageContentPart,\n UserMessageFileData,\n UserText,\n UserTextContent,\n} from \"./events\";\nimport type { UserInput } from \"./input\";\n\ntype AssistantContentPart = Exclude<AssistantContent, string>[number];\ntype ToolContentPart = ToolModelMessage[\"content\"][number];\ntype ModelEvent = AssistantReasoning | AssistantText | ToolCall | ToolResult;\n\n// UserInput -> AI SDK UserModelMessage\nexport function userInputToModelMessage(input: UserInput): UserModelMessage {\n if (input.type === \"user-message\") {\n return userMessageToModelMessage(input);\n }\n\n return userTextToModelMessage(input);\n}\n\nexport function userTextToModelMessage(input: UserText): UserModelMessage {\n return { role: \"user\", content: userTextContentToUserContent(input.text) };\n}\n\nfunction userTextContentToUserContent(\n text: UserTextContent\n): UserModelMessage[\"content\"] {\n if (typeof text === \"string\") {\n return text;\n }\n\n return text.map((part) => ({ type: \"text\", text: part }));\n}\n\nexport function userMessageToModelMessage(\n input: UserMessage\n): UserModelMessage {\n return {\n role: \"user\",\n content: userMessageContentToUserContent(input.content),\n };\n}\n\nfunction userMessageContentToUserContent(\n content: UserMessageContent\n): Exclude<UserModelMessage[\"content\"], string> {\n return content.map(userMessageContentPartToUserContentPart);\n}\n\nfunction userMessageContentPartToUserContentPart(\n part: UserMessageContentPart\n): Exclude<UserModelMessage[\"content\"], string>[number] {\n if (part.type === \"text\") {\n return { type: \"text\", text: part.text };\n }\n\n if (part.type === \"image\") {\n return {\n type: \"file\",\n data: part.image,\n mediaType: part.mediaType ?? \"image\",\n };\n }\n\n return {\n type: \"file\",\n data: userMessageFileDataToFileData(part.data),\n mediaType: part.mediaType,\n ...(part.filename === undefined ? {} : { filename: part.filename }),\n };\n}\n\nfunction userMessageFileDataToFileData(\n data: UserMessageFileData\n): Extract<\n Exclude<UserModelMessage[\"content\"], string>[number],\n { type: \"file\" }\n>[\"data\"] {\n if (typeof data === \"string\") {\n return data;\n }\n\n if (data.type === \"url\") {\n return data.url;\n }\n\n if (data.type === \"data\") {\n return { type: \"data\", data: data.data };\n }\n\n if (data.type === \"reference\") {\n return { type: \"reference\", reference: { ...data.reference } };\n }\n\n return { type: \"text\", text: data.text };\n}\n\n// AI SDK ModelMessage -> public agent events\nexport function modelMessageToAgentEvents(message: ModelMessage): ModelEvent[] {\n if (message.role === \"assistant\") {\n return assistantReasoningFirstParts(assistantContentParts(message)).flatMap(\n assistantContentPartToEvents\n );\n }\n\n if (message.role === \"tool\") {\n return message.content.flatMap(toolContentPartToEvents);\n }\n\n return [];\n}\n\nfunction assistantContentParts(\n message: AssistantModelMessage\n): AssistantContentPart[] {\n return typeof message.content === \"string\"\n ? [{ type: \"text\", text: message.content }]\n : message.content;\n}\n\nfunction assistantReasoningFirstParts(\n parts: AssistantContentPart[]\n): AssistantContentPart[] {\n return [\n ...parts.filter((part) => part.type === \"reasoning\"),\n ...parts.filter((part) => part.type !== \"reasoning\"),\n ];\n}\n\nfunction assistantContentPartToEvents(\n part: AssistantContentPart\n): ModelEvent[] {\n if (part.type === \"text\") {\n return part.text ? [{ type: \"assistant-text\", text: part.text }] : [];\n }\n\n if (part.type === \"reasoning\") {\n return part.text ? [{ type: \"assistant-reasoning\", text: part.text }] : [];\n }\n\n if (part.type === \"tool-call\") {\n return [\n {\n type: \"tool-call\",\n input: part.input,\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n },\n ];\n }\n\n return [];\n}\n\nfunction toolContentPartToEvents(part: ToolContentPart): ModelEvent[] {\n if (part.type === \"tool-result\") {\n return toolResultPartToEvents(part);\n }\n\n return [];\n}\n\nfunction toolResultPartToEvents(part: {\n output: unknown;\n toolCallId: string;\n toolName: string;\n type: \"tool-result\";\n}): ModelEvent[] {\n return [\n {\n type: \"tool-result\",\n output: part.output,\n toolCallId: part.toolCallId,\n toolName: part.toolName,\n },\n ];\n}\n"],"mappings":";AA0BA,SAAgB,wBAAwB,OAAoC;CAC1E,IAAI,MAAM,SAAS,gBACjB,OAAO,0BAA0B,KAAK;CAGxC,OAAO,uBAAuB,KAAK;AACrC;AAEA,SAAgB,uBAAuB,OAAmC;CACxE,OAAO;EAAE,MAAM;EAAQ,SAAS,6BAA6B,MAAM,IAAI;CAAE;AAC3E;AAEA,SAAS,6BACP,MAC6B;CAC7B,IAAI,OAAO,SAAS,UAClB,OAAO;CAGT,OAAO,KAAK,KAAK,UAAU;EAAE,MAAM;EAAQ,MAAM;CAAK,EAAE;AAC1D;AAEA,SAAgB,0BACd,OACkB;CAClB,OAAO;EACL,MAAM;EACN,SAAS,gCAAgC,MAAM,OAAO;CACxD;AACF;AAEA,SAAS,gCACP,SAC8C;CAC9C,OAAO,QAAQ,IAAI,uCAAuC;AAC5D;AAEA,SAAS,wCACP,MACsD;CACtD,IAAI,KAAK,SAAS,QAChB,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;CAGzC,IAAI,KAAK,SAAS,SAChB,OAAO;EACL,MAAM;EACN,MAAM,KAAK;EACX,WAAW,KAAK,aAAa;CAC/B;CAGF,OAAO;EACL,MAAM;EACN,MAAM,8BAA8B,KAAK,IAAI;EAC7C,WAAW,KAAK;EAChB,GAAI,KAAK,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS;CACnE;AACF;AAEA,SAAS,8BACP,MAIQ;CACR,IAAI,OAAO,SAAS,UAClB,OAAO;CAGT,IAAI,KAAK,SAAS,OAChB,OAAO,KAAK;CAGd,IAAI,KAAK,SAAS,QAChB,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;CAGzC,IAAI,KAAK,SAAS,aAChB,OAAO;EAAE,MAAM;EAAa,WAAW,EAAE,GAAG,KAAK,UAAU;CAAE;CAG/D,OAAO;EAAE,MAAM;EAAQ,MAAM,KAAK;CAAK;AACzC;AAGA,SAAgB,0BAA0B,SAAqC;CAC7E,IAAI,QAAQ,SAAS,aACnB,OAAO,6BAA6B,sBAAsB,OAAO,CAAC,EAAE,QAClE,4BACF;CAGF,IAAI,QAAQ,SAAS,QACnB,OAAO,QAAQ,QAAQ,QAAQ,uBAAuB;CAGxD,OAAO,CAAC;AACV;AAEA,SAAS,sBACP,SACwB;CACxB,OAAO,OAAO,QAAQ,YAAY,WAC9B,CAAC;EAAE,MAAM;EAAQ,MAAM,QAAQ;CAAQ,CAAC,IACxC,QAAQ;AACd;AAEA,SAAS,6BACP,OACwB;CACxB,OAAO,CACL,GAAG,MAAM,QAAQ,SAAS,KAAK,SAAS,WAAW,GACnD,GAAG,MAAM,QAAQ,SAAS,KAAK,SAAS,WAAW,CACrD;AACF;AAEA,SAAS,6BACP,MACc;CACd,IAAI,KAAK,SAAS,QAChB,OAAO,KAAK,OAAO,CAAC;EAAE,MAAM;EAAkB,MAAM,KAAK;CAAK,CAAC,IAAI,CAAC;CAGtE,IAAI,KAAK,SAAS,aAChB,OAAO,KAAK,OAAO,CAAC;EAAE,MAAM;EAAuB,MAAM,KAAK;CAAK,CAAC,IAAI,CAAC;CAG3E,IAAI,KAAK,SAAS,aAChB,OAAO,CACL;EACE,MAAM;EACN,OAAO,KAAK;EACZ,YAAY,KAAK;EACjB,UAAU,KAAK;CACjB,CACF;CAGF,OAAO,CAAC;AACV;AAEA,SAAS,wBAAwB,MAAqC;CACpE,IAAI,KAAK,SAAS,eAChB,OAAO,uBAAuB,IAAI;CAGpC,OAAO,CAAC;AACV;AAEA,SAAS,uBAAuB,MAKf;CACf,OAAO,CACL;EACE,MAAM;EACN,QAAQ,KAAK;EACb,YAAY,KAAK;EACjB,UAAU,KAAK;CACjB,CACF;AACF"}
|
package/dist/session/run.js
CHANGED
package/dist/session/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","names":["#events","#closed","#enqueue","#error","#settlePendingAck","#waiter","#eventsStarted","#next","#cancel","#
|
|
1
|
+
{"version":3,"file":"run.js","names":["#events","#closed","#enqueue","#error","#settlePendingAck","#settleQueuedAcks","#waiter","#eventsStarted","#next","#cancel","#deliver","#resultPending","#pendingAck"],"sources":["../../src/session/run.ts"],"sourcesContent":["import type { AgentEvent } from \"./events\";\n\nexport interface AgentRun {\n events(): AsyncIterable<AgentEvent>;\n}\n\ninterface QueuedEvent {\n readonly ack?: () => void;\n readonly event: AgentEvent;\n}\n\ninterface NextWaiter {\n readonly reject: (error: unknown) => void;\n readonly resolve: (value: IteratorResult<AgentEvent>) => void;\n}\n\nexport class BufferedAgentRun implements AgentRun {\n readonly #events: QueuedEvent[] = [];\n #closed = false;\n #error: unknown;\n #pendingAck: (() => void) | undefined;\n #resultPending = false;\n #eventsStarted = false;\n #waiter: NextWaiter | undefined;\n\n emit(event: AgentEvent): void {\n if (this.#closed) {\n return;\n }\n\n this.#enqueue({ event: structuredClone(event) });\n }\n\n emitBoundary(event: AgentEvent): Promise<void> {\n if (this.#closed) {\n return Promise.resolve();\n }\n\n return new Promise((resolve) => {\n this.#enqueue({ ack: resolve, event: structuredClone(event) });\n });\n }\n\n close(error?: unknown, _reason = \"the run is closed\"): void {\n if (this.#closed) {\n return;\n }\n\n this.#closed = true;\n this.#error = error;\n this.#settlePendingAck();\n this.#settleQueuedAcks();\n\n if (!this.#waiter) {\n return;\n }\n\n const waiter = this.#waiter;\n this.#waiter = undefined;\n if (error) {\n waiter.reject(error);\n return;\n }\n waiter.resolve({ done: true, value: undefined });\n }\n\n events(): AsyncIterable<AgentEvent> {\n if (this.#eventsStarted) {\n throw new Error(\"AgentRun.events() can only be consumed once\");\n }\n this.#eventsStarted = true;\n\n const iterator: AsyncIterableIterator<AgentEvent> = {\n next: () => this.#next(),\n return: () => {\n this.#cancel();\n return Promise.resolve({ done: true, value: undefined });\n },\n [Symbol.asyncIterator]: () => iterator,\n };\n return iterator;\n }\n\n #cancel(): void {\n this.#settleQueuedAcks();\n this.#events.length = 0;\n this.close(undefined, \"events return\");\n }\n\n #enqueue(event: QueuedEvent): void {\n const waiter = this.#waiter;\n if (waiter) {\n this.#waiter = undefined;\n this.#deliver(waiter.resolve, event);\n return;\n }\n\n this.#events.push(event);\n }\n\n #next(): Promise<IteratorResult<AgentEvent>> {\n if (this.#resultPending || this.#waiter) {\n return Promise.reject(\n new Error(\"AgentRun.events() does not allow concurrent next() calls\")\n );\n }\n\n this.#settlePendingAck();\n\n const event = this.#events.shift();\n if (event) {\n return new Promise((resolve) => this.#deliver(resolve, event));\n }\n\n if (this.#closed) {\n if (this.#error) {\n return Promise.reject(this.#error);\n }\n return Promise.resolve({ done: true, value: undefined });\n }\n\n return new Promise((resolve, reject) => {\n this.#waiter = { reject, resolve };\n });\n }\n\n #deliver(\n resolve: (value: IteratorResult<AgentEvent>) => void,\n { ack, event }: QueuedEvent\n ): void {\n this.#resultPending = true;\n queueMicrotask(() => {\n this.#resultPending = false;\n });\n this.#pendingAck = ack;\n resolve({ done: false, value: event });\n }\n\n #settlePendingAck(): void {\n const ack = this.#pendingAck;\n this.#pendingAck = undefined;\n ack?.();\n }\n\n #settleQueuedAcks(): void {\n for (const event of this.#events) {\n event.ack?.();\n }\n }\n}\n"],"mappings":";AAgBA,IAAa,mBAAb,MAAkD;CAChD,UAAkC,CAAC;CACnC,UAAU;CACV;CACA;CACA,iBAAiB;CACjB,iBAAiB;CACjB;CAEA,KAAK,OAAyB;EAC5B,IAAI,KAAKC,SACP;EAGF,KAAKC,SAAS,EAAE,OAAO,gBAAgB,KAAK,EAAE,CAAC;CACjD;CAEA,aAAa,OAAkC;EAC7C,IAAI,KAAKD,SACP,OAAO,QAAQ,QAAQ;EAGzB,OAAO,IAAI,SAAS,YAAY;GAC9B,KAAKC,SAAS;IAAE,KAAK;IAAS,OAAO,gBAAgB,KAAK;GAAE,CAAC;EAC/D,CAAC;CACH;CAEA,MAAM,OAAiB,UAAU,qBAA2B;EAC1D,IAAI,KAAKD,SACP;EAGF,KAAKA,UAAU;EACf,KAAKE,SAAS;EACd,KAAKC,kBAAkB;EACvB,KAAKC,kBAAkB;EAEvB,IAAI,CAAC,KAAKC,SACR;EAGF,MAAM,SAAS,KAAKA;EACpB,KAAKA,UAAU,KAAA;EACf,IAAI,OAAO;GACT,OAAO,OAAO,KAAK;GACnB;EACF;EACA,OAAO,QAAQ;GAAE,MAAM;GAAM,OAAO,KAAA;EAAU,CAAC;CACjD;CAEA,SAAoC;EAClC,IAAI,KAAKC,gBACP,MAAM,IAAI,MAAM,6CAA6C;EAE/D,KAAKA,iBAAiB;EAEtB,MAAM,WAA8C;GAClD,YAAY,KAAKC,MAAM;GACvB,cAAc;IACZ,KAAKC,QAAQ;IACb,OAAO,QAAQ,QAAQ;KAAE,MAAM;KAAM,OAAO,KAAA;IAAU,CAAC;GACzD;IACC,OAAO,sBAAsB;EAChC;EACA,OAAO;CACT;CAEA,UAAgB;EACd,KAAKJ,kBAAkB;EACvB,KAAKL,QAAQ,SAAS;EACtB,KAAK,MAAM,KAAA,GAAW,eAAe;CACvC;CAEA,SAAS,OAA0B;EACjC,MAAM,SAAS,KAAKM;EACpB,IAAI,QAAQ;GACV,KAAKA,UAAU,KAAA;GACf,KAAKI,SAAS,OAAO,SAAS,KAAK;GACnC;EACF;EAEA,KAAKV,QAAQ,KAAK,KAAK;CACzB;CAEA,QAA6C;EAC3C,IAAI,KAAKW,kBAAkB,KAAKL,SAC9B,OAAO,QAAQ,uBACb,IAAI,MAAM,0DAA0D,CACtE;EAGF,KAAKF,kBAAkB;EAEvB,MAAM,QAAQ,KAAKJ,QAAQ,MAAM;EACjC,IAAI,OACF,OAAO,IAAI,SAAS,YAAY,KAAKU,SAAS,SAAS,KAAK,CAAC;EAG/D,IAAI,KAAKT,SAAS;GAChB,IAAI,KAAKE,QACP,OAAO,QAAQ,OAAO,KAAKA,MAAM;GAEnC,OAAO,QAAQ,QAAQ;IAAE,MAAM;IAAM,OAAO,KAAA;GAAU,CAAC;EACzD;EAEA,OAAO,IAAI,SAAS,SAAS,WAAW;GACtC,KAAKG,UAAU;IAAE;IAAQ;GAAQ;EACnC,CAAC;CACH;CAEA,SACE,SACA,EAAE,KAAK,SACD;EACN,KAAKK,iBAAiB;EACtB,qBAAqB;GACnB,KAAKA,iBAAiB;EACxB,CAAC;EACD,KAAKC,cAAc;EACnB,QAAQ;GAAE,MAAM;GAAO,OAAO;EAAM,CAAC;CACvC;CAEA,oBAA0B;EACxB,MAAM,MAAM,KAAKA;EACjB,KAAKA,cAAc,KAAA;EACnB,MAAM;CACR;CAEA,oBAA0B;EACxB,KAAK,MAAM,SAAS,KAAKZ,SACvB,MAAM,MAAM;CAEhB;AACF"}
|