@qwen-code/arena-agent 0.0.10-dev.1 → 0.0.10-dev.10

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 (154) hide show
  1. package/.env.example +57 -14
  2. package/CHANGELOG.md +228 -0
  3. package/README.md +228 -50
  4. package/dist/agent.d.ts +28 -2
  5. package/dist/agent.js +341 -106
  6. package/dist/agent.js.map +1 -1
  7. package/dist/anthropic.js +23 -22
  8. package/dist/anthropic.js.map +1 -1
  9. package/dist/ask-user.js +2 -0
  10. package/dist/ask-user.js.map +1 -1
  11. package/dist/attachments.js +4 -3
  12. package/dist/attachments.js.map +1 -1
  13. package/dist/brave-search.js +1 -3
  14. package/dist/brave-search.js.map +1 -1
  15. package/dist/canonical-data.js +2 -2
  16. package/dist/canonical-data.js.map +1 -1
  17. package/dist/cli.js +184 -36
  18. package/dist/cli.js.map +1 -1
  19. package/dist/code-tools.d.ts +8 -2
  20. package/dist/code-tools.js +709 -117
  21. package/dist/code-tools.js.map +1 -1
  22. package/dist/compaction.d.ts +49 -3
  23. package/dist/compaction.js +382 -186
  24. package/dist/compaction.js.map +1 -1
  25. package/dist/config.d.ts +17 -2
  26. package/dist/config.js +47 -5
  27. package/dist/config.js.map +1 -1
  28. package/dist/fetch-page.js +9 -33
  29. package/dist/fetch-page.js.map +1 -1
  30. package/dist/file-edit.d.ts +8 -0
  31. package/dist/file-edit.js +63 -0
  32. package/dist/file-edit.js.map +1 -0
  33. package/dist/history.d.ts +16 -3
  34. package/dist/history.js +117 -19
  35. package/dist/history.js.map +1 -1
  36. package/dist/legacy-compaction.d.ts +20 -0
  37. package/dist/legacy-compaction.js +209 -0
  38. package/dist/legacy-compaction.js.map +1 -0
  39. package/dist/midturn-checkpoint-hook.d.ts +31 -0
  40. package/dist/midturn-checkpoint-hook.js +38 -0
  41. package/dist/midturn-checkpoint-hook.js.map +1 -0
  42. package/dist/mock.js +5 -0
  43. package/dist/mock.js.map +1 -1
  44. package/dist/mode.js +4 -2
  45. package/dist/mode.js.map +1 -1
  46. package/dist/model-router-media.d.ts +1 -0
  47. package/dist/model-router-media.js +71 -1
  48. package/dist/model-router-media.js.map +1 -1
  49. package/dist/openai-responses.js +2 -0
  50. package/dist/openai-responses.js.map +1 -1
  51. package/dist/process-manager.js +2 -1
  52. package/dist/process-manager.js.map +1 -1
  53. package/dist/prompts.d.ts +2 -0
  54. package/dist/prompts.js +6 -2
  55. package/dist/prompts.js.map +1 -1
  56. package/dist/protocol.d.ts +5 -1
  57. package/dist/protocol.js +24 -2
  58. package/dist/protocol.js.map +1 -1
  59. package/dist/provider.d.ts +12 -5
  60. package/dist/provider.js +60 -52
  61. package/dist/provider.js.map +1 -1
  62. package/dist/repetitive-output.d.ts +12 -0
  63. package/dist/repetitive-output.js +80 -0
  64. package/dist/repetitive-output.js.map +1 -0
  65. package/dist/replay-responses.d.ts +17 -0
  66. package/dist/replay-responses.js +100 -0
  67. package/dist/replay-responses.js.map +1 -0
  68. package/dist/routify-web-fetch.js +20 -7
  69. package/dist/routify-web-fetch.js.map +1 -1
  70. package/dist/sandbox-file-write.d.ts +10 -0
  71. package/dist/sandbox-file-write.js +58 -0
  72. package/dist/sandbox-file-write.js.map +1 -0
  73. package/dist/server.js +17 -5
  74. package/dist/server.js.map +1 -1
  75. package/dist/session-memory-prompts.d.ts +5 -0
  76. package/dist/session-memory-prompts.js +7 -0
  77. package/dist/session-memory-prompts.js.map +1 -0
  78. package/dist/snapshot-client.d.ts +10 -0
  79. package/dist/snapshot-client.js +39 -0
  80. package/dist/snapshot-client.js.map +1 -0
  81. package/dist/spec.js +18 -10
  82. package/dist/spec.js.map +1 -1
  83. package/dist/speech-audio.d.ts +9 -0
  84. package/dist/speech-audio.js +130 -0
  85. package/dist/speech-audio.js.map +1 -0
  86. package/dist/speech-model.d.ts +3 -0
  87. package/dist/speech-model.js +8 -0
  88. package/dist/speech-model.js.map +1 -0
  89. package/dist/tools.d.ts +5 -0
  90. package/dist/tools.js +378 -132
  91. package/dist/tools.js.map +1 -1
  92. package/dist/tui.js +13 -10
  93. package/dist/tui.js.map +1 -1
  94. package/dist/types.d.ts +28 -3
  95. package/dist/voice-registry.d.ts +2 -0
  96. package/dist/voice-registry.js +10 -2
  97. package/dist/voice-registry.js.map +1 -1
  98. package/dist/web-fetch-output.d.ts +9 -0
  99. package/dist/web-fetch-output.js +38 -0
  100. package/dist/web-fetch-output.js.map +1 -0
  101. package/dist/workspace.d.ts +2 -0
  102. package/dist/workspace.js +11 -6
  103. package/dist/workspace.js.map +1 -1
  104. package/docs/BINARY_DISTRIBUTION.md +27 -16
  105. package/docs/MODES_AND_RELEASES.md +28 -5
  106. package/docs/SDK.md +5 -0
  107. package/modes/code-arena/capture-provenance.json +57 -0
  108. package/modes/code-arena/full-stack/system-prompt.txt +1 -1
  109. package/modes/code-arena/full-stack/template/eslint.config.mjs +3 -4
  110. package/modes/code-arena/full-stack/template/postcss.config.mjs +2 -2
  111. package/modes/code-arena/full-stack/tools.json +186 -186
  112. package/modes/code-arena/html/system-prompt.txt +1 -1
  113. package/modes/code-arena/html/tools.json +123 -123
  114. package/modes/code-arena/react/system-prompt.txt +4 -3
  115. package/modes/code-arena/react/template/package.json +4 -4
  116. package/modes/code-arena/react/template/src/App.tsx +1 -1
  117. package/modes/code-arena/react/template/src/main.tsx +1 -1
  118. package/modes/code-arena/react/template/tsconfig.json +6 -0
  119. package/modes/code-arena/react/template/vite.config.ts +1 -0
  120. package/modes/code-arena/react/tools.json +178 -184
  121. package/package.json +14 -4
  122. package/scripts/README.md +62 -0
  123. package/scripts/check-changelog.mjs +66 -0
  124. package/vendor/audio/darwin-arm64/FFmpeg.LICENSE +502 -0
  125. package/vendor/audio/darwin-arm64/LAME.LICENSE +481 -0
  126. package/vendor/audio/darwin-arm64/Opus.LICENSE +44 -0
  127. package/vendor/audio/darwin-arm64/ffmpeg.gz +0 -0
  128. package/vendor/audio/darwin-arm64/manifest.json +39 -0
  129. package/vendor/audio/darwin-x64/FFmpeg.LICENSE +502 -0
  130. package/vendor/audio/darwin-x64/LAME.LICENSE +481 -0
  131. package/vendor/audio/darwin-x64/Opus.LICENSE +44 -0
  132. package/vendor/audio/darwin-x64/ffmpeg.gz +0 -0
  133. package/vendor/audio/darwin-x64/manifest.json +39 -0
  134. package/vendor/audio/linux-arm64/FFmpeg.LICENSE +502 -0
  135. package/vendor/audio/linux-arm64/LAME.LICENSE +481 -0
  136. package/vendor/audio/linux-arm64/Opus.LICENSE +44 -0
  137. package/vendor/audio/linux-arm64/ffmpeg.gz +0 -0
  138. package/vendor/audio/linux-arm64/manifest.json +39 -0
  139. package/vendor/audio/linux-x64/FFmpeg.LICENSE +502 -0
  140. package/vendor/audio/linux-x64/LAME.LICENSE +481 -0
  141. package/vendor/audio/linux-x64/Opus.LICENSE +44 -0
  142. package/vendor/audio/linux-x64/ffmpeg.gz +0 -0
  143. package/vendor/audio/linux-x64/manifest.json +39 -0
  144. package/vendor/audio/sources/build-audio-encoder.sh +76 -0
  145. package/vendor/audio/sources/ffmpeg-7.0.2.tar.xz +0 -0
  146. package/vendor/audio/sources/lame-3.100.tar.gz +0 -0
  147. package/vendor/audio/sources/opus-1.5.2.tar.gz +0 -0
  148. package/vendor/audio/sources/pkgconf-2.3.0.tar.xz +0 -0
  149. package/vendor/audio/sources/sources.lock.json +30 -0
  150. package/vendor/audio/win32-x64/FFmpeg.LICENSE +502 -0
  151. package/vendor/audio/win32-x64/LAME.LICENSE +481 -0
  152. package/vendor/audio/win32-x64/Opus.LICENSE +44 -0
  153. package/vendor/audio/win32-x64/ffmpeg.gz +0 -0
  154. package/vendor/audio/win32-x64/manifest.json +39 -0
