@swifty.js/swifty 0.0.27 → 0.0.29
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 +47 -37
- package/dist/agent-YR6YK26C.js +4 -0
- package/dist/anthropic-5GRR5JCT.js +4 -0
- package/dist/checker-N5TIJEN5.js +4 -0
- package/dist/chunk-D34FUVGU.js +4 -0
- package/dist/{chunk-UGJVMFGH.js → chunk-K5ZK27BX.js} +1 -1
- package/dist/chunk-LIMEBKCY.js +408 -0
- package/dist/chunk-OTVZGPHD.js +121 -0
- package/dist/chunk-POHIQUFP.js +301 -0
- package/dist/chunk-QCKJLO6X.js +4 -0
- package/dist/chunk-QFSCPD63.js +4 -0
- package/dist/chunk-TMEX7RFA.js +4 -0
- package/dist/chunk-Y6SQB5FG.js +4 -0
- package/dist/lib/agent-5WEKVRTD.js +11 -0
- package/dist/lib/{anthropic-RYPJDHQM.js → anthropic-KWO3KLNV.js} +4 -5
- package/dist/lib/{checker-6BW4222R.js → checker-AXHPKVBY.js} +2 -2
- package/dist/lib/{chunk-HK2Z6WP4.js → chunk-2IVEVG5N.js} +5 -1
- package/dist/lib/{chunk-XFSN4LMA.js → chunk-3FBS5NB7.js} +71 -18
- package/dist/lib/{chunk-GNI7YX6F.js → chunk-DJ6AILPN.js} +70 -24
- package/dist/lib/chunk-GCY44T7S.js +2346 -0
- package/dist/lib/{chunk-PZ42NAFA.js → chunk-KG4MJGKQ.js} +19 -21
- package/dist/lib/{chunk-2AUSNVIB.js → chunk-KZSBR4FO.js} +44 -37
- package/dist/lib/chunk-PIL7M52F.js +127 -0
- package/dist/lib/chunk-Z4CYHTII.js +392 -0
- package/dist/lib/index.d.ts +227 -132
- package/dist/lib/index.js +2195 -1602
- package/dist/lib/{openai-VX5VBXZ4.js → openai-PBF7EWNJ.js} +2 -3
- package/dist/lib/{tool-filter-VF7TZRE5.js → tool-filter-R6HDDJHE.js} +1 -1
- package/dist/main.js +203 -194
- package/dist/{openai-5FDSLJNM.js → openai-QQ2K7GPF.js} +14 -14
- package/dist/{server-F666APPN.js → server-G23HCFLI.js} +21 -21
- package/dist/{tool-filter-NO7I3HFD.js → tool-filter-VBP6WOGO.js} +1 -1
- package/package.json +2 -2
- package/dist/agent-OMC6YIMW.js +0 -4
- package/dist/anthropic-T5K4BQPB.js +0 -4
- package/dist/checker-TOQVEG3P.js +0 -4
- package/dist/chunk-5I2WXSGV.js +0 -90
- package/dist/chunk-A2VR3BC4.js +0 -4
- package/dist/chunk-A57FEYSN.js +0 -4
- package/dist/chunk-BRC5L644.js +0 -130
- package/dist/chunk-FZPTNGTU.js +0 -4
- package/dist/chunk-G6YIQW3Z.js +0 -238
- package/dist/chunk-I2XG2PXV.js +0 -4
- package/dist/chunk-LVSHXIBK.js +0 -389
- package/dist/chunk-SULWNDNC.js +0 -4
- package/dist/chunk-WO6DL7OB.js +0 -35
- package/dist/lib/agent-U7MIUCKT.js +0 -9
- package/dist/lib/chunk-2QILP24G.js +0 -1120
- package/dist/lib/chunk-3LU4APFB.js +0 -339
- package/dist/lib/chunk-OO2CLOEE.js +0 -88
- package/dist/lib/chunk-RKJYTYQM.js +0 -1285
|
@@ -54,9 +54,9 @@ var MCPToolWrapper = class {
|
|
|
54
54
|
input_schema: this.inputSchema
|
|
55
55
|
};
|
|
56
56
|
}
|
|
57
|
-
async execute(
|
|
57
|
+
async execute(ctx, args) {
|
|
58
58
|
try {
|
|
59
|
-
return await this.client.callTool(this.originalName, args);
|
|
59
|
+
return await this.client.callTool(this.originalName, args, ctx.abortSignal);
|
|
60
60
|
} catch (err) {
|
|
61
61
|
log.error({ err }, "mcp operation failed");
|
|
62
62
|
return {
|
|
@@ -82,7 +82,7 @@ function coerceScalar(value, want) {
|
|
|
82
82
|
return value;
|
|
83
83
|
}
|
|
84
84
|
const parsed = want === "integer" ? Number.parseInt(text, 10) : Number.parseFloat(text);
|
|
85
|
-
return Number.
|
|
85
|
+
return Number.isFinite(parsed) ? parsed : value;
|
|
86
86
|
}
|
|
87
87
|
if (want === "boolean" && typeof value === "string") {
|
|
88
88
|
const low = value.trim().toLowerCase();
|
|
@@ -177,21 +177,15 @@ var McpCallTool = class {
|
|
|
177
177
|
}
|
|
178
178
|
};
|
|
179
179
|
}
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
* round.
|
|
186
|
-
*/
|
|
187
|
-
resolve(server, tool) {
|
|
188
|
-
const direct = this.registry.get(tool) ?? this.registry.get(buildMcpToolName(server, tool));
|
|
189
|
-
if (direct) {
|
|
190
|
-
return direct;
|
|
180
|
+
resolveTarget(args) {
|
|
181
|
+
const server = strArg(args, "server");
|
|
182
|
+
const name = strArg(args, "tool");
|
|
183
|
+
if (!server || !name) {
|
|
184
|
+
return void 0;
|
|
191
185
|
}
|
|
192
|
-
const
|
|
193
|
-
const
|
|
194
|
-
return
|
|
186
|
+
const fullName = name.startsWith(MCP_TOOL_PREFIX) ? name : buildMcpToolName(server, name);
|
|
187
|
+
const target = this.registry.get(fullName);
|
|
188
|
+
return target && isMcpToolLike(target) && sanitizeSegment(target.mcpServerName) === sanitizeSegment(server) ? target : void 0;
|
|
195
189
|
}
|
|
196
190
|
availableNames() {
|
|
197
191
|
return this.registry.listTools().filter((t) => t.name.startsWith(MCP_TOOL_PREFIX)).map((t) => t.name).sort();
|
|
@@ -202,7 +196,7 @@ var McpCallTool = class {
|
|
|
202
196
|
if (tool === "") {
|
|
203
197
|
return { output: "McpCall requires a 'tool' name", isError: true };
|
|
204
198
|
}
|
|
205
|
-
const target = this.
|
|
199
|
+
const target = this.resolveTarget(args);
|
|
206
200
|
if (!target) {
|
|
207
201
|
const names = this.availableNames();
|
|
208
202
|
const hint = names.length > 0 ? names.join(", ") : "(none connected)";
|
|
@@ -211,10 +205,13 @@ var McpCallTool = class {
|
|
|
211
205
|
isError: true
|
|
212
206
|
};
|
|
213
207
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
208
|
+
if (typeof args.arguments !== "object" || args.arguments === null || Array.isArray(args.arguments)) {
|
|
209
|
+
return {
|
|
210
|
+
output: "McpCall requires an 'arguments' object matching the target schema",
|
|
211
|
+
isError: true
|
|
212
|
+
};
|
|
217
213
|
}
|
|
214
|
+
let inner = asRecord(args.arguments);
|
|
218
215
|
if (isMcpToolLike(target)) {
|
|
219
216
|
const schema = target.mcpInputSchema();
|
|
220
217
|
if (Object.keys(schema).length > 0) {
|
|
@@ -224,6 +221,7 @@ var McpCallTool = class {
|
|
|
224
221
|
}
|
|
225
222
|
}
|
|
226
223
|
}
|
|
224
|
+
ctx.abortSignal?.throwIfAborted();
|
|
227
225
|
return target.execute(ctx, inner);
|
|
228
226
|
}
|
|
229
227
|
};
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
} from "./chunk-
|
|
4
|
-
import {
|
|
5
|
-
getContextWindow,
|
|
6
|
-
getMaxOutputTokens,
|
|
7
|
-
resolveAPIKey
|
|
8
|
-
} from "./chunk-3LU4APFB.js";
|
|
2
|
+
normalizeToolResultContentBlock
|
|
3
|
+
} from "./chunk-PIL7M52F.js";
|
|
9
4
|
import {
|
|
10
5
|
AuthenticationError,
|
|
11
6
|
ContextTooLongError,
|
|
12
7
|
LLMError,
|
|
13
8
|
NetworkError,
|
|
14
9
|
RateLimitError,
|
|
15
|
-
ensureToolPairing
|
|
16
|
-
|
|
10
|
+
ensureToolPairing,
|
|
11
|
+
getMaxOutputTokens,
|
|
12
|
+
getThinkingLevel,
|
|
13
|
+
resolveAPIKey,
|
|
14
|
+
thinkingBudgetForLevel
|
|
15
|
+
} from "./chunk-Z4CYHTII.js";
|
|
17
16
|
import {
|
|
18
17
|
MCP_TOOL_PREFIX,
|
|
19
18
|
isMcpToolLike
|
|
20
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-KG4MJGKQ.js";
|
|
21
20
|
import {
|
|
22
21
|
asErrorString,
|
|
23
22
|
asRecord,
|
|
24
23
|
asString,
|
|
25
24
|
contentToText,
|
|
26
25
|
createChildLogger,
|
|
27
|
-
isRecord
|
|
26
|
+
isRecord,
|
|
27
|
+
strArg
|
|
28
28
|
} from "./chunk-EY7HE52Q.js";
|
|
29
29
|
|
|
30
30
|
// src/llm/anthropic.ts
|
|
@@ -96,6 +96,8 @@ function decideAndApply(registry, baseUrl, contextWindow) {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
// src/llm/anthropic.ts
|
|
99
|
+
var MIN_THINKING_BUDGET_TOKENS = 1024;
|
|
100
|
+
var MIN_ANSWER_TOKENS = 1024;
|
|
99
101
|
function markToolsForCache(tools) {
|
|
100
102
|
for (let i = tools.length - 1; i >= 0; i--) {
|
|
101
103
|
const t = tools[i];
|
|
@@ -152,14 +154,17 @@ async function fetchModelContextWindow(config) {
|
|
|
152
154
|
clearTimeout(timer);
|
|
153
155
|
}
|
|
154
156
|
}
|
|
155
|
-
function supportsAdaptiveThinking() {
|
|
156
|
-
return true;
|
|
157
|
-
}
|
|
158
157
|
function userBlocksFor(content) {
|
|
159
158
|
if (typeof content === "string") {
|
|
160
159
|
return [{ type: "text", text: content }];
|
|
161
160
|
}
|
|
162
|
-
return content
|
|
161
|
+
return content.map((raw) => {
|
|
162
|
+
const block = normalizeToolResultContentBlock(raw);
|
|
163
|
+
if (!block || block.type === "tool_reference") {
|
|
164
|
+
throw new Error(`Unsupported user content block: ${strArg(raw, "type", "unknown")}`);
|
|
165
|
+
}
|
|
166
|
+
return block;
|
|
167
|
+
});
|
|
163
168
|
}
|
|
164
169
|
function buildAnthropicMessages(messages) {
|
|
165
170
|
const result = [];
|
|
@@ -208,6 +213,9 @@ function buildAnthropicMessages(messages) {
|
|
|
208
213
|
content: tr.contentBlocks?.length ? tr.contentBlocks : tr.content
|
|
209
214
|
});
|
|
210
215
|
}
|
|
216
|
+
if (m.content.length > 0) {
|
|
217
|
+
blocks.push(...userBlocksFor(m.content));
|
|
218
|
+
}
|
|
211
219
|
result.push({ role: "user", content: blocks });
|
|
212
220
|
} else {
|
|
213
221
|
if (result.length === 0) {
|
|
@@ -248,18 +256,17 @@ var AnthropicClient = class {
|
|
|
248
256
|
client;
|
|
249
257
|
model;
|
|
250
258
|
/**
|
|
251
|
-
*
|
|
259
|
+
* PI-equivalent thinking level; maps to a thinking token budget.
|
|
252
260
|
*/
|
|
253
|
-
|
|
261
|
+
thinkingLevel;
|
|
254
262
|
systemPrompt;
|
|
255
263
|
maxOutputTokens;
|
|
256
264
|
/** Currently not used */
|
|
257
|
-
contextWindow;
|
|
258
265
|
constructor(config, systemPrompt) {
|
|
259
266
|
const apiKey = resolveAPIKey(config);
|
|
260
267
|
if (!apiKey) {
|
|
261
268
|
throw new AuthenticationError(
|
|
262
|
-
"Anthropic API key not found, set ANTHROPIC_API_KEY in
|
|
269
|
+
"Anthropic API key not found, set ANTHROPIC_API_KEY in ~/.swifty/config.yaml, or via ANTHROPIC_API_KEY env variable."
|
|
263
270
|
);
|
|
264
271
|
}
|
|
265
272
|
this.client = new Anthropic({
|
|
@@ -267,10 +274,9 @@ var AnthropicClient = class {
|
|
|
267
274
|
baseURL: config.base_url
|
|
268
275
|
});
|
|
269
276
|
this.model = config.model;
|
|
270
|
-
this.
|
|
277
|
+
this.thinkingLevel = getThinkingLevel(config);
|
|
271
278
|
this.systemPrompt = systemPrompt;
|
|
272
279
|
this.maxOutputTokens = getMaxOutputTokens(config);
|
|
273
|
-
this.contextWindow = getContextWindow(config);
|
|
274
280
|
}
|
|
275
281
|
setSystemPrompt(prompt) {
|
|
276
282
|
this.systemPrompt = prompt;
|
|
@@ -278,6 +284,12 @@ var AnthropicClient = class {
|
|
|
278
284
|
setMaxOutputTokens(maxTokens) {
|
|
279
285
|
this.maxOutputTokens = maxTokens;
|
|
280
286
|
}
|
|
287
|
+
setThinkingLevel(level) {
|
|
288
|
+
this.thinkingLevel = level;
|
|
289
|
+
}
|
|
290
|
+
getThinkingLevel() {
|
|
291
|
+
return this.thinkingLevel;
|
|
292
|
+
}
|
|
281
293
|
async *stream(conversation, toolSchemas, abortSignal) {
|
|
282
294
|
const messages = buildAnthropicMessages(ensureToolPairing(conversation.getMessages()));
|
|
283
295
|
const sendToolSearchBeta = needsToolSearchBeta(toolSchemas);
|
|
@@ -316,19 +328,11 @@ var AnthropicClient = class {
|
|
|
316
328
|
messages,
|
|
317
329
|
...antToolSchemas.length > 0 ? { tools: antToolSchemas } : {}
|
|
318
330
|
};
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
};
|
|
325
|
-
}
|
|
326
|
-
} else {
|
|
327
|
-
params.thinking = {
|
|
328
|
-
type: "enabled",
|
|
329
|
-
budget_tokens: computeCompactThreshold(this.contextWindow, this.maxOutputTokens)
|
|
330
|
-
};
|
|
331
|
-
}
|
|
331
|
+
const budgetCeiling = this.maxOutputTokens - MIN_ANSWER_TOKENS;
|
|
332
|
+
params.thinking = this.thinkingLevel !== "off" && budgetCeiling >= MIN_THINKING_BUDGET_TOKENS ? {
|
|
333
|
+
type: "enabled",
|
|
334
|
+
budget_tokens: Math.min(thinkingBudgetForLevel(this.thinkingLevel), budgetCeiling)
|
|
335
|
+
} : { type: "disabled" };
|
|
332
336
|
let inputTokens = 0;
|
|
333
337
|
let outputTokens = 0;
|
|
334
338
|
let cacheReadInputTokens = 0;
|
|
@@ -377,7 +381,7 @@ var AnthropicClient = class {
|
|
|
377
381
|
text: delta.thinking
|
|
378
382
|
};
|
|
379
383
|
} else if (delta.type === "signature_delta") {
|
|
380
|
-
thinkingSignature
|
|
384
|
+
thinkingSignature += delta.signature;
|
|
381
385
|
} else if (delta.type === "text_delta") {
|
|
382
386
|
yield {
|
|
383
387
|
type: "text_delta",
|
|
@@ -497,6 +501,7 @@ function markLastUserTailForCache(messages) {
|
|
|
497
501
|
Reflect.set(last, "cache_control", {
|
|
498
502
|
type: "ephemeral"
|
|
499
503
|
});
|
|
504
|
+
return;
|
|
500
505
|
}
|
|
501
506
|
}
|
|
502
507
|
function classifyAnthropicError(err) {
|
|
@@ -508,14 +513,16 @@ function classifyAnthropicError(err) {
|
|
|
508
513
|
return new AuthenticationError(`Invalid API key: ${err.message}`);
|
|
509
514
|
}
|
|
510
515
|
if (err.status === 429 /* RateLimitError */) {
|
|
511
|
-
const
|
|
516
|
+
const headers = err.headers;
|
|
517
|
+
const retryAfter = headers instanceof Headers ? headers.get("retry-after") : void 0;
|
|
512
518
|
let message = "Rate Limited";
|
|
513
519
|
if (retryAfter) {
|
|
514
520
|
const s = Number.parseInt(asString(retryAfter));
|
|
515
521
|
if (Number.isNaN(s)) {
|
|
516
522
|
message += ", please wait.";
|
|
523
|
+
} else {
|
|
524
|
+
message += `, retry after ${asString(s)}s.`;
|
|
517
525
|
}
|
|
518
|
-
message += `, retry after ${asString(s)}s.`;
|
|
519
526
|
} else {
|
|
520
527
|
message += ", please wait.";
|
|
521
528
|
}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// src/tools/types.ts
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
var IMAGE_MEDIA_TYPES = /* @__PURE__ */ new Set([
|
|
6
|
+
"image/jpeg",
|
|
7
|
+
"image/png",
|
|
8
|
+
"image/gif",
|
|
9
|
+
"image/webp"
|
|
10
|
+
]);
|
|
11
|
+
function isImageMediaType(value) {
|
|
12
|
+
return IMAGE_MEDIA_TYPES.has(value);
|
|
13
|
+
}
|
|
14
|
+
function normalizeTextBlock(value) {
|
|
15
|
+
return isRecord(value) && value.type === "text" && typeof value.text === "string" ? { type: "text", text: value.text } : null;
|
|
16
|
+
}
|
|
17
|
+
function normalizeImageBlock(value) {
|
|
18
|
+
if (!isRecord(value) || value.type !== "image" || !isRecord(value.source)) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
if (value.source.type === "url" && typeof value.source.url === "string") {
|
|
22
|
+
return { type: "image", source: { type: "url", url: value.source.url } };
|
|
23
|
+
}
|
|
24
|
+
if (value.source.type === "base64" && typeof value.source.media_type === "string" && isImageMediaType(value.source.media_type) && typeof value.source.data === "string") {
|
|
25
|
+
return {
|
|
26
|
+
type: "image",
|
|
27
|
+
source: {
|
|
28
|
+
type: "base64",
|
|
29
|
+
media_type: value.source.media_type,
|
|
30
|
+
data: value.source.data
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
function normalizeDocumentBlock(value) {
|
|
37
|
+
if (value.type !== "document" || !isRecord(value.source)) {
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
let source = null;
|
|
41
|
+
if (value.source.type === "url" && typeof value.source.url === "string") {
|
|
42
|
+
source = { type: "url", url: value.source.url };
|
|
43
|
+
} else if (value.source.type === "base64" && value.source.media_type === "application/pdf" && typeof value.source.data === "string") {
|
|
44
|
+
source = { type: "base64", media_type: "application/pdf", data: value.source.data };
|
|
45
|
+
} else if (value.source.type === "text" && value.source.media_type === "text/plain" && typeof value.source.data === "string") {
|
|
46
|
+
source = { type: "text", media_type: "text/plain", data: value.source.data };
|
|
47
|
+
} else if (value.source.type === "content") {
|
|
48
|
+
if (typeof value.source.content === "string") {
|
|
49
|
+
source = { type: "content", content: value.source.content };
|
|
50
|
+
} else if (Array.isArray(value.source.content)) {
|
|
51
|
+
const content = [];
|
|
52
|
+
for (const raw of value.source.content) {
|
|
53
|
+
const block = normalizeTextBlock(raw) ?? normalizeImageBlock(raw);
|
|
54
|
+
if (!block) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
content.push(block);
|
|
58
|
+
}
|
|
59
|
+
source = { type: "content", content };
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
if (!source) {
|
|
63
|
+
return null;
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
type: "document",
|
|
67
|
+
source,
|
|
68
|
+
...typeof value.title === "string" || value.title === null ? { title: value.title } : {},
|
|
69
|
+
...typeof value.context === "string" || value.context === null ? { context: value.context } : {}
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
function normalizeToolResultContentBlock(value) {
|
|
73
|
+
const text = normalizeTextBlock(value);
|
|
74
|
+
if (text) {
|
|
75
|
+
return text;
|
|
76
|
+
}
|
|
77
|
+
const image = normalizeImageBlock(value);
|
|
78
|
+
if (image) {
|
|
79
|
+
return image;
|
|
80
|
+
}
|
|
81
|
+
if (!isRecord(value)) {
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
if (value.type === "tool_reference" && typeof value.tool_name === "string") {
|
|
85
|
+
return { type: "tool_reference", tool_name: value.tool_name };
|
|
86
|
+
}
|
|
87
|
+
if (value.type === "search_result" && typeof value.source === "string" && typeof value.title === "string" && Array.isArray(value.content)) {
|
|
88
|
+
const content = [];
|
|
89
|
+
for (const raw of value.content) {
|
|
90
|
+
const block = normalizeTextBlock(raw);
|
|
91
|
+
if (!block) {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
content.push(block);
|
|
95
|
+
}
|
|
96
|
+
return { type: "search_result", source: value.source, title: value.title, content };
|
|
97
|
+
}
|
|
98
|
+
return normalizeDocumentBlock(value);
|
|
99
|
+
}
|
|
100
|
+
function isToolResultContentBlock(value) {
|
|
101
|
+
return normalizeToolResultContentBlock(value) !== null;
|
|
102
|
+
}
|
|
103
|
+
var SKIP_DIRS = /* @__PURE__ */ new Set([
|
|
104
|
+
".agents",
|
|
105
|
+
".git",
|
|
106
|
+
// Git
|
|
107
|
+
".swifty",
|
|
108
|
+
// Swifty
|
|
109
|
+
".next",
|
|
110
|
+
// Next.js
|
|
111
|
+
".venv",
|
|
112
|
+
// Python venv
|
|
113
|
+
".mypy_cache",
|
|
114
|
+
// Python mypy
|
|
115
|
+
"__pycache__",
|
|
116
|
+
// Python
|
|
117
|
+
"dist",
|
|
118
|
+
// Webpack, Vite
|
|
119
|
+
"node_modules"
|
|
120
|
+
// Node.js
|
|
121
|
+
]);
|
|
122
|
+
|
|
123
|
+
export {
|
|
124
|
+
normalizeToolResultContentBlock,
|
|
125
|
+
isToolResultContentBlock,
|
|
126
|
+
SKIP_DIRS
|
|
127
|
+
};
|