@qwen-code/arena-agent 0.0.10-dev.1 → 0.0.10-dev.11
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/.env.example +68 -14
- package/CHANGELOG.md +245 -0
- package/README.md +307 -57
- package/dist/agent.d.ts +28 -2
- package/dist/agent.js +389 -109
- package/dist/agent.js.map +1 -1
- package/dist/anthropic.js +32 -35
- package/dist/anthropic.js.map +1 -1
- package/dist/ask-user.js +2 -0
- package/dist/ask-user.js.map +1 -1
- package/dist/attachments.js +4 -3
- package/dist/attachments.js.map +1 -1
- package/dist/brave-search.js +1 -3
- package/dist/brave-search.js.map +1 -1
- package/dist/canonical-data.d.ts +2 -0
- package/dist/canonical-data.js +4 -2
- package/dist/canonical-data.js.map +1 -1
- package/dist/cli.js +184 -36
- package/dist/cli.js.map +1 -1
- package/dist/code-tools.d.ts +8 -2
- package/dist/code-tools.js +709 -117
- package/dist/code-tools.js.map +1 -1
- package/dist/compaction.d.ts +50 -3
- package/dist/compaction.js +390 -185
- package/dist/compaction.js.map +1 -1
- package/dist/config.d.ts +23 -2
- package/dist/config.js +52 -5
- package/dist/config.js.map +1 -1
- package/dist/connector-mcp.d.ts +47 -0
- package/dist/connector-mcp.js +314 -0
- package/dist/connector-mcp.js.map +1 -0
- package/dist/connectors.d.ts +8 -0
- package/dist/connectors.js +57 -0
- package/dist/connectors.js.map +1 -0
- package/dist/fetch-page.js +9 -33
- package/dist/fetch-page.js.map +1 -1
- package/dist/file-edit.d.ts +8 -0
- package/dist/file-edit.js +63 -0
- package/dist/file-edit.js.map +1 -0
- package/dist/history.d.ts +16 -3
- package/dist/history.js +117 -19
- package/dist/history.js.map +1 -1
- package/dist/midturn-checkpoint-hook.d.ts +44 -0
- package/dist/midturn-checkpoint-hook.js +38 -0
- package/dist/midturn-checkpoint-hook.js.map +1 -0
- package/dist/mock.js +5 -0
- package/dist/mock.js.map +1 -1
- package/dist/mode.js +4 -2
- package/dist/mode.js.map +1 -1
- package/dist/model-router-media.d.ts +1 -0
- package/dist/model-router-media.js +121 -1
- package/dist/model-router-media.js.map +1 -1
- package/dist/openai-responses.js +2 -0
- package/dist/openai-responses.js.map +1 -1
- package/dist/process-manager.js +2 -1
- package/dist/process-manager.js.map +1 -1
- package/dist/prompts.d.ts +2 -1
- package/dist/prompts.js +15 -37
- package/dist/prompts.js.map +1 -1
- package/dist/protocol.d.ts +5 -1
- package/dist/protocol.js +24 -2
- package/dist/protocol.js.map +1 -1
- package/dist/provider.d.ts +12 -5
- package/dist/provider.js +63 -52
- package/dist/provider.js.map +1 -1
- package/dist/repetitive-output.d.ts +12 -0
- package/dist/repetitive-output.js +80 -0
- package/dist/repetitive-output.js.map +1 -0
- package/dist/replay-responses.d.ts +17 -0
- package/dist/replay-responses.js +100 -0
- package/dist/replay-responses.js.map +1 -0
- package/dist/routify-web-fetch.js +20 -7
- package/dist/routify-web-fetch.js.map +1 -1
- package/dist/sandbox-file-write.d.ts +10 -0
- package/dist/sandbox-file-write.js +58 -0
- package/dist/sandbox-file-write.js.map +1 -0
- package/dist/server.js +17 -5
- package/dist/server.js.map +1 -1
- package/dist/session-memory-prompts.d.ts +5 -0
- package/dist/session-memory-prompts.js +7 -0
- package/dist/session-memory-prompts.js.map +1 -0
- package/dist/snapshot-client.d.ts +10 -0
- package/dist/snapshot-client.js +39 -0
- package/dist/snapshot-client.js.map +1 -0
- package/dist/spec.d.ts +5 -4
- package/dist/spec.js +31 -17
- package/dist/spec.js.map +1 -1
- package/dist/speech-audio.d.ts +9 -0
- package/dist/speech-audio.js +130 -0
- package/dist/speech-audio.js.map +1 -0
- package/dist/speech-model.d.ts +3 -0
- package/dist/speech-model.js +8 -0
- package/dist/speech-model.js.map +1 -0
- package/dist/summary-compaction.d.ts +21 -0
- package/dist/summary-compaction.js +211 -0
- package/dist/summary-compaction.js.map +1 -0
- package/dist/tools.d.ts +8 -1
- package/dist/tools.js +407 -135
- package/dist/tools.js.map +1 -1
- package/dist/tui.js +13 -10
- package/dist/tui.js.map +1 -1
- package/dist/types.d.ts +30 -3
- package/dist/voice-registry.d.ts +2 -0
- package/dist/voice-registry.js +10 -2
- package/dist/voice-registry.js.map +1 -1
- package/dist/web-fetch-output.d.ts +9 -0
- package/dist/web-fetch-output.js +38 -0
- package/dist/web-fetch-output.js.map +1 -0
- package/dist/workspace.d.ts +2 -0
- package/dist/workspace.js +11 -6
- package/dist/workspace.js.map +1 -1
- package/docs/BINARY_DISTRIBUTION.md +27 -16
- package/docs/MODES_AND_RELEASES.md +60 -6
- package/docs/SDK.md +5 -0
- package/modes/code-arena/capture-provenance.json +57 -0
- package/modes/code-arena/full-stack/system-prompt.txt +1 -1
- package/modes/code-arena/full-stack/template/eslint.config.mjs +3 -4
- package/modes/code-arena/full-stack/template/postcss.config.mjs +2 -2
- package/modes/code-arena/full-stack/tools.json +186 -186
- package/modes/code-arena/html/system-prompt.txt +1 -1
- package/modes/code-arena/html/tools.json +123 -123
- package/modes/code-arena/react/system-prompt.txt +4 -3
- package/modes/code-arena/react/template/package.json +4 -4
- package/modes/code-arena/react/template/src/App.tsx +1 -1
- package/modes/code-arena/react/template/src/main.tsx +1 -1
- package/modes/code-arena/react/template/tsconfig.json +6 -0
- package/modes/code-arena/react/template/vite.config.ts +1 -0
- package/modes/code-arena/react/tools.json +178 -184
- package/package.json +15 -4
- package/scripts/README.md +80 -0
- package/scripts/check-changelog.mjs +66 -0
- package/vendor/audio/darwin-arm64/FFmpeg.LICENSE +502 -0
- package/vendor/audio/darwin-arm64/LAME.LICENSE +481 -0
- package/vendor/audio/darwin-arm64/Opus.LICENSE +44 -0
- package/vendor/audio/darwin-arm64/ffmpeg.gz +0 -0
- package/vendor/audio/darwin-arm64/manifest.json +39 -0
- package/vendor/audio/darwin-x64/FFmpeg.LICENSE +502 -0
- package/vendor/audio/darwin-x64/LAME.LICENSE +481 -0
- package/vendor/audio/darwin-x64/Opus.LICENSE +44 -0
- package/vendor/audio/darwin-x64/ffmpeg.gz +0 -0
- package/vendor/audio/darwin-x64/manifest.json +39 -0
- package/vendor/audio/linux-arm64/FFmpeg.LICENSE +502 -0
- package/vendor/audio/linux-arm64/LAME.LICENSE +481 -0
- package/vendor/audio/linux-arm64/Opus.LICENSE +44 -0
- package/vendor/audio/linux-arm64/ffmpeg.gz +0 -0
- package/vendor/audio/linux-arm64/manifest.json +39 -0
- package/vendor/audio/linux-x64/FFmpeg.LICENSE +502 -0
- package/vendor/audio/linux-x64/LAME.LICENSE +481 -0
- package/vendor/audio/linux-x64/Opus.LICENSE +44 -0
- package/vendor/audio/linux-x64/ffmpeg.gz +0 -0
- package/vendor/audio/linux-x64/manifest.json +39 -0
- package/vendor/audio/sources/build-audio-encoder.sh +76 -0
- package/vendor/audio/sources/ffmpeg-7.0.2.tar.xz +0 -0
- package/vendor/audio/sources/lame-3.100.tar.gz +0 -0
- package/vendor/audio/sources/opus-1.5.2.tar.gz +0 -0
- package/vendor/audio/sources/pkgconf-2.3.0.tar.xz +0 -0
- package/vendor/audio/sources/sources.lock.json +30 -0
- package/vendor/audio/win32-x64/FFmpeg.LICENSE +502 -0
- package/vendor/audio/win32-x64/LAME.LICENSE +481 -0
- package/vendor/audio/win32-x64/Opus.LICENSE +44 -0
- package/vendor/audio/win32-x64/ffmpeg.gz +0 -0
- 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
|
-
|
|
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
|
|
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
|
-
|
|
175
|
-
|
|
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":"AAAA,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,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,CAAC;
|
|
1
|
+
{"version":3,"file":"routify-web-fetch.js","sourceRoot":"","sources":["../src/routify-web-fetch.ts"],"names":[],"mappings":"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"}
|
|
@@ -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
|
-
|
|
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;
|