@@ -0,0 +1,100 @@
1
+ import { readFileSync } from "node:fs";
2
+ // Nondeterministic network/media tools across both arenas. generate_image and
3
+ // generate_speech write files, but their side effects are reproduced through
4
+ // recorded artifacts, so they replay safely.
5
+ const REPLAYABLE_TOOLS = new Set([
6
+ "fetch_media",
7
+ "fetch_page",
8
+ "generate_image",
9
+ "generate_speech",
10
+ "image_search",
11
+ "web_fetch",
12
+ "web_search",
13
+ ]);
14
+ let cached;
15
+ let cachedSource;
16
+ let stats = { served: 0, missed: [] };
17
+ function stableStringify(value) {
18
+ if (Array.isArray(value)) {
19
+ return `[${value.map(stableStringify).join(",")}]`;
20
+ }
21
+ if (value !== null && typeof value === "object") {
22
+ const entries = Object.entries(value)
23
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
24
+ .map(([key, item]) => `${JSON.stringify(key)}:${stableStringify(item)}`);
25
+ return `{${entries.join(",")}}`;
26
+ }
27
+ return JSON.stringify(value);
28
+ }
29
+ function loadReplayResponses() {
30
+ const file = process.env.CODE_HARNESS_REPLAY_RESPONSES;
31
+ if (cached !== undefined && cachedSource === file)
32
+ return cached;
33
+ cachedSource = file;
34
+ cached = null;
35
+ stats = { served: 0, missed: [] };
36
+ if (file) {
37
+ try {
38
+ const parsed = JSON.parse(readFileSync(file, "utf8"));
39
+ const map = new Map();
40
+ const nonReplayable = new Set();
41
+ for (const entry of parsed.entries ?? []) {
42
+ if (!REPLAYABLE_TOOLS.has(entry.tool)) {
43
+ nonReplayable.add(entry.tool);
44
+ continue;
45
+ }
46
+ const key = `${entry.tool}|${stableStringify(entry.arguments)}`;
47
+ const queue = map.get(key);
48
+ if (queue)
49
+ queue.push(entry);
50
+ else
51
+ map.set(key, [entry]);
52
+ }
53
+ if (nonReplayable.size) {
54
+ console.error(`[replay-responses] ignoring recorded entries for non-replayable tool(s): ${[...nonReplayable].sort().join(", ")}`);
55
+ }
56
+ cached = map;
57
+ }
58
+ catch {
59
+ cached = null;
60
+ }
61
+ }
62
+ return cached;
63
+ }
64
+ export function replayResponseFor(tool, args) {
65
+ const map = loadReplayResponses();
66
+ if (!map)
67
+ return undefined;
68
+ if (!REPLAYABLE_TOOLS.has(tool))
69
+ return undefined;
70
+ const argumentsKey = stableStringify(args);
71
+ // Repeated calls with identical arguments consume recorded entries in
72
+ // source order.
73
+ const queue = map.get(`${tool}|${argumentsKey}`);
74
+ if (!queue || !queue.length) {
75
+ stats.missed.push({ tool, arguments: argumentsKey });
76
+ console.error(`[replay-responses] no recorded response for ${tool} ${argumentsKey}; falling through to live execution`);
77
+ return undefined;
78
+ }
79
+ const entry = queue.shift();
80
+ stats.served += 1;
81
+ return { found: true, output: entry.output, artifacts: entry.artifacts };
82
+ }
83
+ // Hit/miss counters for the current recording. Reset whenever a different
84
+ // recording file is loaded.
85
+ export function replayResponseStats() {
86
+ return { served: stats.served, missed: [...stats.missed] };
87
+ }
88
+ // With replay mode on from process start, emit a one-line hit-rate summary at
89
+ // exit so replay drivers can flag recordings that partially fell through to
90
+ // live execution.
91
+ if (process.env.CODE_HARNESS_REPLAY_RESPONSES) {
92
+ process.once("exit", () => {
93
+ const total = stats.served + stats.missed.length;
94
+ if (total === 0)
95
+ return;
96
+ const rate = Math.round((stats.served / total) * 100);
97
+ console.error(`[replay-responses] replay summary: served=${stats.served} missed=${stats.missed.length} hit-rate=${rate}%`);
98
+ });
99
+ }
100
+ //# sourceMappingURL=replay-responses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"replay-responses.js","sourceRoot":"","sources":["../src/replay-responses.ts"],"names":[],"mappings":"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"}
@@ -1,3 +1,4 @@
1
+ import { parseHTML } from "linkedom";
1
2
  import { splitMarkdown } from "./fetch-page.js";
