@ai-setting/roy-agent-core 1.5.43 → 1.5.45
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/config/index.js +5 -5
- package/dist/env/agent/index.js +5 -5
- package/dist/env/commands/index.js +5 -5
- package/dist/env/context/index.js +4 -1
- package/dist/env/debug/index.js +5 -5
- package/dist/env/event-source/index.js +7 -7
- package/dist/env/hook/index.js +3 -3
- package/dist/env/index.js +24 -20
- package/dist/env/llm/index.js +5 -5
- package/dist/env/log-trace/index.js +5 -5
- package/dist/env/mcp/index.js +20 -6
- package/dist/env/memory/index.js +5 -5
- package/dist/env/plugin/index.js +5 -5
- package/dist/env/prompt/index.js +5 -5
- package/dist/env/session/index.js +6 -6
- package/dist/env/session/storage/index.js +1 -1
- package/dist/env/skill/index.js +5 -5
- package/dist/env/task/delegate/index.js +3 -3
- package/dist/env/task/index.js +6 -6
- package/dist/env/task/plugins/index.js +2 -2
- package/dist/env/tool/built-in/index.js +1 -1
- package/dist/env/tool/index.js +6 -6
- package/dist/env/workflow/decorators/index.js +1 -1
- package/dist/env/workflow/engine/index.js +10 -4
- package/dist/env/workflow/index.js +42 -24
- package/dist/env/workflow/nodes/index.js +5 -1
- package/dist/env/workflow/tools/index.js +14 -0
- package/dist/env/workflow/types/index.js +16 -2
- package/dist/env/workflow/utils/index.js +15 -196
- package/dist/index.js +35 -31
- package/dist/shared/@ai-setting/{roy-agent-core-kajktp3d.js → roy-agent-core-20fm423j.js} +47 -26
- package/dist/shared/@ai-setting/{roy-agent-core-ffb9fq4v.js → roy-agent-core-2vhsccvz.js} +54 -12
- package/dist/shared/@ai-setting/{roy-agent-core-69jskqjg.js → roy-agent-core-44g4dhzg.js} +75 -7
- package/dist/shared/@ai-setting/{roy-agent-core-e9fdm13a.js → roy-agent-core-4gmxjdhn.js} +4 -2
- package/dist/shared/@ai-setting/{roy-agent-core-b4wd9tn6.js → roy-agent-core-4k9a823d.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-68qy97r3.js +31 -0
- package/dist/shared/@ai-setting/roy-agent-core-6atd905e.js +42 -0
- package/dist/shared/@ai-setting/{roy-agent-core-4jqq077c.js → roy-agent-core-6e3wz81d.js} +2 -2
- package/dist/shared/@ai-setting/{roy-agent-core-pwkk12p4.js → roy-agent-core-6mcb7nqa.js} +60 -0
- package/dist/shared/@ai-setting/roy-agent-core-6vxg2gmr.js +321 -0
- package/dist/shared/@ai-setting/{roy-agent-core-9p43ap7h.js → roy-agent-core-8y804aat.js} +4 -2
- package/dist/shared/@ai-setting/{roy-agent-core-0rtxwr28.js → roy-agent-core-9bmtxmp6.js} +77 -120
- package/dist/shared/@ai-setting/{roy-agent-core-r6rwsr54.js → roy-agent-core-9p604xjf.js} +29 -9
- package/dist/shared/@ai-setting/{roy-agent-core-z1xf2fdk.js → roy-agent-core-a67e90d1.js} +6 -4
- package/dist/shared/@ai-setting/{roy-agent-core-xkb264a8.js → roy-agent-core-bp3xggmb.js} +192 -26
- package/dist/shared/@ai-setting/{roy-agent-core-zrja5v78.js → roy-agent-core-ce9w0j8n.js} +10 -2
- package/dist/shared/@ai-setting/{roy-agent-core-bmr6bdfb.js → roy-agent-core-cr8xer31.js} +15 -8
- package/dist/shared/@ai-setting/roy-agent-core-dbxm76wf.js +190 -0
- package/dist/shared/@ai-setting/{roy-agent-core-nj8yerg9.js → roy-agent-core-eftqdsy5.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-7fgf85wc.js → roy-agent-core-h0x19xgn.js} +6 -7
- package/dist/shared/@ai-setting/{roy-agent-core-psvwzdhj.js → roy-agent-core-hdszq729.js} +9 -5
- package/dist/shared/@ai-setting/{roy-agent-core-dxbsc1zy.js → roy-agent-core-ja9qhg6d.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-cevpwnq7.js → roy-agent-core-mjbfgqen.js} +5 -3
- package/dist/shared/@ai-setting/roy-agent-core-nhfy3p8q.js +132 -0
- package/dist/shared/@ai-setting/{roy-agent-core-2jnzv9at.js → roy-agent-core-nn9dmffw.js} +629 -288
- package/dist/shared/@ai-setting/roy-agent-core-qnrf2aw6.js +441 -0
- package/dist/shared/@ai-setting/{roy-agent-core-ee6nnnqw.js → roy-agent-core-r9hq4cjx.js} +8 -1
- package/dist/shared/@ai-setting/{roy-agent-core-jqy2mdyq.js → roy-agent-core-rgj6hq15.js} +52 -41
- package/dist/shared/@ai-setting/{roy-agent-core-z33en0cz.js → roy-agent-core-rm3hay00.js} +15 -2
- package/dist/shared/@ai-setting/{roy-agent-core-e130w7mv.js → roy-agent-core-rx74rye7.js} +5 -3
- package/dist/shared/@ai-setting/{roy-agent-core-pxcrzyv9.js → roy-agent-core-sk535ft2.js} +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-v002ynpa.js +435 -0
- package/dist/shared/@ai-setting/{roy-agent-core-2dhd60aw.js → roy-agent-core-vdwvamre.js} +10 -0
- package/dist/shared/@ai-setting/{roy-agent-core-1zq3p19q.js → roy-agent-core-w64zachx.js} +8 -4
- package/dist/shared/@ai-setting/roy-agent-core-ye0z728h.js +18 -0
- package/dist/shared/@ai-setting/{roy-agent-core-rsybkb38.js → roy-agent-core-ysvh8er9.js} +36 -39
- package/dist/shared/@ai-setting/{roy-agent-core-9yxb3ty9.js → roy-agent-core-z5sxe4p7.js} +5 -1
- package/dist/shared/@ai-setting/{roy-agent-core-eg6nv09z.js → roy-agent-core-ztx5eh72.js} +1 -1
- package/dist/shared/@ai-setting/{roy-agent-core-nqgrjja0.js → roy-agent-core-zwq6vhpj.js} +1 -1
- package/package.json +1 -1
- package/dist/shared/@ai-setting/roy-agent-core-5x94xmt6.js +0 -350
- package/dist/shared/@ai-setting/roy-agent-core-dh9d7a3m.js +0 -11
- package/dist/shared/@ai-setting/roy-agent-core-jvatggbb.js +0 -603
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WORKFLOW_SUBMIT_OUTPUT_TOOL_NAME,
|
|
3
|
+
createSubmitJsonOutputTool,
|
|
4
|
+
init_submit_json_output_tool,
|
|
5
|
+
parseWorkflowJsonOutput
|
|
6
|
+
} from "./roy-agent-core-nhfy3p8q.js";
|
|
7
|
+
import {
|
|
8
|
+
AskUserError,
|
|
9
|
+
init_workflow_hil
|
|
10
|
+
} from "./roy-agent-core-e25xkv53.js";
|
|
11
|
+
import {
|
|
12
|
+
globalHookManager,
|
|
13
|
+
init_global_hook_manager
|
|
14
|
+
} from "./roy-agent-core-rgj6hq15.js";
|
|
15
|
+
import {
|
|
16
|
+
createLogger,
|
|
17
|
+
init_logger
|
|
18
|
+
} from "./roy-agent-core-10n2jh7p.js";
|
|
19
|
+
import {
|
|
20
|
+
__esm
|
|
21
|
+
} from "./roy-agent-core-fs0mn2jk.js";
|
|
22
|
+
|
|
23
|
+
// src/env/workflow/utils/output-schema-hint.ts
|
|
24
|
+
function describeOutputSchema(schema) {
|
|
25
|
+
if (!schema || typeof schema !== "object") {
|
|
26
|
+
return "Submit a JSON object matching the configured output schema";
|
|
27
|
+
}
|
|
28
|
+
const obj = schema;
|
|
29
|
+
if (!obj.properties || Object.keys(obj.properties).length === 0) {
|
|
30
|
+
return "Submit a JSON object matching the configured output schema";
|
|
31
|
+
}
|
|
32
|
+
const required = new Set(obj.required ?? []);
|
|
33
|
+
const fields = Object.entries(obj.properties).map(([name, prop]) => {
|
|
34
|
+
const type = prop.type ?? "unknown";
|
|
35
|
+
const req = required.has(name) ? "required" : "optional";
|
|
36
|
+
const desc = prop.description ? ` — ${prop.description}` : "";
|
|
37
|
+
return `${name}: ${type} (${req})${desc}`;
|
|
38
|
+
});
|
|
39
|
+
return `Expected fields: ${fields.join("; ")}`;
|
|
40
|
+
}
|
|
41
|
+
var init_output_schema_hint = () => {};
|
|
42
|
+
|
|
43
|
+
// src/env/workflow/plugins/workflow-json-output-plugin.ts
|
|
44
|
+
function isWorkflowJsonOutputEnabled(pluginEnabled) {
|
|
45
|
+
return pluginEnabled?.[WORKFLOW_JSON_OUTPUT_PLUGIN_KEY] === true;
|
|
46
|
+
}
|
|
47
|
+
function registerWorkflowJsonOutputPlugin(llmComponent) {
|
|
48
|
+
if (registered) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
registered = true;
|
|
52
|
+
globalHookManager.register(HOOK_POINT, {
|
|
53
|
+
name: HOOK_NAME,
|
|
54
|
+
pluginName: WORKFLOW_JSON_OUTPUT_PLUGIN_NAME,
|
|
55
|
+
sourceId: WORKFLOW_JSON_OUTPUT_SOURCE_ID,
|
|
56
|
+
priority: 100,
|
|
57
|
+
description: "Extract structured JSON after ReAct via a dedicated LLM invoke",
|
|
58
|
+
execute: async (wrapper) => {
|
|
59
|
+
const hookCtx = wrapper.data;
|
|
60
|
+
await runWorkflowJsonOutputExtraction(hookCtx, llmComponent);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
logger.info("Workflow JSON output plugin registered on agent:after.react");
|
|
64
|
+
}
|
|
65
|
+
function unregisterWorkflowJsonOutputPlugin() {
|
|
66
|
+
globalHookManager.unregister(HOOK_POINT, HOOK_NAME);
|
|
67
|
+
registered = false;
|
|
68
|
+
}
|
|
69
|
+
async function runWorkflowJsonOutputExtraction(hookCtx, llmComponent) {
|
|
70
|
+
const schema = hookCtx.context.metadata?.outputSchema;
|
|
71
|
+
if (!schema) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (hookCtx.error instanceof AskUserError) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (hookCtx.structuredOutputExtracted) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const extracted = await extractStructuredJsonViaLlm(llmComponent, hookCtx.messages, schema, {
|
|
81
|
+
model: hookCtx.context.model ?? hookCtx.agent.config.model,
|
|
82
|
+
sessionId: hookCtx.context.sessionId,
|
|
83
|
+
abortSignal: hookCtx.context.abort
|
|
84
|
+
});
|
|
85
|
+
if (extracted) {
|
|
86
|
+
hookCtx.structuredOutputExtracted = extracted;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
async function extractStructuredJsonViaLlm(llmComponent, historyMessages, schema, options = {}) {
|
|
90
|
+
const submitTool = createSubmitJsonOutputTool(schema);
|
|
91
|
+
const extractionUserMessage = {
|
|
92
|
+
role: "user",
|
|
93
|
+
content: "Based on the conversation above, call workflow_submit_output exactly once with structured JSON. " + `${describeOutputSchema(schema)}.`
|
|
94
|
+
};
|
|
95
|
+
const messages = [...historyMessages, extractionUserMessage].map(toLLMMessage);
|
|
96
|
+
const result = await llmComponent.invoke({
|
|
97
|
+
messages,
|
|
98
|
+
tools: [
|
|
99
|
+
{
|
|
100
|
+
name: submitTool.name,
|
|
101
|
+
description: submitTool.description ?? "",
|
|
102
|
+
parameters: submitTool.parameters
|
|
103
|
+
}
|
|
104
|
+
],
|
|
105
|
+
toolChoice: {
|
|
106
|
+
type: "function",
|
|
107
|
+
function: { name: WORKFLOW_SUBMIT_OUTPUT_TOOL_NAME }
|
|
108
|
+
},
|
|
109
|
+
model: options.model,
|
|
110
|
+
context: {
|
|
111
|
+
sessionId: options.sessionId
|
|
112
|
+
},
|
|
113
|
+
abortSignal: options.abortSignal,
|
|
114
|
+
skipThresholdCheck: true
|
|
115
|
+
});
|
|
116
|
+
const toolCalls = result.output?.toolCalls ?? [];
|
|
117
|
+
for (let i = toolCalls.length - 1;i >= 0; i--) {
|
|
118
|
+
const tc = toolCalls[i];
|
|
119
|
+
const name = tc.function?.name ?? tc.name;
|
|
120
|
+
if (name !== WORKFLOW_SUBMIT_OUTPUT_TOOL_NAME) {
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
const argsRaw = tc.function?.arguments ?? tc.arguments;
|
|
124
|
+
const argsStr = typeof argsRaw === "string" ? argsRaw : JSON.stringify(argsRaw ?? {});
|
|
125
|
+
try {
|
|
126
|
+
const parsed = submitTool.parameters.parse(JSON.parse(argsStr));
|
|
127
|
+
return parsed;
|
|
128
|
+
} catch {
|
|
129
|
+
const fromExecute = await submitTool.execute(JSON.parse(argsStr));
|
|
130
|
+
const fromMarker = parseWorkflowJsonOutput(fromExecute.output);
|
|
131
|
+
if (fromMarker) {
|
|
132
|
+
return fromMarker;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
logger.warn("Workflow JSON extraction invoke did not return workflow_submit_output");
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
function toLLMMessage(msg) {
|
|
140
|
+
if (typeof msg.content === "string") {
|
|
141
|
+
return {
|
|
142
|
+
role: msg.role,
|
|
143
|
+
content: msg.content
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
if (Array.isArray(msg.content)) {
|
|
147
|
+
if (msg.role === "tool") {
|
|
148
|
+
const toolResult = msg.content.find((part) => part.type === "tool-result");
|
|
149
|
+
const output = toolResult?.output;
|
|
150
|
+
const content = typeof output === "string" ? output : output && typeof output === "object" && ("value" in output) ? String(output.value ?? "") : JSON.stringify(output ?? "");
|
|
151
|
+
return {
|
|
152
|
+
role: "tool",
|
|
153
|
+
content,
|
|
154
|
+
toolCallId: toolResult?.toolCallId,
|
|
155
|
+
name: toolResult?.toolName
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
const text = msg.content.filter((part) => part.type === "text").map((part) => part.text ?? "").join("");
|
|
159
|
+
const toolCallParts = msg.content.filter((part) => part.type === "tool-call");
|
|
160
|
+
const toolCalls = msg.role === "assistant" && toolCallParts.length > 0 ? toolCallParts.map((part) => {
|
|
161
|
+
const argsString = typeof part.input === "string" ? part.input : JSON.stringify(part.input ?? {});
|
|
162
|
+
const toolName = part.toolName ?? "unknown";
|
|
163
|
+
return {
|
|
164
|
+
id: part.toolCallId ?? "",
|
|
165
|
+
name: toolName,
|
|
166
|
+
arguments: argsString,
|
|
167
|
+
function: { name: toolName, arguments: argsString }
|
|
168
|
+
};
|
|
169
|
+
}) : undefined;
|
|
170
|
+
return {
|
|
171
|
+
role: msg.role,
|
|
172
|
+
content: text,
|
|
173
|
+
...toolCalls?.length ? { toolCalls } : {}
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
return { role: msg.role, content: "" };
|
|
177
|
+
}
|
|
178
|
+
var logger, WORKFLOW_JSON_OUTPUT_SOURCE_ID = "workflow", WORKFLOW_JSON_OUTPUT_PLUGIN_NAME = "json-output", WORKFLOW_JSON_OUTPUT_PLUGIN_KEY, HOOK_POINT = "agent:after.react", HOOK_NAME, registered = false;
|
|
179
|
+
var init_workflow_json_output_plugin = __esm(() => {
|
|
180
|
+
init_global_hook_manager();
|
|
181
|
+
init_workflow_hil();
|
|
182
|
+
init_submit_json_output_tool();
|
|
183
|
+
init_output_schema_hint();
|
|
184
|
+
init_logger();
|
|
185
|
+
logger = createLogger("WorkflowJsonOutputPlugin");
|
|
186
|
+
WORKFLOW_JSON_OUTPUT_PLUGIN_KEY = `${WORKFLOW_JSON_OUTPUT_SOURCE_ID}:${WORKFLOW_JSON_OUTPUT_PLUGIN_NAME}`;
|
|
187
|
+
HOOK_NAME = `${WORKFLOW_JSON_OUTPUT_PLUGIN_NAME}:${HOOK_POINT}`;
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
export { WORKFLOW_JSON_OUTPUT_SOURCE_ID, WORKFLOW_JSON_OUTPUT_PLUGIN_NAME, WORKFLOW_JSON_OUTPUT_PLUGIN_KEY, isWorkflowJsonOutputEnabled, registerWorkflowJsonOutputPlugin, unregisterWorkflowJsonOutputPlugin, runWorkflowJsonOutputExtraction, extractStructuredJsonViaLlm, init_workflow_json_output_plugin };
|
|
@@ -132,6 +132,11 @@ class WorkflowConverter {
|
|
|
132
132
|
retry: meta.retry,
|
|
133
133
|
timeout: meta.timeout
|
|
134
134
|
}));
|
|
135
|
+
const edges = edgeMetadatas.map((edge) => ({
|
|
136
|
+
from: edge.from,
|
|
137
|
+
to: edge.to,
|
|
138
|
+
when: edge.condition
|
|
139
|
+
}));
|
|
135
140
|
const entry = workflowMeta.entry || nodeMetadatas[0]?.nodeId || "unknown";
|
|
136
141
|
return {
|
|
137
142
|
name: workflowMeta.name,
|
|
@@ -139,6 +144,7 @@ class WorkflowConverter {
|
|
|
139
144
|
description: workflowMeta.description,
|
|
140
145
|
config: workflowMeta.config || {},
|
|
141
146
|
nodes,
|
|
147
|
+
edges,
|
|
142
148
|
entry,
|
|
143
149
|
outputs: [],
|
|
144
150
|
metadata: {
|
|
@@ -158,13 +164,6 @@ class WorkflowConverter {
|
|
|
158
164
|
if (!targetNode.dependsOn.includes(edge.from)) {
|
|
159
165
|
targetNode.dependsOn = [...targetNode.dependsOn, edge.from];
|
|
160
166
|
}
|
|
161
|
-
if (edge.condition) {
|
|
162
|
-
if (targetNode.condition) {
|
|
163
|
-
targetNode.condition = `(${targetNode.condition}) AND (${edge.condition})`;
|
|
164
|
-
} else {
|
|
165
|
-
targetNode.condition = edge.condition;
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
167
|
}
|
|
169
168
|
}
|
|
170
169
|
return nodeMap;
|
|
@@ -1,20 +1,22 @@
|
|
|
1
1
|
import {
|
|
2
2
|
TaskTagPlugin,
|
|
3
3
|
createLarkCliTaskNotifyHook
|
|
4
|
-
} from "./roy-agent-core-
|
|
4
|
+
} from "./roy-agent-core-4gmxjdhn.js";
|
|
5
5
|
import {
|
|
6
6
|
envKeyToConfigKey
|
|
7
7
|
} from "./roy-agent-core-qxhq8ven.js";
|
|
8
8
|
import {
|
|
9
9
|
BaseComponent
|
|
10
|
-
} from "./roy-agent-core-
|
|
10
|
+
} from "./roy-agent-core-6e3wz81d.js";
|
|
11
11
|
import {
|
|
12
|
-
globalHookManager
|
|
13
|
-
|
|
12
|
+
globalHookManager,
|
|
13
|
+
init_global_hook_manager
|
|
14
|
+
} from "./roy-agent-core-rgj6hq15.js";
|
|
14
15
|
import {
|
|
15
16
|
createEnvContext,
|
|
17
|
+
init_context,
|
|
16
18
|
runWithEnvContext
|
|
17
|
-
} from "./roy-agent-core-
|
|
19
|
+
} from "./roy-agent-core-rm3hay00.js";
|
|
18
20
|
import {
|
|
19
21
|
createLogger,
|
|
20
22
|
init_logger
|
|
@@ -27,7 +29,9 @@ import {
|
|
|
27
29
|
} from "./roy-agent-core-fs0mn2jk.js";
|
|
28
30
|
|
|
29
31
|
// src/env/event-source/event-source-handlers.ts
|
|
32
|
+
init_global_hook_manager();
|
|
30
33
|
import { spawn } from "child_process";
|
|
34
|
+
init_context();
|
|
31
35
|
var BUILT_IN_PLUGIN_FACTORIES = {
|
|
32
36
|
LarkCliTaskNotifyPlugin: (cfg) => createLarkCliTaskNotifyHook(cfg),
|
|
33
37
|
"task-tag": () => new TaskTagPlugin
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
2
|
BaseComponent
|
|
3
|
-
} from "./roy-agent-core-
|
|
3
|
+
} from "./roy-agent-core-6e3wz81d.js";
|
|
4
4
|
import {
|
|
5
|
-
globalHookManager
|
|
6
|
-
|
|
5
|
+
globalHookManager,
|
|
6
|
+
init_global_hook_manager
|
|
7
|
+
} from "./roy-agent-core-rgj6hq15.js";
|
|
7
8
|
import {
|
|
8
9
|
createLogger,
|
|
9
10
|
init_logger
|
|
10
11
|
} from "./roy-agent-core-10n2jh7p.js";
|
|
11
12
|
|
|
12
13
|
// src/env/plugin/plugin-component.ts
|
|
14
|
+
init_global_hook_manager();
|
|
13
15
|
init_logger();
|
|
14
16
|
|
|
15
17
|
class PluginComponent extends BaseComponent {
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import {
|
|
2
|
+
__esm
|
|
3
|
+
} from "./roy-agent-core-fs0mn2jk.js";
|
|
4
|
+
|
|
5
|
+
// src/env/workflow/utils/json-schema-to-zod.ts
|
|
6
|
+
import { z } from "zod";
|
|
7
|
+
function validateJsonOutputSchema(schema) {
|
|
8
|
+
if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
|
|
9
|
+
throw new Error("output.schema must be a JSON object");
|
|
10
|
+
}
|
|
11
|
+
const record = schema;
|
|
12
|
+
if (record.type !== "object") {
|
|
13
|
+
throw new Error('output.schema.type must be "object"');
|
|
14
|
+
}
|
|
15
|
+
const properties = record.properties;
|
|
16
|
+
if (!properties || typeof properties !== "object" || Array.isArray(properties)) {
|
|
17
|
+
throw new Error("output.schema.properties must be an object");
|
|
18
|
+
}
|
|
19
|
+
const propertyEntries = Object.entries(properties);
|
|
20
|
+
if (propertyEntries.length === 0) {
|
|
21
|
+
throw new Error("output.schema.properties must not be empty");
|
|
22
|
+
}
|
|
23
|
+
const required = record.required;
|
|
24
|
+
if (required !== undefined) {
|
|
25
|
+
if (!Array.isArray(required)) {
|
|
26
|
+
throw new Error("output.schema.required must be an array of property names");
|
|
27
|
+
}
|
|
28
|
+
for (const key of required) {
|
|
29
|
+
if (typeof key !== "string") {
|
|
30
|
+
throw new Error("output.schema.required entries must be strings");
|
|
31
|
+
}
|
|
32
|
+
if (!(key in properties)) {
|
|
33
|
+
throw new Error(`output.schema.required references unknown property "${key}"`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
for (const [name, prop] of propertyEntries) {
|
|
38
|
+
if (!prop || typeof prop !== "object" || Array.isArray(prop)) {
|
|
39
|
+
throw new Error(`output.schema.properties.${name} must be an object`);
|
|
40
|
+
}
|
|
41
|
+
const propRecord = prop;
|
|
42
|
+
const type = propRecord.type;
|
|
43
|
+
if (typeof type !== "string" || !SUPPORTED_PROPERTY_TYPES.has(type)) {
|
|
44
|
+
throw new Error(`output.schema.properties.${name}.type must be one of: ${[...SUPPORTED_PROPERTY_TYPES].join(", ")}`);
|
|
45
|
+
}
|
|
46
|
+
if (propRecord.description !== undefined && typeof propRecord.description !== "string") {
|
|
47
|
+
throw new Error(`output.schema.properties.${name}.description must be a string`);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
jsonSchemaToZod(record);
|
|
51
|
+
return record;
|
|
52
|
+
}
|
|
53
|
+
function jsonSchemaToZod(schema) {
|
|
54
|
+
if (schema.type !== "object" || !schema.properties) {
|
|
55
|
+
throw new Error("Agent output schema must be a JSON object with properties");
|
|
56
|
+
}
|
|
57
|
+
const required = new Set(schema.required ?? []);
|
|
58
|
+
const shape = {};
|
|
59
|
+
for (const [key, prop] of Object.entries(schema.properties)) {
|
|
60
|
+
let field = propertyToZod(prop);
|
|
61
|
+
if (prop.description) {
|
|
62
|
+
field = field.describe(prop.description);
|
|
63
|
+
}
|
|
64
|
+
if (!required.has(key)) {
|
|
65
|
+
field = field.optional();
|
|
66
|
+
}
|
|
67
|
+
shape[key] = field;
|
|
68
|
+
}
|
|
69
|
+
return z.object(shape);
|
|
70
|
+
}
|
|
71
|
+
function propertyToZod(prop) {
|
|
72
|
+
switch (prop.type) {
|
|
73
|
+
case "boolean":
|
|
74
|
+
return z.boolean();
|
|
75
|
+
case "string":
|
|
76
|
+
return z.string();
|
|
77
|
+
case "number":
|
|
78
|
+
case "integer":
|
|
79
|
+
return z.number();
|
|
80
|
+
default:
|
|
81
|
+
return z.unknown();
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
var SUPPORTED_PROPERTY_TYPES;
|
|
85
|
+
var init_json_schema_to_zod = __esm(() => {
|
|
86
|
+
SUPPORTED_PROPERTY_TYPES = new Set(["boolean", "string", "number", "integer"]);
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
// src/env/workflow/tools/submit-json-output-tool.ts
|
|
90
|
+
function createSubmitJsonOutputTool(schema) {
|
|
91
|
+
const parameters = jsonSchemaToZod(schema);
|
|
92
|
+
return {
|
|
93
|
+
name: WORKFLOW_SUBMIT_OUTPUT_TOOL_NAME,
|
|
94
|
+
description: "Submit the final structured JSON result for this workflow agent step. " + "You MUST call this tool once with your final answer — do not reply with plain text only.",
|
|
95
|
+
parameters,
|
|
96
|
+
async execute(args) {
|
|
97
|
+
const parsed = parameters.parse(args);
|
|
98
|
+
return {
|
|
99
|
+
success: true,
|
|
100
|
+
output: `${WorkflowJsonOutputMarker}:${JSON.stringify(parsed)}`
|
|
101
|
+
};
|
|
102
|
+
},
|
|
103
|
+
metadata: {
|
|
104
|
+
category: "workflow",
|
|
105
|
+
tags: ["structured-output"],
|
|
106
|
+
version: "1.0.0"
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function parseWorkflowJsonOutput(output) {
|
|
111
|
+
if (typeof output !== "string") {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
if (!output.startsWith(`${WorkflowJsonOutputMarker}:`)) {
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
try {
|
|
118
|
+
const data = JSON.parse(output.slice(WorkflowJsonOutputMarker.length + 1));
|
|
119
|
+
if (data && typeof data === "object" && !Array.isArray(data)) {
|
|
120
|
+
return data;
|
|
121
|
+
}
|
|
122
|
+
} catch {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
var WORKFLOW_SUBMIT_OUTPUT_TOOL_NAME = "workflow_submit_output", WorkflowJsonOutputMarker = "__WORKFLOW_JSON_OUTPUT__";
|
|
128
|
+
var init_submit_json_output_tool = __esm(() => {
|
|
129
|
+
init_json_schema_to_zod();
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
export { validateJsonOutputSchema, jsonSchemaToZod, init_json_schema_to_zod, WORKFLOW_SUBMIT_OUTPUT_TOOL_NAME, WorkflowJsonOutputMarker, createSubmitJsonOutputTool, parseWorkflowJsonOutput, init_submit_json_output_tool };
|