@deepstrike/sdk 0.2.24 → 0.2.26
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/tools/index.js +31 -4
- package/dist/types/agent.js +14 -1
- package/package.json +2 -2
package/dist/tools/index.js
CHANGED
|
@@ -37,6 +37,22 @@ export function validateToolArguments(schemaJson, args) {
|
|
|
37
37
|
function validateValue(schema, parent, key, path, state) {
|
|
38
38
|
let value = parent[key];
|
|
39
39
|
const expectedType = schema.type;
|
|
40
|
+
// 0. 多态联合 (oneOf / anyOf) —— 先于单一 type 分支匹配
|
|
41
|
+
const union = (schema.oneOf ?? schema.anyOf);
|
|
42
|
+
if (Array.isArray(union)) {
|
|
43
|
+
for (const sub of union) {
|
|
44
|
+
// 先克隆再试:避免某分支的 auto-cast/裁剪部分改写后又失败,污染后续分支
|
|
45
|
+
const probe = { v: structuredClone(parent[key]) };
|
|
46
|
+
const probeState = { repaired: false };
|
|
47
|
+
if (!validateValue(sub, probe, "v", path, probeState)) {
|
|
48
|
+
parent[key] = probe.v; // 接受首个匹配分支(连同它内部的 repair)
|
|
49
|
+
if (probeState.repaired)
|
|
50
|
+
state.repaired = true;
|
|
51
|
+
return undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return `${path} does not match any allowed shape`;
|
|
55
|
+
}
|
|
40
56
|
// 1. 类型自动规整 (Auto-cast)
|
|
41
57
|
if (typeof expectedType === "string") {
|
|
42
58
|
if (expectedType === "boolean") {
|
|
@@ -92,14 +108,25 @@ function validateValue(schema, parent, key, path, state) {
|
|
|
92
108
|
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
93
109
|
return `${path} must be object`;
|
|
94
110
|
const obj = value;
|
|
95
|
-
// 3a. 裁剪多余字段
|
|
111
|
+
// 3a. 裁剪多余字段 —— 尊重 additionalProperties。
|
|
112
|
+
// 缺省/false 维持旧的"裁剪"行为(所有现存工具都依赖它);只有显式 true 或子 schema 才放行。
|
|
96
113
|
const properties = schema.properties ?? {};
|
|
97
114
|
const allowedKeys = new Set(Object.keys(properties));
|
|
115
|
+
const additional = schema.additionalProperties;
|
|
98
116
|
for (const objKey of Object.keys(obj)) {
|
|
99
|
-
if (
|
|
100
|
-
|
|
101
|
-
|
|
117
|
+
if (allowedKeys.has(objKey))
|
|
118
|
+
continue;
|
|
119
|
+
if (additional === true)
|
|
120
|
+
continue; // 任意键放行:不校验、不裁剪
|
|
121
|
+
if (additional && typeof additional === "object") {
|
|
122
|
+
// 用子 schema 递归校验每个额外键的值(也会 auto-cast / 补默认)
|
|
123
|
+
const err = validateValue(additional, obj, objKey, `${path}.${objKey}`, state);
|
|
124
|
+
if (err)
|
|
125
|
+
return err;
|
|
126
|
+
continue;
|
|
102
127
|
}
|
|
128
|
+
delete obj[objKey]; // additionalProperties 缺省/false → 维持旧行为
|
|
129
|
+
state.repaired = true;
|
|
103
130
|
}
|
|
104
131
|
for (const required of schema.required ?? []) {
|
|
105
132
|
if (!(required in obj))
|
package/dist/types/agent.js
CHANGED
|
@@ -66,6 +66,19 @@ export function milestoneCheckResultToKernel(result) {
|
|
|
66
66
|
...(result.reason ? { reason: result.reason } : {}),
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
|
+
/** Tool-call `arguments` reach us as a raw model-authored string (e.g. the OpenAIChat-family
|
|
70
|
+
* non-streaming path passes it through verbatim via `normalizeToolCalls`). A malformed JSON
|
|
71
|
+
* string must degrade to empty args here, never throw — otherwise one bad tool-call on a
|
|
72
|
+
* sub-agent's final turn bricks the parent's result serialization. Mirrors the `catch→{}`
|
|
73
|
+
* guard every provider/runtime parse site already uses. */
|
|
74
|
+
function safeParseToolArgs(raw) {
|
|
75
|
+
try {
|
|
76
|
+
return JSON.parse(raw || "{}");
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
return {};
|
|
80
|
+
}
|
|
81
|
+
}
|
|
69
82
|
export function subAgentResultToKernel(result) {
|
|
70
83
|
const finalMessage = result.result.finalMessage;
|
|
71
84
|
return {
|
|
@@ -79,7 +92,7 @@ export function subAgentResultToKernel(result) {
|
|
|
79
92
|
tool_calls: (finalMessage.toolCalls ?? []).map(tc => ({
|
|
80
93
|
id: tc.id,
|
|
81
94
|
name: tc.name,
|
|
82
|
-
arguments:
|
|
95
|
+
arguments: safeParseToolArgs(tc.arguments),
|
|
83
96
|
})),
|
|
84
97
|
...(finalMessage.tokenCount !== undefined ? { token_count: finalMessage.tokenCount } : {}),
|
|
85
98
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepstrike/sdk",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.26",
|
|
4
4
|
"description": "DeepStrike Node.js SDK",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@anthropic-ai/sdk": "^0.99.0",
|
|
23
|
-
"@deepstrike/core": "0.2.
|
|
23
|
+
"@deepstrike/core": "0.2.26",
|
|
24
24
|
"@google/generative-ai": "^0.24.1",
|
|
25
25
|
"openai": "^5.23.2"
|
|
26
26
|
},
|