2
3
  function record(value) {
3
4
  return value !== null && typeof value === "object" && !Array.isArray(value)
@@ -46,9 +47,18 @@ const maxFetchPageCacheEntries = 16;
46
47
  export function routifyWebFetchEnabled(value = process.env.CODE_HARNESS_ROUTIFY_WEB_FETCH_ENABLED) {
47
48
  return ["1", "true", "yes", "on"].includes(value?.trim().toLowerCase() || "");
48
49
  }
50
+ function htmlToText(html) {
51
+ // Firecrawl accepts html, not text. Handle both fragments and full documents;
52
+ // innerText preserves block/line breaks and the parser decodes HTML entities.
53
+ const { document } = parseHTML(`<html><body>${html}</body></html>`);
54
+ for (const element of document.querySelectorAll("head, title, script, style, noscript, template")) {
55
+ element.remove();
56
+ }
57
+ return document.body.innerText.trim();
58
+ }
49
59
  async function firecrawl(url, format, options) {
50
60
  const fetchImpl = options.fetchImpl || globalThis.fetch;
51
- const requestedFormat = format;
61
+ const requestedFormat = format === "text" ? "html" : format;
52
62
  const response = await fetchImpl(routifyReadPageUrl, {
53
63
  method: "POST",
54
64
  headers: {
@@ -79,7 +89,7 @@ async function firecrawl(url, format, options) {
79
89
  }
80
90
  return {
81
91
  title: stringValue(metadata.title) || "No Title Found",
82
- content,
92
+ content: format === "text" ? htmlToText(content) : content,
83
93
  };
84
94
  }
85
95
  async function jinaReader(url, format, options) {
@@ -107,12 +117,16 @@ async function jinaReader(url, format, options) {
107
117
  throw new Error(`Jina Reader returned code ${String(payload.code || "unknown")}`);
108
118
  }
109
119
  const data = record(payload.data);
110
- if (typeof data.content !== "string") {
120
+ // Jina uses text/html fields for those formats; some gateways normalize all
121
+ // formats into content. Markdown continues to use content.
122
+ const field = format === "markdown" ? "content" : format;
123
+ const content = typeof data[field] === "string" ? data[field] : data.content;
124
+ if (typeof content !== "string") {
111
125
  throw new Error("Jina Reader response is missing content");
112
126
  }
113
127
  return {
114
128
  title: stringValue(data.title) || "No Title Found",
115
- content: data.content,
129
+ content,
116
130
  };
117
131
  }
118
132
  export async function executeRoutifyWebFetch(url, format, options = {}) {
@@ -171,9 +185,8 @@ export class RoutifyFetchPageReader {
171
185
  }
172
186
  this.cache.set(cacheKey, page);
173
187
  }
174
- if (chunkIndex >= page.chunks.length) {
175
- throw new Error("chunkIndex is past the end of the page");
176
- }
188
+ // Captures clamp a stale/out-of-range page request to the final page.
189
+ chunkIndex = Math.min(chunkIndex, page.chunks.length - 1);
177
190
  return {
178
191
  url,
179
192
  title: page.title,
@@ -1 +1 @@
1
- {"version":3,"file":"routify-web-fetch.js","sourceRoot":"","sources":["../src/routify-web-fetch.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"routify-web-fetch.js","sourceRoot":"","sources":["../src/routify-web-fetch.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAErC,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAEhD,SAAS,MAAM,CAAC,KAAc;IAC5B,OAAO,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACzE,CAAC,CAAE,KAAiC;QACpC,CAAC,CAAC,EAAE,CAAC;AACT,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;AAChD,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,MAAM;IACb,MAAM,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,IAAI,EAAE,CAAC;IAClD,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB,CAAC,KAAa;IACxC,OAAO,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,KAAK,EAAE,CAAC;AAC/D,CAAC;AAED,SAAS,cAAc,CAAC,OAAe;IACrC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAC5C,OAAO,CACL,WAAW,CAAC,OAAO,CAAC,OAAO,CAAC;YAC5B,WAAW,CAAC,OAAO,CAAC,aAAa,CAAC;YAClC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC;YAC1C,OAAO,CACR,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,SAAS,SAAS,CAAC,OAAe,EAAE,QAAgB;IAClD,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,GAAG,QAAQ,0BAA0B,CAAC,CAAC;IACzD,CAAC;AACH,CAAC;AAED,MAAM,kBAAkB,GACtB,2DAA2D,CAAC;AAC9D,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACjC,MAAM,wBAAwB,GAAG,EAAE,CAAC;AAcpC,MAAM,UAAU,sBAAsB,CACpC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,sCAAsC;IAE1D,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC,QAAQ,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC;AAChF,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,8EAA8E;IAC9E,8EAA8E;IAC9E,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAC,eAAe,IAAI,gBAAgB,CAAC,CAAC;IACpE,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,gBAAgB,CAC7C,gDAAgD,CACjD,EAAE,CAAC;QACF,OAAO,CAAC,MAAM,EAAE,CAAC;IACnB,CAAC;IACD,OAAO,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;AACxC,CAAC;AAED,KAAK,UAAU,SAAS,CACtB,GAAW,EACX,MAAsB,EACtB,OAA+B;IAE/B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC;IACxD,MAAM,eAAe,GAAG,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAC5D,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,kBAAkB,EAAE;QACnD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,aAAa,EAAE,mBAAmB,CAAC,MAAM,EAAE,CAAC;YAC5C,cAAc,EAAE,kBAAkB;SACnC;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,KAAK,EAAE,0BAA0B;YACjC,GAAG;YACH,OAAO,EAAE,CAAC,eAAe,CAAC;YAC1B,eAAe,EAAE,IAAI;SACtB,CAAC;QACF,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACtC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,qBAAqB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAC1G,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;IAChD,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI,EAAE,CAAC;QAC7B,MAAM,IAAI,KAAK,CAAC,6CAA6C,CAAC,CAAC;IACjE,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC;IACnD,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC,eAAe,IAAI,IAAI,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,iCAAiC,eAAe,UAAU,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO;QACL,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,gBAAgB;QACtD,OAAO,EAAE,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO;KAC3D,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,UAAU,CACvB,GAAW,EACX,MAAsB,EACtB,OAA+B;IAE/B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC;IACxD,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,kBAAkB,EAAE;QACnD,MAAM,EAAE,MAAM;QACd,OAAO,EAAE;YACP,MAAM,EAAE,kBAAkB;YAC1B,aAAa,EAAE,mBAAmB,CAAC,MAAM,EAAE,CAAC;YAC5C,cAAc,EAAE,kBAAkB;YAClC,gBAAgB,EAAE,MAAM;SACzB;QACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;YACnB,KAAK,EAAE,qBAAqB;YAC5B,GAAG;SACJ,CAAC;QACF,MAAM,EAAE,OAAO,CAAC,MAAM;KACvB,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;IACtC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CACb,uBAAuB,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAC5G,CAAC;IACJ,CAAC;IACD,MAAM,OAAO,GAAG,SAAS,CAAC,OAAO,EAAE,aAAa,CAAC,CAAC;IAClD,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CACb,6BAA6B,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,SAAS,CAAC,EAAE,CACjE,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IAClC,4EAA4E;IAC5E,2DAA2D;IAC3D,MAAM,KAAK,GAAG,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC;IACzD,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC;IAC7E,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,yCAAyC,CAAC,CAAC;IAC7D,CAAC;IACD,OAAO;QACL,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,gBAAgB;QAClD,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,GAAW,EACX,MAAsB,EACtB,OAAO,GAA2B,EAAE;IAEpC,IAAI,gBAAwB,CAAC;IAC7B,IAAI,CAAC;QACH,OAAO,MAAM,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,gBAAgB,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;IACzC,CAAC;IAED,IAAI,CAAC;QACH,OAAO,MAAM,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CACb,8BAA8B,gBAAgB,KAAK,YAAY,CAAC,KAAK,CAAC,EAAE,CACzE,CAAC;IACJ,CAAC;AACH,CAAC;AAOD,SAAS,iBAAiB,CAAC,KAAa;IACtC,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IACvB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,oCAAoC,KAAK,EAAE,CAAC,CAAC;IAC/D,CAAC;IACD,IAAI,CAAC,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAC;IAClE,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,KAAK,CAAC,+CAA+C,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,GAAG,CAAC,IAAI,CAAC;AAClB,CAAC;AAED,MAAM,OAAO,sBAAsB;IAGJ,OAAO;IAFnB,KAAK,GAAG,IAAI,GAAG,EAA2B,CAAC;IAE5D,YAA6B,OAAO,GAA2B,EAAE;uBAApC,OAAO;IAAgC,CAAC;IAErE,KAAK,CAAC,IAAI,CAAC,GAAW,EAAE,UAAkB;QACxC,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,UAAU,CAAC,IAAI,UAAU,GAAG,CAAC,EAAE,CAAC;YACxD,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;QACpE,CAAC;QACD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;QACxC,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,MAAM,GAAG,MAAM,sBAAsB,CAAC,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3E,IAAI,GAAG;gBACL,KAAK,EAAE,MAAM,CAAC,KAAK,KAAK,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK;gBAC5D,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,OAAO,EAAE,kBAAkB,CAAC;aAC1D,CAAC;YACF,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,IAAI,wBAAwB,EAAE,CAAC;gBAChD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;gBAC9C,IAAI,MAAM;oBAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YACxC,CAAC;YACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACjC,CAAC;QACD,sEAAsE;QACtE,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAC1D,OAAO;YACL,GAAG;YACH,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,MAAM,EAAE,SAAS;YACjB,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE;YACtC,OAAO,EAAE,UAAU,GAAG,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM;YAC5C,UAAU;YACV,WAAW,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;SAChC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ /** Explicit opt-in for the disposable Docker replay environment, never host paths. */
2
+ export declare function privilegedFileCreationEnabled(input: {
3
+ platform: string;
4
+ workspace: string;
5
+ docker: boolean;
6
+ flag?: string;
7
+ uid?: number;
8
+ }): boolean;
9
+ /** Creates only a missing file in an existing directory; no privilege for edits. */
10
+ export declare function createSandboxFile(target: string, content: string): Promise<void>;
@@ -0,0 +1,58 @@
1
+ import { spawn } from "node:child_process";
2
+ /** Explicit opt-in for the disposable Docker replay environment, never host paths. */
3
+ export function privilegedFileCreationEnabled(input) {
4
+ return input.flag === "1" && input.platform === "linux" && input.docker &&
5
+ input.workspace === "/home/user" && Number.isInteger(input.uid) && input.uid > 0;
6
+ }
7
+ // Run only as a child of an explicitly enabled sandbox. No shell, user modules,
8
+ // NODE_OPTIONS, or arbitrary executable paths are accepted. Existing files are
9
+ // NEVER opened for privileged overwrite, including symlinks and hard links.
10
+ const createNewFileProgram = String.raw `
11
+ const fs = require('node:fs'), path = require('node:path');
12
+ let input = '';
13
+ process.stdin.setEncoding('utf8');
14
+ process.stdin.on('data', chunk => input += chunk);
15
+ process.stdin.on('end', () => {
16
+ let directory, file;
17
+ try {
18
+ const x = JSON.parse(input);
19
+ if (!Number.isInteger(x.uid) || x.uid <= 0 || !Number.isInteger(x.gid) || x.gid < 0 ||
20
+ !Number.isInteger(x.mode) || x.mode < 0 || (x.mode & ~0o666) !== 0 ||
21
+ typeof x.content !== 'string' || typeof x.target !== 'string' ||
22
+ !path.isAbsolute(x.target) || path.normalize(x.target) !== x.target || x.target === '/') throw Error('invalid request');
23
+ const parent = path.dirname(x.target);
24
+ if (fs.realpathSync(parent) !== parent) throw Error('symlink parent');
25
+ directory = fs.openSync(parent, fs.constants.O_RDONLY | fs.constants.O_DIRECTORY | fs.constants.O_NOFOLLOW);
26
+ const target = '/proc/self/fd/' + directory + '/' + path.basename(x.target);
27
+ file = fs.openSync(target, fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL | fs.constants.O_NOFOLLOW, 0o600);
28
+ fs.writeFileSync(file, x.content, 'utf8');
29
+ fs.fchownSync(file, x.uid, x.gid);
30
+ fs.fchmodSync(file, x.mode);
31
+ } catch (error) {
32
+ process.stderr.write(String(error.code || error.message));
33
+ process.exitCode = 1;
34
+ } finally {
35
+ if (file !== undefined) fs.closeSync(file);
36
+ if (directory !== undefined) fs.closeSync(directory);
37
+ }
38
+ });
39
+ `;
40
+ /** Creates only a missing file in an existing directory; no privilege for edits. */
41
+ export async function createSandboxFile(target, content) {
42
+ const uid = process.getuid?.(), gid = process.getgid?.();
43
+ if (!uid || gid === undefined)
44
+ throw new Error("requires unprivileged sandbox user");
45
+ await new Promise((resolve, reject) => {
46
+ const child = spawn("/usr/bin/sudo", ["-n", "--", "/usr/bin/node", "-e", createNewFileProgram], {
47
+ env: { PATH: "/usr/bin:/bin", LANG: "C" }, stdio: ["pipe", "ignore", "pipe"],
48
+ });
49
+ let error = "";
50
+ child.stderr.on("data", chunk => { error = (error + chunk).slice(-1024); });
51
+ const timer = setTimeout(() => child.kill("SIGKILL"), 10_000);
52
+ child.on("error", err => { clearTimeout(timer); reject(err); });
53
+ child.on("close", code => { clearTimeout(timer); code === 0 ? resolve() : reject(new Error(error || "sandbox file creation failed")); });
54
+ child.stdin.on("error", reject);
55
+ child.stdin.end(JSON.stringify({ target, content, uid, gid, mode: 0o666 & ~process.umask() }));
56
+ });
57
+ }
58
+ //# sourceMappingURL=sandbox-file-write.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sandbox-file-write.js","sourceRoot":"","sources":["../src/sandbox-file-write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAE3C,sFAAsF;AACtF,MAAM,UAAU,6BAA6B,CAAC,KAE7C;IACC,OAAO,KAAK,CAAC,IAAI,KAAK,GAAG,IAAI,KAAK,CAAC,QAAQ,KAAK,OAAO,IAAI,KAAK,CAAC,MAAM;QACrE,KAAK,CAAC,SAAS,KAAK,YAAY,IAAI,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,KAAK,CAAC,GAAI,GAAG,CAAC,CAAC;AACtF,CAAC;AAED,gFAAgF;AAChF,+EAA+E;AAC/E,4EAA4E;AAC5E,MAAM,oBAAoB,GAAG,MAAM,CAAC,GAAG,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BtC,CAAC;AAEF,oFAAoF;AACpF,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAAc,EAAE,OAAe;IACrE,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,EAAE,GAAG,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IACzD,IAAI,CAAC,GAAG,IAAI,GAAG,KAAK,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC;IACrF,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,KAAK,GAAG,KAAK,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,oBAAoB,CAAC,EAAE;YAC9F,GAAG,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC;SAC7E,CAAC,CAAC;QACH,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,GAAG,KAAK,GAAG,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5E,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9D,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAChE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,EAAE,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,KAAK,IAAI,8BAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACzI,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAChC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,GAAG,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;IACjG,CAAC,CAAC,CAAC;AACL,CAAC"}
package/dist/server.js CHANGED
@@ -877,6 +877,13 @@ function createUiStream(session, messageId) {
877
877
  });
878
878
  return;
879
879
  }
880
+ if (event.type === "memory.update") {
881
+ emit(session, { type: "memory.update", status: event.status,
882
+ ...(event.code ? { code: event.code } : {}),
883
+ ...(event.error ? { error: event.error } : {}),
884
+ ...(event.usage ? { usage: event.usage } : {}) });
885
+ return;
886
+ }
880
887
  if (event.type === "compaction") {
881
888
  emit(session, {
882
889
  type: "compaction",
@@ -1077,8 +1084,8 @@ function createUiStream(session, messageId) {
1077
1084
  async function readHistory(session) {
1078
1085
  return loadStoredHistory(sessionHistoryPath(session));
1079
1086
  }
1080
- async function saveHistory(session, messages, config, metrics, tools) {
1081
- await saveStoredHistory(sessionHistoryPath(session), messages, historyMetadata(config, session.id), metrics, tools);
1087
+ async function saveHistory(session, messages, config, metrics, tools, memory) {
1088
+ await saveStoredHistory(sessionHistoryPath(session), messages, historyMetadata(config, session.id), metrics, tools, memory);
1082
1089
  }
1083
1090
  function sessionMetricsAnalyzer(config, signal) {
1084
1091
  const sideQueryModel = config.metricsSideQueryModel || config.model;
@@ -1163,6 +1170,7 @@ async function runAgent(context, session, prompt, messageId, controller, interru
1163
1170
  const storedHistory = await loadStoredHistoryState(sessionHistoryPath(session));
1164
1171
  const history = storedHistory?.messages;
1165
1172
  const historyWriter = await IncrementalHistoryWriter.create(sessionHistoryPath(session), storedHistory, historyMetadata(sessionConfig, session.id));
1173
+ session.sessionMemory ||= {};
1166
1174
  let latestTools = storedHistory?.tools;
1167
1175
  const result = await new Agent(sessionConfig, sink, {
1168
1176
  askUserHandler,
@@ -1170,9 +1178,11 @@ async function runAgent(context, session, prompt, messageId, controller, interru
1170
1178
  sessionAffinityId: session.sessionAffinityId,
1171
1179
  signal: controller.signal,
1172
1180
  reuseHistoryMessages: true,
1173
- onCheckpoint: (messages, tools) => {
1181
+ sessionMemory: (session.sessionMemory ||= {}),
1182
+ storedSessionMemory: storedHistory?.session_memory,
1183
+ onCheckpoint: (messages, tools, memory) => {
1174
1184
  latestTools = [...tools];
1175
- return historyWriter.checkpoint(messages, tools);
1185
+ return historyWriter.checkpoint(messages, tools, memory);
1176
1186
  },
1177
1187
  onModelFailure: (messages, error) => {
1178
1188
  failedModelCheckpoint = structuredClone([...messages]);
@@ -1187,6 +1197,7 @@ async function runAgent(context, session, prompt, messageId, controller, interru
1187
1197
  interrupted: interruptionGeneration !== undefined,
1188
1198
  userMessage,
1189
1199
  resumeFromHistory,
1200
+ restoreSessionMemory: sessionConfig.restoreSessionMemory,
1190
1201
  });
1191
1202
  let deliveredResult = result;
1192
1203
  let retryable = false;
@@ -1559,7 +1570,8 @@ async function undoLastTurn(config, request, response, session) {
1559
1570
  const checkpointMessages = checkpointHistory?.messages || [];
1560
1571
  const checkpointMetrics = checkpointHistory?.metrics ?? null;
1561
1572
  await restoreUndoWorkspace(session);
1562
- await saveHistory(session, checkpointMessages, config, checkpointMetrics, checkpointHistory?.tools);
1573
+ await saveHistory(session, checkpointMessages, config, checkpointMetrics, checkpointHistory?.tools, checkpointHistory?.session_memory ?? null);
1574
+ session.sessionMemory = {};
1563
1575
  await clearModelRetry(session);
1564
1576
  session.pendingInterruption = false;
1565
1577
  session.activePrompt = null;