@clwnd/opencode 0.4.3 → 0.5.1
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/index.js +57 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -283,10 +283,19 @@ var { btoa, atob } = globalThis;
|
|
|
283
283
|
|
|
284
284
|
// provider.ts
|
|
285
285
|
var MCP_PREFIX = "mcp__clwnd__";
|
|
286
|
+
var TOOL_NAME_MAP = {
|
|
287
|
+
WebFetch: "webfetch",
|
|
288
|
+
WebSearch: "websearch",
|
|
289
|
+
TodoWrite: "todowrite",
|
|
290
|
+
AskUserQuestion: "question",
|
|
291
|
+
Task: "task",
|
|
292
|
+
Skill: "skill"
|
|
293
|
+
};
|
|
286
294
|
function mapToolName(name14) {
|
|
287
295
|
if (name14.startsWith(MCP_PREFIX)) return name14.slice(MCP_PREFIX.length);
|
|
288
|
-
return name14;
|
|
296
|
+
return TOOL_NAME_MAP[name14] ?? name14;
|
|
289
297
|
}
|
|
298
|
+
var BROKERED_TOOLS = /* @__PURE__ */ new Set(["webfetch", "websearch", "todowrite"]);
|
|
290
299
|
var INPUT_FIELD_MAP = {
|
|
291
300
|
read: { file_path: "filePath" },
|
|
292
301
|
edit: { file_path: "filePath", old_string: "oldString", new_string: "newString", replace_all: "replaceAll" },
|
|
@@ -300,6 +309,21 @@ var INPUT_FIELD_MAP = {
|
|
|
300
309
|
};
|
|
301
310
|
function mapToolInput(toolName, input) {
|
|
302
311
|
const ocName = mapToolName(toolName);
|
|
312
|
+
if (ocName === "todowrite") {
|
|
313
|
+
try {
|
|
314
|
+
const parsed = JSON.parse(input);
|
|
315
|
+
if (parsed.todos && Array.isArray(parsed.todos)) {
|
|
316
|
+
parsed.todos = parsed.todos.map((t) => ({
|
|
317
|
+
content: t.content ?? "",
|
|
318
|
+
status: t.status ?? "pending",
|
|
319
|
+
priority: t.priority ?? "medium"
|
|
320
|
+
}));
|
|
321
|
+
}
|
|
322
|
+
return JSON.stringify(parsed);
|
|
323
|
+
} catch {
|
|
324
|
+
return input;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
303
327
|
const fieldMap = INPUT_FIELD_MAP[ocName];
|
|
304
328
|
if (!fieldMap || Object.keys(fieldMap).length === 0) return input;
|
|
305
329
|
try {
|
|
@@ -347,6 +371,25 @@ function isAuxiliaryCall(opts) {
|
|
|
347
371
|
const hasTools = Array.isArray(opts.tools) && opts.tools.length > 0;
|
|
348
372
|
return !hasTools;
|
|
349
373
|
}
|
|
374
|
+
var OC_TO_MCP = {
|
|
375
|
+
read: "read",
|
|
376
|
+
edit: "edit",
|
|
377
|
+
write: "write",
|
|
378
|
+
bash: "bash",
|
|
379
|
+
glob: "glob",
|
|
380
|
+
grep: "grep",
|
|
381
|
+
apply_patch: "edit",
|
|
382
|
+
webfetch: "webfetch"
|
|
383
|
+
};
|
|
384
|
+
function deriveAllowedTools(opts) {
|
|
385
|
+
if (!Array.isArray(opts.tools)) return ["read", "edit", "write", "bash", "glob", "grep"];
|
|
386
|
+
const ocTools = new Set(opts.tools.map((t) => t.name));
|
|
387
|
+
const allowed = [];
|
|
388
|
+
for (const [ocName, mcpName] of Object.entries(OC_TO_MCP)) {
|
|
389
|
+
if (ocTools.has(ocName)) allowed.push(mcpName);
|
|
390
|
+
}
|
|
391
|
+
return [...new Set(allowed)];
|
|
392
|
+
}
|
|
350
393
|
function extractText(prompt) {
|
|
351
394
|
for (let i = prompt.length - 1; i >= 0; i--) {
|
|
352
395
|
const m = prompt[i];
|
|
@@ -416,6 +459,7 @@ var ClwndModel = class {
|
|
|
416
459
|
const warnings = [];
|
|
417
460
|
const cwd = this.config.cwd ?? process.cwd();
|
|
418
461
|
const permissions = isTitle ? [] : await getSessionPermissions(this.config.client, sid);
|
|
462
|
+
const allowedTools = isTitle ? [] : deriveAllowedTools(opts);
|
|
419
463
|
let reasoning = "";
|
|
420
464
|
let responseText = "";
|
|
421
465
|
const toolCalls = [];
|
|
@@ -435,7 +479,8 @@ var ClwndModel = class {
|
|
|
435
479
|
modelId: this.modelId,
|
|
436
480
|
text,
|
|
437
481
|
systemPrompt,
|
|
438
|
-
permissions
|
|
482
|
+
permissions,
|
|
483
|
+
allowedTools
|
|
439
484
|
}).then(async (resp) => {
|
|
440
485
|
if (!resp.body) {
|
|
441
486
|
abort();
|
|
@@ -540,6 +585,7 @@ var ClwndModel = class {
|
|
|
540
585
|
const self = this;
|
|
541
586
|
const toolInputAccum = /* @__PURE__ */ new Map();
|
|
542
587
|
const permissions = isTitle ? [] : await getSessionPermissions(this.config.client, sid);
|
|
588
|
+
const allowedTools = isTitle ? [] : deriveAllowedTools(opts);
|
|
543
589
|
const stream = new ReadableStream({
|
|
544
590
|
async start(controller) {
|
|
545
591
|
const textId = generateId();
|
|
@@ -548,6 +594,7 @@ var ClwndModel = class {
|
|
|
548
594
|
let reader = null;
|
|
549
595
|
let textStarted = false;
|
|
550
596
|
let reasoningStarted = false;
|
|
597
|
+
const brokeredCallIds = /* @__PURE__ */ new Set();
|
|
551
598
|
function emit(part) {
|
|
552
599
|
if (done) return;
|
|
553
600
|
try {
|
|
@@ -580,7 +627,8 @@ var ClwndModel = class {
|
|
|
580
627
|
modelId: self.modelId,
|
|
581
628
|
text,
|
|
582
629
|
systemPrompt,
|
|
583
|
-
permissions
|
|
630
|
+
permissions,
|
|
631
|
+
allowedTools
|
|
584
632
|
});
|
|
585
633
|
} catch (e) {
|
|
586
634
|
emit({ type: "error", error: new Error(String(e)) });
|
|
@@ -653,16 +701,19 @@ var ClwndModel = class {
|
|
|
653
701
|
} else {
|
|
654
702
|
rawInput = "{}";
|
|
655
703
|
}
|
|
704
|
+
const isBrokered = BROKERED_TOOLS.has(ocToolName);
|
|
705
|
+
if (isBrokered) brokeredCallIds.add(msg.toolCallId);
|
|
656
706
|
emit({
|
|
657
707
|
type: "tool-call",
|
|
658
708
|
toolCallId: msg.toolCallId,
|
|
659
709
|
toolName: ocToolName,
|
|
660
710
|
input: rawInput,
|
|
661
|
-
providerExecuted:
|
|
711
|
+
providerExecuted: !isBrokered
|
|
662
712
|
});
|
|
663
713
|
}
|
|
664
714
|
if (ct === "tool_result" && (msg.toolCallId || msg.toolUseId)) {
|
|
665
715
|
const callId = msg.toolCallId ?? msg.toolUseId;
|
|
716
|
+
if (brokeredCallIds.has(callId)) continue;
|
|
666
717
|
const raw = msg.result ?? "";
|
|
667
718
|
const { output, title, metadata } = parseToolResult(typeof raw === "string" ? raw : JSON.stringify(raw));
|
|
668
719
|
emit({
|
|
@@ -684,9 +735,10 @@ var ClwndModel = class {
|
|
|
684
735
|
const cacheRead = u?.cache_read_input_tokens ?? 0;
|
|
685
736
|
const cacheWrite = u?.cache_creation_input_tokens ?? 0;
|
|
686
737
|
const inputBase = u?.input_tokens ?? u?.inputTokens ?? 0;
|
|
738
|
+
const fr = brokeredCallIds.size > 0 ? "tool-calls" : msg.finishReason ?? "stop";
|
|
687
739
|
emit({
|
|
688
740
|
type: "finish",
|
|
689
|
-
finishReason:
|
|
741
|
+
finishReason: fr,
|
|
690
742
|
usage: {
|
|
691
743
|
inputTokens: inputBase + cacheRead + cacheWrite,
|
|
692
744
|
outputTokens: u?.output_tokens ?? u?.outputTokens,
|