@clwnd/opencode 0.14.0 → 0.15.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.
Files changed (2) hide show
  1. package/dist/index.js +43 -11
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -631,12 +631,14 @@ function extractContent(prompt, sessionId) {
631
631
  }
632
632
  if (parts.length === 0) continue;
633
633
  if (sessionId) {
634
+ const norm = (s) => s.replace(/\s+/g, " ").trim();
634
635
  for (let j = parts.length - 1; j >= 0; j--) {
635
636
  if (parts[j].type !== "text") continue;
636
637
  const reminder = parts[j].text.match(/<system-reminder>[\s\S]*?<\/system-reminder>/)?.[0];
637
638
  if (reminder) {
639
+ const key = norm(reminder);
638
640
  const prev = lastReminder.get(sessionId);
639
- if (prev === reminder) {
641
+ if (prev === key) {
640
642
  const stripped = parts[j].text.replace(reminder, "").trim();
641
643
  if (stripped) {
642
644
  parts[j] = { type: "text", text: stripped };
@@ -645,7 +647,7 @@ function extractContent(prompt, sessionId) {
645
647
  }
646
648
  trace("reminder.stripped", { sid: sessionId });
647
649
  } else {
648
- lastReminder.set(sessionId, reminder);
650
+ lastReminder.set(sessionId, key);
649
651
  }
650
652
  }
651
653
  }
@@ -740,6 +742,11 @@ function sanitizePrompt(text, word) {
740
742
  function isAuxiliaryCall(opts) {
741
743
  return opts.tools === void 0;
742
744
  }
745
+ function pickAuxModel(primary) {
746
+ if (/^claude-opus/i.test(primary)) return "claude-sonnet-4-6";
747
+ if (/^claude-sonnet/i.test(primary)) return "claude-haiku-4-5";
748
+ return primary;
749
+ }
743
750
  function isBrokeredToolReturn(prompt) {
744
751
  if (prompt.length < 2) return false;
745
752
  const last = prompt[prompt.length - 1];
@@ -817,6 +824,14 @@ async function getMcpServerConfigs(client) {
817
824
  }
818
825
  }
819
826
  var lastAllowedTools = /* @__PURE__ */ new Map();
827
+ var lastSystemPromptHash = /* @__PURE__ */ new Map();
828
+ var lastPermissionsHash = /* @__PURE__ */ new Map();
829
+ var lastAllowedToolsHash = /* @__PURE__ */ new Map();
830
+ function cheapHash(s) {
831
+ let h = 5381;
832
+ for (let i = 0; i < s.length; i++) h = (h << 5) + h + s.charCodeAt(i) | 0;
833
+ return h.toString(36) + ":" + s.length;
834
+ }
820
835
  var AGENT_DENY = {
821
836
  plan: /* @__PURE__ */ new Set(["edit", "write"])
822
837
  };
@@ -939,6 +954,18 @@ var ClwndModel = class {
939
954
  }
940
955
  const skipGraft = isEmptyTools;
941
956
  if (skipGraft) trace("graft.skip", { method: "doStream", sid, reason: "emptyTools", toolsLen: opts.tools?.length ?? "undefined" });
957
+ const effectiveModel = isEmptyTools ? pickAuxModel(self.modelId) : self.modelId;
958
+ if (effectiveModel !== self.modelId) trace("aux.model.routed", { sid, primary: self.modelId, aux: effectiveModel });
959
+ const systemPromptHash = cheapHash(systemPrompt);
960
+ const permissionsHash = cheapHash(JSON.stringify(permissions));
961
+ const allowedToolsHash = cheapHash(allowedTools.join(","));
962
+ const sendSystemPrompt = lastSystemPromptHash.get(sid) !== systemPromptHash;
963
+ const sendPermissions = lastPermissionsHash.get(sid) !== permissionsHash;
964
+ const sendAllowedTools = lastAllowedToolsHash.get(sid) !== allowedToolsHash;
965
+ if (sendSystemPrompt) lastSystemPromptHash.set(sid, systemPromptHash);
966
+ if (sendPermissions) lastPermissionsHash.set(sid, permissionsHash);
967
+ if (sendAllowedTools) lastAllowedToolsHash.set(sid, allowedToolsHash);
968
+ trace("hum.dedup", { sid, sp: sendSystemPrompt, perm: sendPermissions, tools: sendAllowedTools });
942
969
  let permAskId = null;
943
970
  const isPermReturn = isBrokeredToolReturn(opts.prompt) && (() => {
944
971
  const lt = opts.prompt.findLast((m) => m.role === "tool");
@@ -983,12 +1010,17 @@ var ClwndModel = class {
983
1010
  (p) => p.role === "assistant" && Array.isArray(p.content)
984
1011
  ).reduce((acc, p) => acc + p.content.filter((c) => c.type === "tool-call").length, 0)
985
1012
  });
1013
+ let prevPetalCount = 0;
1014
+ let elidePriorPetals = false;
986
1015
  if (!skipGraft) {
987
- const prev = sessionPetalCounts.get(sid) ?? 0;
1016
+ prevPetalCount = sessionPetalCounts.get(sid) ?? 0;
988
1017
  sessionPetalCounts.set(sid, priorPetals.length);
989
- if (prev > 0 && priorPetals.length < prev * 0.5) {
990
- trace("compaction.detected", { sid, prev, now: priorPetals.length });
1018
+ if (prevPetalCount > 0 && priorPetals.length < prevPetalCount * 0.5) {
1019
+ trace("compaction.detected", { sid, prev: prevPetalCount, now: priorPetals.length });
991
1020
  hum({ chi: "cancel", sid, reason: "compaction" });
1021
+ } else if (prevPetalCount === priorPetals.length && prevPetalCount > 0) {
1022
+ elidePriorPetals = true;
1023
+ trace("priorPetals.elided", { sid, count: priorPetals.length });
992
1024
  }
993
1025
  }
994
1026
  const externalTools = [];
@@ -1011,7 +1043,7 @@ var ClwndModel = class {
1011
1043
  chi: "prompt",
1012
1044
  sid,
1013
1045
  cwd,
1014
- modelId: self.modelId,
1046
+ modelId: effectiveModel,
1015
1047
  listenOnly: true,
1016
1048
  dusk: duskIn(3e4)
1017
1049
  });
@@ -1025,16 +1057,16 @@ var ClwndModel = class {
1025
1057
  chi: "prompt",
1026
1058
  sid,
1027
1059
  cwd,
1028
- modelId: self.modelId,
1060
+ modelId: effectiveModel,
1029
1061
  content,
1030
1062
  text,
1031
- systemPrompt,
1032
- permissions,
1033
- allowedTools,
1063
+ ...sendSystemPrompt ? { systemPrompt } : {},
1064
+ ...sendPermissions ? { permissions } : {},
1065
+ ...sendAllowedTools ? { allowedTools } : {},
1034
1066
  listenOnly,
1035
1067
  skipGraft: skipGraft || void 0,
1036
1068
  ocServerUrl: self.config.pluginInput?.serverUrl?.toString(),
1037
- priorPetals,
1069
+ ...elidePriorPetals ? {} : { priorPetals },
1038
1070
  externalTools: externalTools.length > 0 ? externalTools : void 0,
1039
1071
  mcpServerConfigs: await getMcpServerConfigs(this.config.client),
1040
1072
  visibleTools: allToolNames,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@clwnd/opencode",
3
- "version": "0.14.0",
3
+ "version": "0.15.1",
4
4
  "description": "clwnd for opencode",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",