@clwnd/opencode 0.13.1 → 0.14.0
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 +130 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -152,6 +152,11 @@ var Drone = class _Drone {
|
|
|
152
152
|
this.swallowThreshold = swallowThreshold;
|
|
153
153
|
this.llmAssess = llmAssess;
|
|
154
154
|
}
|
|
155
|
+
side;
|
|
156
|
+
onAction;
|
|
157
|
+
evaluate;
|
|
158
|
+
swallowThreshold;
|
|
159
|
+
llmAssess;
|
|
155
160
|
states = /* @__PURE__ */ new Map();
|
|
156
161
|
timers = /* @__PURE__ */ new Map();
|
|
157
162
|
evaluating = /* @__PURE__ */ new Set();
|
|
@@ -661,8 +666,79 @@ function extractSystemPrompt(prompt) {
|
|
|
661
666
|
}
|
|
662
667
|
return parts.join("\n\n");
|
|
663
668
|
}
|
|
669
|
+
function sanitizePrompt(text, word) {
|
|
670
|
+
if (!text) return text;
|
|
671
|
+
text = text.replace(/<\/?\w[\w-]*\b[^>]*>/g, "");
|
|
672
|
+
if (!word) {
|
|
673
|
+
return text.replace(/^\n+/, "");
|
|
674
|
+
}
|
|
675
|
+
const needle = new RegExp(word.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"), "i");
|
|
676
|
+
const lines = [];
|
|
677
|
+
{
|
|
678
|
+
let cursor = 0;
|
|
679
|
+
while (cursor < text.length) {
|
|
680
|
+
const nl = text.indexOf("\n", cursor);
|
|
681
|
+
if (nl === -1) {
|
|
682
|
+
lines.push(text.slice(cursor));
|
|
683
|
+
break;
|
|
684
|
+
}
|
|
685
|
+
lines.push(text.slice(cursor, nl + 1));
|
|
686
|
+
cursor = nl + 1;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
const kindOf = (line) => {
|
|
690
|
+
const body = line.replace(/\n$/, "");
|
|
691
|
+
if (!body.trim()) return "blank";
|
|
692
|
+
if (/^\s*#/.test(body)) return "header";
|
|
693
|
+
if (/^\s*(?:[-*]|\d+\.)\s/.test(body)) return "list";
|
|
694
|
+
return "prose";
|
|
695
|
+
};
|
|
696
|
+
const isContinuation = (line) => {
|
|
697
|
+
const body = line.replace(/\n$/, "");
|
|
698
|
+
if (!body.trim()) return false;
|
|
699
|
+
return /^\s/.test(body) && !/^\s*(?:[-*]|\d+\.)\s/.test(body);
|
|
700
|
+
};
|
|
701
|
+
const units = [];
|
|
702
|
+
let i = 0;
|
|
703
|
+
while (i < lines.length) {
|
|
704
|
+
const k = kindOf(lines[i]);
|
|
705
|
+
if (k === "blank" || k === "header") {
|
|
706
|
+
units.push(lines[i]);
|
|
707
|
+
i++;
|
|
708
|
+
continue;
|
|
709
|
+
}
|
|
710
|
+
if (k === "list") {
|
|
711
|
+
let unit = lines[i];
|
|
712
|
+
i++;
|
|
713
|
+
while (i < lines.length && isContinuation(lines[i])) {
|
|
714
|
+
unit += lines[i];
|
|
715
|
+
i++;
|
|
716
|
+
}
|
|
717
|
+
units.push(unit);
|
|
718
|
+
continue;
|
|
719
|
+
}
|
|
720
|
+
let block = lines[i];
|
|
721
|
+
i++;
|
|
722
|
+
while (i < lines.length && kindOf(lines[i]) === "prose") {
|
|
723
|
+
block += lines[i];
|
|
724
|
+
i++;
|
|
725
|
+
}
|
|
726
|
+
const sentRe = /[.!?][ \t\n]+|\n/g;
|
|
727
|
+
let start = 0;
|
|
728
|
+
let m;
|
|
729
|
+
while ((m = sentRe.exec(block)) !== null) {
|
|
730
|
+
const end = m.index + m[0].length;
|
|
731
|
+
units.push(block.slice(start, end));
|
|
732
|
+
start = end;
|
|
733
|
+
}
|
|
734
|
+
if (start < block.length) units.push(block.slice(start));
|
|
735
|
+
}
|
|
736
|
+
const kept = units.filter((u) => !needle.test(u));
|
|
737
|
+
while (kept.length > 0 && !kept[0].trim()) kept.shift();
|
|
738
|
+
return kept.join("");
|
|
739
|
+
}
|
|
664
740
|
function isAuxiliaryCall(opts) {
|
|
665
|
-
return
|
|
741
|
+
return opts.tools === void 0;
|
|
666
742
|
}
|
|
667
743
|
function isBrokeredToolReturn(prompt) {
|
|
668
744
|
if (prompt.length < 2) return false;
|
|
@@ -779,11 +855,27 @@ var ClwndModel = class {
|
|
|
779
855
|
this.config = config;
|
|
780
856
|
this.modelId = modelId;
|
|
781
857
|
}
|
|
858
|
+
config;
|
|
782
859
|
specificationVersion = "v3";
|
|
783
860
|
modelId;
|
|
784
861
|
provider = "clwnd";
|
|
785
862
|
supportedUrls = { "image/*": [] };
|
|
786
863
|
async doGenerate(opts) {
|
|
864
|
+
const rawAgent = opts.headers?.["x-clwnd-agent"] ?? "";
|
|
865
|
+
let agentName = rawAgent;
|
|
866
|
+
try {
|
|
867
|
+
const p = JSON.parse(rawAgent);
|
|
868
|
+
if (p?.name) agentName = p.name;
|
|
869
|
+
} catch {
|
|
870
|
+
}
|
|
871
|
+
if (agentName === "title") {
|
|
872
|
+
return {
|
|
873
|
+
content: [{ type: "text", text: "" }],
|
|
874
|
+
usage: zeroUsage(),
|
|
875
|
+
finishReason: { unified: "stop", raw: "stop" },
|
|
876
|
+
warnings: []
|
|
877
|
+
};
|
|
878
|
+
}
|
|
787
879
|
if (isAuxiliaryCall(opts)) {
|
|
788
880
|
return {
|
|
789
881
|
content: [{ type: "text", text: "" }],
|
|
@@ -818,15 +910,35 @@ var ClwndModel = class {
|
|
|
818
910
|
trace("doStream.enter", { sid, promptLen: opts.prompt.length, lastRole });
|
|
819
911
|
const content = extractContent(opts.prompt, sid);
|
|
820
912
|
const text = content.filter((p) => p.type === "text").map((p) => p.text).join("\n\n");
|
|
821
|
-
const systemPrompt = extractSystemPrompt(opts.prompt);
|
|
913
|
+
const systemPrompt = sanitizePrompt(extractSystemPrompt(opts.prompt), "opencode");
|
|
822
914
|
detectAgent(sid, opts.headers);
|
|
823
915
|
const cwd = (this.config.client ? await getSessionDirectory(this.config.client, sid) : null) ?? this.config.cwd ?? process.cwd();
|
|
824
916
|
const self = this;
|
|
825
917
|
const sap = /* @__PURE__ */ new Map();
|
|
826
918
|
const permissions = await getSessionPermissions(this.config.client, sid);
|
|
827
919
|
const allowedTools = deriveAllowedTools(sid, opts);
|
|
828
|
-
const
|
|
829
|
-
|
|
920
|
+
const rawAgent = opts.headers?.["x-clwnd-agent"] ?? "";
|
|
921
|
+
let agentName = rawAgent;
|
|
922
|
+
try {
|
|
923
|
+
const p = JSON.parse(rawAgent);
|
|
924
|
+
if (p?.name) agentName = p.name;
|
|
925
|
+
} catch {
|
|
926
|
+
}
|
|
927
|
+
const isTitleGen = agentName === "title";
|
|
928
|
+
const isEmptyTools = !opts.tools || opts.tools.length === 0;
|
|
929
|
+
if (isTitleGen) {
|
|
930
|
+
trace("title.skip", { method: "doStream", sid });
|
|
931
|
+
return {
|
|
932
|
+
stream: new ReadableStream({
|
|
933
|
+
start(controller) {
|
|
934
|
+
controller.enqueue({ type: "finish", finishReason: { unified: "stop", raw: "stop" }, usage: zeroUsage() });
|
|
935
|
+
controller.close();
|
|
936
|
+
}
|
|
937
|
+
})
|
|
938
|
+
};
|
|
939
|
+
}
|
|
940
|
+
const skipGraft = isEmptyTools;
|
|
941
|
+
if (skipGraft) trace("graft.skip", { method: "doStream", sid, reason: "emptyTools", toolsLen: opts.tools?.length ?? "undefined" });
|
|
830
942
|
let permAskId = null;
|
|
831
943
|
const isPermReturn = isBrokeredToolReturn(opts.prompt) && (() => {
|
|
832
944
|
const lt = opts.prompt.findLast((m) => m.role === "tool");
|
|
@@ -860,8 +972,18 @@ var ClwndModel = class {
|
|
|
860
972
|
}
|
|
861
973
|
const listenOnly = !!isPermReturn;
|
|
862
974
|
const priorPetals = opts.prompt.filter((m) => m.role === "user" || m.role === "assistant" || m.role === "tool");
|
|
863
|
-
trace("priorPetals", {
|
|
864
|
-
|
|
975
|
+
trace("priorPetals", {
|
|
976
|
+
sid,
|
|
977
|
+
count: priorPetals.length,
|
|
978
|
+
roles: priorPetals.map((m) => m.role).join(","),
|
|
979
|
+
hasToolUse: priorPetals.some(
|
|
980
|
+
(p) => p.role === "assistant" && Array.isArray(p.content) && p.content.some((c) => c.type === "tool-call")
|
|
981
|
+
),
|
|
982
|
+
toolCallCount: priorPetals.filter(
|
|
983
|
+
(p) => p.role === "assistant" && Array.isArray(p.content)
|
|
984
|
+
).reduce((acc, p) => acc + p.content.filter((c) => c.type === "tool-call").length, 0)
|
|
985
|
+
});
|
|
986
|
+
if (!skipGraft) {
|
|
865
987
|
const prev = sessionPetalCounts.get(sid) ?? 0;
|
|
866
988
|
sessionPetalCounts.set(sid, priorPetals.length);
|
|
867
989
|
if (prev > 0 && priorPetals.length < prev * 0.5) {
|
|
@@ -910,8 +1032,7 @@ var ClwndModel = class {
|
|
|
910
1032
|
permissions,
|
|
911
1033
|
allowedTools,
|
|
912
1034
|
listenOnly,
|
|
913
|
-
|
|
914
|
-
// skip graft for compaction/title gen
|
|
1035
|
+
skipGraft: skipGraft || void 0,
|
|
915
1036
|
ocServerUrl: self.config.pluginInput?.serverUrl?.toString(),
|
|
916
1037
|
priorPetals,
|
|
917
1038
|
externalTools: externalTools.length > 0 ? externalTools : void 0,
|
|
@@ -976,6 +1097,7 @@ var ClwndModel = class {
|
|
|
976
1097
|
permissions,
|
|
977
1098
|
allowedTools,
|
|
978
1099
|
listenOnly,
|
|
1100
|
+
skipGraft: skipGraft || void 0,
|
|
979
1101
|
ocServerUrl: self.config.pluginInput?.serverUrl?.toString(),
|
|
980
1102
|
priorPetals,
|
|
981
1103
|
dusk: duskIn(3e4)
|