@cjhyy/code-shell 0.1.0-alpha.1 → 0.1.0-alpha.3
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/README.md +8 -0
- package/dist/anthropic-P5VETAFI.cjs +10 -0
- package/dist/{anthropic-NENYS535.js → anthropic-W2GU3D76.js} +3 -2
- package/dist/arena/context/context-tools.d.ts +1 -1
- package/dist/arena/index.cjs +4 -4
- package/dist/arena/index.js +3 -3
- package/dist/arena/providers/index.d.ts +19 -3
- package/dist/arena/strategies/utils.d.ts +6 -1
- package/dist/arena/types.d.ts +10 -1
- package/dist/{arena-46QQ6BZQ.js → arena-ENHBHB2W.js} +5 -7
- package/dist/{arena-HZZZ2GJH.cjs → arena-HHDYYVHJ.cjs} +19 -21
- package/dist/{chunk-BE6IPRDM.js → chunk-2EUAE7AY.js} +1 -1
- package/dist/{chunk-WYKNZ54E.cjs → chunk-3CAZIWUA.cjs} +6 -6
- package/dist/{chunk-J5XW6UYL.js → chunk-5C5HIOML.js} +63 -4
- package/dist/chunk-75E4BBFC.js +224 -0
- package/dist/chunk-BF4LXLQV.cjs +4753 -0
- package/dist/{chunk-ZJV3YSY3.cjs → chunk-BUJ5KYCI.cjs} +53 -11
- package/dist/{chunk-BMH65OVB.cjs → chunk-C7C7ZZY4.cjs} +8 -8
- package/dist/{chunk-KO2FPF7G.js → chunk-F5BS3GUC.js} +20 -2
- package/dist/chunk-FPFTIKEJ.js +4753 -0
- package/dist/chunk-FV2ARONZ.cjs +224 -0
- package/dist/{chunk-DICG4AB7.cjs → chunk-GZBD6QRS.cjs} +42 -3
- package/dist/{chunk-FVP7XJGS.cjs → chunk-HOXQLX5R.cjs} +406 -196
- package/dist/{chunk-4PKZPFCD.js → chunk-I57ZD5IQ.js} +47 -14
- package/dist/{chunk-JUHRV2XF.js → chunk-ID6EJUHP.js} +1703 -438
- package/dist/chunk-JHNCK7JP.cjs +202 -0
- package/dist/{chunk-MOILS4WE.cjs → chunk-JHXNOB5G.cjs} +3 -3
- package/dist/{chunk-UK2SU23S.cjs → chunk-KOGV6PDQ.cjs} +20 -2
- package/dist/{chunk-VKGNCYRL.js → chunk-LMEKCQX4.js} +95 -13
- package/dist/{chunk-3EAEC566.cjs → chunk-M2QI5X3X.cjs} +51 -18
- package/dist/{chunk-YZ25SSWJ.js → chunk-M2SVOKC6.js} +46 -4
- package/dist/{chunk-NG73UR3L.cjs → chunk-OP57WUWQ.cjs} +23 -1
- package/dist/{chunk-ZXYDDJEJ.js → chunk-OUC2DFA7.js} +2 -2
- package/dist/{chunk-AP5F6VYE.js → chunk-REFCCVDM.js} +1 -1
- package/dist/{chunk-O6F2EF2Z.js → chunk-SCDKLTN3.js} +41 -2
- package/dist/{chunk-FECTK5KJ.js → chunk-SW3L7HIM.js} +1 -1
- package/dist/chunk-TDXBHD24.js +54 -0
- package/dist/chunk-VIPLU4RY.cjs +54 -0
- package/dist/{chunk-Q6BYFYGD.cjs → chunk-VWFET3MG.cjs} +1886 -621
- package/dist/{chunk-3EUDE77E.cjs → chunk-X2DNIMPC.cjs} +19 -19
- package/dist/{chunk-SQZHPD3S.js → chunk-Y7TSCDF6.js} +297 -87
- package/dist/{chunk-WHRTARDJ.cjs → chunk-YAFCN7ZW.cjs} +112 -30
- package/dist/{chunk-LRAY5IYC.cjs → chunk-YD7XTI7T.cjs} +65 -6
- package/dist/{chunk-S74VVJBF.js → chunk-ZLPJJZUW.js} +23 -1
- package/dist/chunk-ZRVPCXI7.js +202 -0
- package/dist/cli/commands/builtin/advanced-commands.d.ts +1 -1
- package/dist/cli/commands/builtin/extra-commands.d.ts +2 -2
- package/dist/cli/commands/builtin/more-commands.d.ts +1 -3
- package/dist/cli/commands/registry.d.ts +8 -0
- package/dist/cli/cost-tracker.d.ts +6 -0
- package/dist/cli/main.cjs +3556 -1995
- package/dist/cli/main.js +3658 -2097
- package/dist/cli/onboarding.d.ts +67 -14
- package/dist/client-base-TOVE25FA.js +9 -0
- package/dist/client-base-VDDIADAC.cjs +9 -0
- package/dist/compaction-D3KV2NWY.cjs +31 -0
- package/dist/{compaction-CCHWA4G6.js → compaction-YNWCEF7B.js} +1 -2
- package/dist/context/manager.d.ts +9 -0
- package/dist/data/openrouter-models.d.ts +35 -0
- package/dist/data/openrouter-sync.d.ts +16 -0
- package/dist/{devtools-KIY3LWQJ.js → devtools-IRQQPIRY.js} +1 -1
- package/dist/{devtools-LRP47DDV.cjs → devtools-WTC3NFNE.cjs} +1 -1
- package/dist/engine/engine.d.ts +29 -6
- package/dist/engine/turn-loop.d.ts +7 -0
- package/dist/engine/turn-state.d.ts +6 -0
- package/dist/index.cjs +19 -28
- package/dist/index.js +28 -37
- package/dist/llm/client-base.d.ts +7 -0
- package/dist/llm/model-pool.d.ts +4 -0
- package/dist/logging/logger.d.ts +69 -8
- package/dist/manager-FWLOVEEK.cjs +7 -0
- package/dist/manager-GEXJLOIS.js +7 -0
- package/dist/{mcp-manager-OKXHHWYR.js → mcp-manager-37GQLFGX.js} +2 -2
- package/dist/mcp-manager-U77NEXBY.cjs +8 -0
- package/dist/memory-ADGOWADP.cjs +9 -0
- package/dist/memory-EPFDBPII.js +9 -0
- package/dist/native-ts/yoga-layout/index.d.ts +2 -2
- package/dist/{openai-5HQGBL4L.js → openai-RXU5URYI.js} +3 -2
- package/dist/openai-SQW4H2K4.cjs +10 -0
- package/dist/openrouter-models-2FM3H4SQ.js +15 -0
- package/dist/openrouter-models-PLCWZZYE.cjs +15 -0
- package/dist/openrouter-sync-K2WK3A2A.cjs +11 -0
- package/dist/openrouter-sync-SO3AWEAM.js +11 -0
- package/dist/product/index.cjs +12 -16
- package/dist/product/index.js +11 -15
- package/dist/protocol/types.d.ts +11 -3
- package/dist/{ink → render}/hooks/use-input.d.ts +1 -1
- package/dist/run/index.cjs +12 -16
- package/dist/run/index.js +11 -15
- package/dist/session/memory.d.ts +23 -3
- package/dist/session/session-manager.d.ts +4 -1
- package/dist/{session-manager-UQKB564H.cjs → session-manager-HRSKENKB.cjs} +2 -2
- package/dist/{session-manager-JIIBCFTC.js → session-manager-NEKFEHF3.js} +1 -1
- package/dist/settings/manager.d.ts +9 -0
- package/dist/settings/schema.d.ts +48 -39
- package/dist/{tool-summary-J2ICNMWP.js → tool-summary-2RUFL5QK.js} +1 -1
- package/dist/{tool-summary-5P2GKRA4.cjs → tool-summary-RYNR4DDB.cjs} +2 -2
- package/dist/tool-system/builtin/agent.d.ts +3 -26
- package/dist/tool-system/builtin/apply-patch/applier.d.ts +26 -0
- package/dist/tool-system/builtin/apply-patch/index.d.ts +19 -0
- package/dist/tool-system/builtin/apply-patch/parser.d.ts +17 -0
- package/dist/tool-system/builtin/apply-patch/seek-sequence.d.ts +18 -0
- package/dist/tool-system/builtin/apply-patch/types.d.ts +49 -0
- package/dist/tool-system/builtin/arena.d.ts +18 -5
- package/dist/tool-system/builtin/ask-user.d.ts +6 -6
- package/dist/tool-system/builtin/index.d.ts +11 -1
- package/dist/tool-system/builtin/tool-search.d.ts +2 -3
- package/dist/tool-system/context.d.ts +74 -0
- package/dist/tool-system/executor.d.ts +16 -0
- package/dist/tool-system/permission.d.ts +40 -5
- package/dist/tool-system/registry.d.ts +2 -0
- package/dist/types.d.ts +28 -1
- package/dist/ui/App.d.ts +1 -1
- package/dist/ui/components/AgentBlock.d.ts +1 -1
- package/dist/ui/components/AskUserPrompt.d.ts +7 -0
- package/dist/ui/components/MessageContent.d.ts +7 -3
- package/dist/ui/components/ModelManager.d.ts +35 -0
- package/dist/ui/components/ModelSelector.d.ts +10 -0
- package/dist/ui/components/OnboardingPrompt.d.ts +7 -0
- package/dist/ui/components/PermissionPrompt.d.ts +5 -2
- package/dist/ui/components/SessionPicker.d.ts +14 -0
- package/dist/ui/components/StatusLine.d.ts +4 -2
- package/dist/ui/components/ThemedBox.d.ts +1 -1
- package/dist/ui/components/ToolCall.d.ts +8 -1
- package/dist/ui/components/WelcomeTips.d.ts +5 -0
- package/dist/ui/onboarding-runner.d.ts +2 -0
- package/dist/ui/store.d.ts +1 -0
- package/dist/{updater-2N6745WR.cjs → updater-J7L7R6BY.cjs} +7 -5
- package/dist/{updater-PV7FKSUI.js → updater-LDBNYCAO.js} +7 -5
- package/dist/utils/debug.d.ts +17 -33
- package/package.json +7 -5
- package/scripts/check-node.cjs +21 -0
- package/dist/anthropic-XMTTVNSH.cjs +0 -9
- package/dist/bridge-4ZRXVWBN.js +0 -98
- package/dist/bridge-W476QDFH.cjs +0 -98
- package/dist/chunk-4RRUP4MM.js +0 -86
- package/dist/chunk-4SFPFHMG.js +0 -132
- package/dist/chunk-5LHVI777.cjs +0 -246
- package/dist/chunk-6ZIROYXX.js +0 -207
- package/dist/chunk-C7JBCO5V.js +0 -80
- package/dist/chunk-CSO5EOEP.cjs +0 -132
- package/dist/chunk-FGZGCFJX.cjs +0 -207
- package/dist/chunk-HD7MT5XU.cjs +0 -86
- package/dist/chunk-IMMTBZ33.cjs +0 -63
- package/dist/chunk-JT2WSQSR.cjs +0 -335
- package/dist/chunk-NZ4DQ72D.cjs +0 -664
- package/dist/chunk-OG4MIQJ6.js +0 -335
- package/dist/chunk-WRZJUQ5Z.js +0 -664
- package/dist/chunk-X4HAERTQ.js +0 -63
- package/dist/chunk-XHC2JMEC.cjs +0 -80
- package/dist/chunk-ZRSSGYA5.js +0 -246
- package/dist/compaction-44I55TLI.cjs +0 -32
- package/dist/coordinator-5HY7ALO2.js +0 -7
- package/dist/coordinator-INDLPVMF.cjs +0 -7
- package/dist/cost-tracker-IWYAUPXH.js +0 -9
- package/dist/cost-tracker-JXTJQQWE.cjs +0 -9
- package/dist/loader-DXFSUB4R.cjs +0 -91
- package/dist/loader-J5UID6CV.js +0 -91
- package/dist/manager-ETWDOCHN.cjs +0 -9
- package/dist/manager-HGMQNEJB.cjs +0 -11
- package/dist/manager-HUAQOORS.js +0 -9
- package/dist/manager-VJIZ2CQC.js +0 -11
- package/dist/mcp-manager-G4G2QASE.cjs +0 -8
- package/dist/memory-AP747G5H.js +0 -7
- package/dist/memory-BH3BYUN5.cjs +0 -7
- package/dist/onboarding-6WEPV7C2.js +0 -11
- package/dist/onboarding-QM5DY2TU.cjs +0 -11
- package/dist/openai-656VWUQW.cjs +0 -9
- package/dist/skills-63RBYQRX.js +0 -13
- package/dist/skills-V3BPLW3D.cjs +0 -13
- package/dist/token-counter-CHAXW5O7.cjs +0 -13
- package/dist/token-counter-DSOZGZ5Q.js +0 -13
- package/dist/utils/log.d.ts +0 -56
- package/dist/voice-KTZ7PAGO.js +0 -80
- package/dist/voice-KZE25GKB.cjs +0 -80
- /package/dist/{ink → render}/Ansi.d.ts +0 -0
- /package/dist/{ink → render}/bidi.d.ts +0 -0
- /package/dist/{ink → render}/clearTerminal.d.ts +0 -0
- /package/dist/{ink → render}/colorize.d.ts +0 -0
- /package/dist/{ink → render}/components/AlternateScreen.d.ts +0 -0
- /package/dist/{ink → render}/components/App.d.ts +0 -0
- /package/dist/{ink → render}/components/AppContext.d.ts +0 -0
- /package/dist/{ink → render}/components/Box.d.ts +0 -0
- /package/dist/{ink → render}/components/Button.d.ts +0 -0
- /package/dist/{ink → render}/components/ClockContext.d.ts +0 -0
- /package/dist/{ink → render}/components/CursorDeclarationContext.d.ts +0 -0
- /package/dist/{ink → render}/components/ErrorOverview.d.ts +0 -0
- /package/dist/{ink → render}/components/Link.d.ts +0 -0
- /package/dist/{ink → render}/components/Newline.d.ts +0 -0
- /package/dist/{ink → render}/components/NoSelect.d.ts +0 -0
- /package/dist/{ink → render}/components/RawAnsi.d.ts +0 -0
- /package/dist/{ink → render}/components/ScrollBox.d.ts +0 -0
- /package/dist/{ink → render}/components/Spacer.d.ts +0 -0
- /package/dist/{ink → render}/components/StdinContext.d.ts +0 -0
- /package/dist/{ink → render}/components/TerminalFocusContext.d.ts +0 -0
- /package/dist/{ink → render}/components/TerminalSizeContext.d.ts +0 -0
- /package/dist/{ink → render}/components/Text.d.ts +0 -0
- /package/dist/{ink → render}/constants.d.ts +0 -0
- /package/dist/{ink → render}/cursor.d.ts +0 -0
- /package/dist/{ink → render}/devtools.d.ts +0 -0
- /package/dist/{ink → render}/dom.d.ts +0 -0
- /package/dist/{ink → render}/events/click-event.d.ts +0 -0
- /package/dist/{ink → render}/events/dispatcher.d.ts +0 -0
- /package/dist/{ink → render}/events/emitter.d.ts +0 -0
- /package/dist/{ink → render}/events/event-handlers.d.ts +0 -0
- /package/dist/{ink → render}/events/event.d.ts +0 -0
- /package/dist/{ink → render}/events/focus-event.d.ts +0 -0
- /package/dist/{ink → render}/events/input-event.d.ts +0 -0
- /package/dist/{ink → render}/events/keyboard-event.d.ts +0 -0
- /package/dist/{ink → render}/events/paste-event.d.ts +0 -0
- /package/dist/{ink → render}/events/resize-event.d.ts +0 -0
- /package/dist/{ink → render}/events/terminal-event.d.ts +0 -0
- /package/dist/{ink → render}/events/terminal-focus-event.d.ts +0 -0
- /package/dist/{ink → render}/focus.d.ts +0 -0
- /package/dist/{ink → render}/frame.d.ts +0 -0
- /package/dist/{ink → render}/get-max-width.d.ts +0 -0
- /package/dist/{ink → render}/hit-test.d.ts +0 -0
- /package/dist/{ink → render}/hooks/use-animation-frame.d.ts +0 -0
- /package/dist/{ink → render}/hooks/use-app.d.ts +0 -0
- /package/dist/{ink → render}/hooks/use-declared-cursor.d.ts +0 -0
- /package/dist/{ink → render}/hooks/use-interval.d.ts +0 -0
- /package/dist/{ink → render}/hooks/use-search-highlight.d.ts +0 -0
- /package/dist/{ink → render}/hooks/use-selection.d.ts +0 -0
- /package/dist/{ink → render}/hooks/use-stdin.d.ts +0 -0
- /package/dist/{ink → render}/hooks/use-tab-status.d.ts +0 -0
- /package/dist/{ink → render}/hooks/use-terminal-focus.d.ts +0 -0
- /package/dist/{ink → render}/hooks/use-terminal-title.d.ts +0 -0
- /package/dist/{ink → render}/hooks/use-terminal-viewport.d.ts +0 -0
- /package/dist/{ink → render}/index.d.ts +0 -0
- /package/dist/{ink → render}/ink.d.ts +0 -0
- /package/dist/{ink → render}/instances.d.ts +0 -0
- /package/dist/{ink → render}/layout/engine.d.ts +0 -0
- /package/dist/{ink → render}/layout/geometry.d.ts +0 -0
- /package/dist/{ink → render}/layout/node.d.ts +0 -0
- /package/dist/{ink → render}/layout/yoga.d.ts +0 -0
- /package/dist/{ink → render}/line-width-cache.d.ts +0 -0
- /package/dist/{ink → render}/log-update.d.ts +0 -0
- /package/dist/{ink → render}/measure-element.d.ts +0 -0
- /package/dist/{ink → render}/measure-text.d.ts +0 -0
- /package/dist/{ink → render}/node-cache.d.ts +0 -0
- /package/dist/{ink → render}/optimizer.d.ts +0 -0
- /package/dist/{ink → render}/output.d.ts +0 -0
- /package/dist/{ink → render}/parse-keypress.d.ts +0 -0
- /package/dist/{ink → render}/reconciler.d.ts +0 -0
- /package/dist/{ink → render}/render-border.d.ts +0 -0
- /package/dist/{ink → render}/render-node-to-output.d.ts +0 -0
- /package/dist/{ink → render}/render-to-screen.d.ts +0 -0
- /package/dist/{ink → render}/renderer.d.ts +0 -0
- /package/dist/{ink → render}/root.d.ts +0 -0
- /package/dist/{ink → render}/screen.d.ts +0 -0
- /package/dist/{ink → render}/searchHighlight.d.ts +0 -0
- /package/dist/{ink → render}/selection.d.ts +0 -0
- /package/dist/{ink → render}/squash-text-nodes.d.ts +0 -0
- /package/dist/{ink → render}/stringWidth.d.ts +0 -0
- /package/dist/{ink → render}/styles.d.ts +0 -0
- /package/dist/{ink → render}/supports-hyperlinks.d.ts +0 -0
- /package/dist/{ink → render}/tabstops.d.ts +0 -0
- /package/dist/{ink → render}/terminal-focus-state.d.ts +0 -0
- /package/dist/{ink → render}/terminal-querier.d.ts +0 -0
- /package/dist/{ink → render}/terminal.d.ts +0 -0
- /package/dist/{ink → render}/termio/ansi.d.ts +0 -0
- /package/dist/{ink → render}/termio/csi.d.ts +0 -0
- /package/dist/{ink → render}/termio/dec.d.ts +0 -0
- /package/dist/{ink → render}/termio/esc.d.ts +0 -0
- /package/dist/{ink → render}/termio/osc.d.ts +0 -0
- /package/dist/{ink → render}/termio/parser.d.ts +0 -0
- /package/dist/{ink → render}/termio/sgr.d.ts +0 -0
- /package/dist/{ink → render}/termio/tokenize.d.ts +0 -0
- /package/dist/{ink → render}/termio/types.d.ts +0 -0
- /package/dist/{ink → render}/termio.d.ts +0 -0
- /package/dist/{ink → render}/useTerminalNotification.d.ts +0 -0
- /package/dist/{ink → render}/warn.d.ts +0 -0
- /package/dist/{ink → render}/widest-line.d.ts +0 -0
- /package/dist/{ink → render}/wrap-text.d.ts +0 -0
- /package/dist/{ink → render}/wrapAnsi.d.ts +0 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
logger
|
|
3
|
-
} from "./chunk-X4HAERTQ.js";
|
|
4
1
|
import {
|
|
5
2
|
LLMError
|
|
6
3
|
} from "./chunk-FUOKLKR2.js";
|
|
4
|
+
import {
|
|
5
|
+
logger
|
|
6
|
+
} from "./chunk-ZRVPCXI7.js";
|
|
7
7
|
import {
|
|
8
8
|
init_esm_shims
|
|
9
9
|
} from "./chunk-DI7RDLOS.js";
|
|
@@ -18,11 +18,11 @@ async function createLLMClient(config) {
|
|
|
18
18
|
let Cls = PROVIDER_REGISTRY.get(config.provider);
|
|
19
19
|
if (!Cls) {
|
|
20
20
|
if (config.provider === "anthropic") {
|
|
21
|
-
const { AnthropicClient } = await import("./anthropic-
|
|
21
|
+
const { AnthropicClient } = await import("./anthropic-W2GU3D76.js");
|
|
22
22
|
registerProvider("anthropic", AnthropicClient);
|
|
23
23
|
Cls = AnthropicClient;
|
|
24
24
|
} else if (config.provider === "openai") {
|
|
25
|
-
const { OpenAIClient } = await import("./openai-
|
|
25
|
+
const { OpenAIClient } = await import("./openai-RXU5URYI.js");
|
|
26
26
|
registerProvider("openai", OpenAIClient);
|
|
27
27
|
Cls = OpenAIClient;
|
|
28
28
|
}
|
|
@@ -158,6 +158,8 @@ function parseReport(participant, text) {
|
|
|
158
158
|
findings: []
|
|
159
159
|
};
|
|
160
160
|
}
|
|
161
|
+
const xmlReport = tryParseReportXml(participant, text);
|
|
162
|
+
if (xmlReport && xmlReport.findings.length > 0) return xmlReport;
|
|
161
163
|
try {
|
|
162
164
|
const json = extractJSON(text);
|
|
163
165
|
const parsed = JSON.parse(json);
|
|
@@ -172,22 +174,82 @@ function parseReport(participant, text) {
|
|
|
172
174
|
contextSummary: parsed.contextSummary ?? parsed.context_summary ?? "",
|
|
173
175
|
findings: Array.isArray(findings) ? findings.map(parseFinding) : []
|
|
174
176
|
};
|
|
175
|
-
if (report.findings.length
|
|
176
|
-
logger.warn("arena.parse_report_no_findings", {
|
|
177
|
-
participant,
|
|
178
|
-
textPreview: text.slice(0, 200)
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
return report;
|
|
177
|
+
if (report.findings.length > 0) return report;
|
|
182
178
|
} catch (err) {
|
|
183
179
|
logger.warn("arena.parse_report_json_fail", {
|
|
184
180
|
participant,
|
|
185
181
|
error: err.message,
|
|
186
182
|
textLength: text.length,
|
|
187
|
-
text: text.slice(0,
|
|
183
|
+
text: text.slice(0, 500)
|
|
188
184
|
});
|
|
189
|
-
return extractFindingsFromFreeText(participant, text);
|
|
190
185
|
}
|
|
186
|
+
if (xmlReport) {
|
|
187
|
+
logger.warn("arena.parse_report_no_findings", {
|
|
188
|
+
participant,
|
|
189
|
+
textPreview: text.slice(0, 200)
|
|
190
|
+
});
|
|
191
|
+
return xmlReport;
|
|
192
|
+
}
|
|
193
|
+
return extractFindingsFromFreeText(participant, text);
|
|
194
|
+
}
|
|
195
|
+
function tryParseReportXml(participant, text) {
|
|
196
|
+
const reportMatch = text.match(/<report\b[^>]*>([\s\S]*?)<\/report>/i);
|
|
197
|
+
if (!reportMatch) return void 0;
|
|
198
|
+
const body = reportMatch[1];
|
|
199
|
+
const contextSummary = decodeXmlText(extractTag(body, "contextSummary") ?? "");
|
|
200
|
+
const findingsBlock = extractTag(body, "findings") ?? "";
|
|
201
|
+
const findings = [];
|
|
202
|
+
let i = 0;
|
|
203
|
+
for (const match of findingsBlock.matchAll(/<finding\b([^>]*)>([\s\S]*?)<\/finding>/gi)) {
|
|
204
|
+
const attrs = parseAttrs(match[1]);
|
|
205
|
+
const inner = match[2];
|
|
206
|
+
const title = decodeXmlText(extractTag(inner, "title") ?? "");
|
|
207
|
+
const summary = decodeXmlText(extractTag(inner, "summary") ?? "");
|
|
208
|
+
const evidence = [];
|
|
209
|
+
for (const ev of inner.matchAll(/<evidence\b([^>]*)>([\s\S]*?)<\/evidence>/gi)) {
|
|
210
|
+
const evAttrs = parseAttrs(ev[1]);
|
|
211
|
+
evidence.push({
|
|
212
|
+
type: evAttrs.type ?? "doc",
|
|
213
|
+
ref: evAttrs.ref ?? "",
|
|
214
|
+
note: decodeXmlText(ev[2].trim())
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
const affectedFilesBlock = extractTag(inner, "affectedFiles") ?? "";
|
|
218
|
+
const affectedFiles = [];
|
|
219
|
+
for (const f of affectedFilesBlock.matchAll(/<file>([\s\S]*?)<\/file>/gi)) {
|
|
220
|
+
affectedFiles.push(decodeXmlText(f[1].trim()));
|
|
221
|
+
}
|
|
222
|
+
const suggestedChange = decodeXmlText(extractTag(inner, "suggestedChange") ?? "").trim();
|
|
223
|
+
const confidence = Number(attrs.confidence);
|
|
224
|
+
findings.push({
|
|
225
|
+
id: attrs.id || `f${i + 1}`,
|
|
226
|
+
kind: validateFindingKind(attrs.kind),
|
|
227
|
+
title: title || "Untitled",
|
|
228
|
+
summary,
|
|
229
|
+
severity: attrs.severity || void 0,
|
|
230
|
+
confidence: Number.isFinite(confidence) ? confidence : 0.5,
|
|
231
|
+
evidence,
|
|
232
|
+
affectedFiles,
|
|
233
|
+
suggestedChange: suggestedChange || void 0
|
|
234
|
+
});
|
|
235
|
+
i++;
|
|
236
|
+
}
|
|
237
|
+
return { participant, contextSummary, findings };
|
|
238
|
+
}
|
|
239
|
+
function extractTag(xml, tag) {
|
|
240
|
+
const re = new RegExp(`<${tag}\\b[^>]*>([\\s\\S]*?)<\\/${tag}>`, "i");
|
|
241
|
+
const m = xml.match(re);
|
|
242
|
+
return m?.[1];
|
|
243
|
+
}
|
|
244
|
+
function parseAttrs(attrString) {
|
|
245
|
+
const out = {};
|
|
246
|
+
for (const m of attrString.matchAll(/(\w+)\s*=\s*"([^"]*)"/g)) {
|
|
247
|
+
out[m[1]] = m[2];
|
|
248
|
+
}
|
|
249
|
+
return out;
|
|
250
|
+
}
|
|
251
|
+
function decodeXmlText(s) {
|
|
252
|
+
return s.replace(/<!\[CDATA\[([\s\S]*?)\]\]>/g, "$1").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/&/g, "&").trim();
|
|
191
253
|
}
|
|
192
254
|
function parseFinding(raw, index) {
|
|
193
255
|
return {
|
|
@@ -564,13 +626,32 @@ var ReviewStrategy = class {
|
|
|
564
626
|
You may have access to read-only tools to fetch additional context. The base context is intentionally lean \u2014 use tools to inspect details as needed.
|
|
565
627
|
|
|
566
628
|
IMPORTANT RULES:
|
|
567
|
-
- Limit yourself to 3
|
|
629
|
+
- Limit yourself to AT MOST 3 tool rounds. Do NOT exhaustively read every file.
|
|
568
630
|
- Focus on the HIGHEST-IMPACT findings. Quality over quantity.
|
|
569
|
-
- Output as many findings as the topic warrants \u2014 typically 5-15 for a non-trivial subject. Each
|
|
631
|
+
- Output as many findings as the topic warrants \u2014 typically 5-15 for a non-trivial subject. Each <summary> should be 80+ words with concrete evidence and rationale, not a one-liner. Rank by confidence.
|
|
570
632
|
- Prioritize: risks > improvements > questions. Strengths are optional.
|
|
571
633
|
|
|
572
|
-
When ready, respond ONLY with
|
|
573
|
-
|
|
634
|
+
When ready, respond ONLY with the following XML structure (no markdown fences, no commentary outside the root element):
|
|
635
|
+
|
|
636
|
+
<report>
|
|
637
|
+
<contextSummary>brief summary of what you investigated</contextSummary>
|
|
638
|
+
<findings>
|
|
639
|
+
<finding id="unique-id" kind="risk|improvement|question|strength" severity="high|medium|low" confidence="0.0-1.0">
|
|
640
|
+
<title>short title</title>
|
|
641
|
+
<summary>detailed explanation, 80+ words, citing specific files/lines</summary>
|
|
642
|
+
<evidence type="file|diff|grep|git|doc" ref="path">what it shows</evidence>
|
|
643
|
+
<evidence type="file" ref="another/path">\u2026</evidence>
|
|
644
|
+
<affectedFiles>
|
|
645
|
+
<file>src/foo.ts</file>
|
|
646
|
+
<file>src/bar.ts</file>
|
|
647
|
+
</affectedFiles>
|
|
648
|
+
<suggestedChange>optional concrete fix</suggestedChange>
|
|
649
|
+
</finding>
|
|
650
|
+
<!-- repeat <finding> blocks as needed -->
|
|
651
|
+
</findings>
|
|
652
|
+
</report>
|
|
653
|
+
|
|
654
|
+
XML is preferred over JSON because thinking-mode models produce more reliable output here. Do not wrap the XML in code fences. Do not include text outside <report>\u2026</report>.`;
|
|
574
655
|
}
|
|
575
656
|
researchUserPrompt(topic, baseContext) {
|
|
576
657
|
return `## Review Topic
|
|
@@ -578,7 +659,7 @@ ${topic}
|
|
|
578
659
|
|
|
579
660
|
${formatBaseContext(baseContext)}
|
|
580
661
|
|
|
581
|
-
Use tools to read specific files from the diff. Then output 3-6 highest-confidence findings as
|
|
662
|
+
Use tools to read specific files from the diff. Then output 3-6 highest-confidence findings as a single <report> XML element.`;
|
|
582
663
|
}
|
|
583
664
|
parseResearchResponse(participant, text) {
|
|
584
665
|
return parseReport(participant, text);
|
|
@@ -716,7 +797,14 @@ ${debateSummary}
|
|
|
716
797
|
## Evidence Digest
|
|
717
798
|
${formatDigestForPrompt(digest)}
|
|
718
799
|
|
|
719
|
-
As moderator,
|
|
800
|
+
As moderator, you MUST issue a verdict \u2014 "unresolved" is reserved ONLY for the rare case where the debate produced genuinely irreconcilable interpretations of the same evidence. Default to deciding.
|
|
801
|
+
|
|
802
|
+
Decision rule:
|
|
803
|
+
- "accepted": claim is correct as stated AND has direct evidence (file/line refs).
|
|
804
|
+
- "accepted_with_revision": core insight is correct but the challenge surfaced a real refinement (scope/severity/wording). Issue a corrected finalSummary.
|
|
805
|
+
- "rejected": the challenger demonstrated the claim is factually wrong or already addressed in the code under review.
|
|
806
|
+
- "unresolved": ONLY when no amount of further evidence could break the tie \u2014 e.g., taste-level disagreement on design philosophy. Using this on a verifiable code claim is a failure of adjudication.
|
|
807
|
+
|
|
720
808
|
Respond ONLY with JSON:
|
|
721
809
|
{"outcome": "accepted|accepted_with_revision|rejected|unresolved", "rationale": "...", "finalSummary": "revised claim summary if needed", "supportingEvidenceRefs": ["..."]}`;
|
|
722
810
|
}
|
|
@@ -1852,15 +1940,15 @@ var gitProvider = {
|
|
|
1852
1940
|
});
|
|
1853
1941
|
}
|
|
1854
1942
|
const statArgs = isCompare ? ["diff", "--stat", `${baseRef}...${headRef}`] : ["diff", "--stat", "HEAD"];
|
|
1855
|
-
let
|
|
1856
|
-
if (!
|
|
1857
|
-
if (
|
|
1943
|
+
let stat2 = git(statArgs);
|
|
1944
|
+
if (!stat2 && !isCompare) stat2 = git(["diff", "--stat", "--cached"]);
|
|
1945
|
+
if (stat2) {
|
|
1858
1946
|
artifacts.push({
|
|
1859
1947
|
id: "git-diffstat",
|
|
1860
1948
|
kind: "doc",
|
|
1861
1949
|
source: "git",
|
|
1862
1950
|
title: "Diff Stat",
|
|
1863
|
-
preview:
|
|
1951
|
+
preview: stat2
|
|
1864
1952
|
});
|
|
1865
1953
|
}
|
|
1866
1954
|
const filesArgs = isCompare ? ["diff", "--name-status", `${baseRef}...${headRef}`] : ["diff", "--name-status", "HEAD"];
|
|
@@ -1909,7 +1997,7 @@ var gitProvider = {
|
|
|
1909
1997
|
metadata: { totalChars: diff.length, truncated }
|
|
1910
1998
|
});
|
|
1911
1999
|
}
|
|
1912
|
-
if (!diff && !
|
|
2000
|
+
if (!diff && !stat2) {
|
|
1913
2001
|
const status = git(["status", "--short"]);
|
|
1914
2002
|
if (status) {
|
|
1915
2003
|
artifacts.push({
|
|
@@ -1957,16 +2045,21 @@ function clusterByDirectory(paths) {
|
|
|
1957
2045
|
|
|
1958
2046
|
// src/arena/providers/repo.ts
|
|
1959
2047
|
init_esm_shims();
|
|
1960
|
-
import { existsSync,
|
|
2048
|
+
import { existsSync, readFileSync, statSync } from "fs";
|
|
2049
|
+
import { readdir, stat } from "fs/promises";
|
|
1961
2050
|
import { join } from "path";
|
|
1962
|
-
import {
|
|
2051
|
+
import { execFile } from "child_process";
|
|
2052
|
+
import { promisify } from "util";
|
|
1963
2053
|
var MAX_FILE_CHARS = 8e3;
|
|
2054
|
+
var GREP_TIMEOUT_MS = 3e3;
|
|
2055
|
+
var MAX_TREE_NODES = 400;
|
|
2056
|
+
var execFileAsync = promisify(execFile);
|
|
1964
2057
|
var repoProvider = {
|
|
1965
2058
|
kind: "repo",
|
|
1966
|
-
collect(plan, topic) {
|
|
2059
|
+
async collect(plan, topic) {
|
|
1967
2060
|
const artifacts = [];
|
|
1968
2061
|
const targets = plan.sources.find((s) => s.kind === "repo")?.targets ?? [];
|
|
1969
|
-
const tree = buildTree(".", 2);
|
|
2062
|
+
const tree = await buildTree(".", 2);
|
|
1970
2063
|
if (tree) {
|
|
1971
2064
|
artifacts.push({
|
|
1972
2065
|
id: "repo-tree",
|
|
@@ -1980,7 +2073,7 @@ var repoProvider = {
|
|
|
1980
2073
|
if (!existsSync(target)) continue;
|
|
1981
2074
|
const st = statSync(target);
|
|
1982
2075
|
if (st.isDirectory()) {
|
|
1983
|
-
const dirTree = buildTree(target, 3);
|
|
2076
|
+
const dirTree = await buildTree(target, 3);
|
|
1984
2077
|
if (dirTree) {
|
|
1985
2078
|
artifacts.push({
|
|
1986
2079
|
id: `repo-tree-${target}`,
|
|
@@ -1990,7 +2083,7 @@ var repoProvider = {
|
|
|
1990
2083
|
preview: dirTree
|
|
1991
2084
|
});
|
|
1992
2085
|
}
|
|
1993
|
-
for (const file of collectEntryFiles(target).slice(0, 3)) {
|
|
2086
|
+
for (const file of (await collectEntryFiles(target)).slice(0, 3)) {
|
|
1994
2087
|
const content = safeReadFile(file);
|
|
1995
2088
|
if (content) {
|
|
1996
2089
|
artifacts.push({
|
|
@@ -2018,29 +2111,30 @@ var repoProvider = {
|
|
|
2018
2111
|
}
|
|
2019
2112
|
}
|
|
2020
2113
|
if (targets.length === 0) {
|
|
2021
|
-
const hints = extractSearchHints(topic);
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2114
|
+
const hints = extractSearchHints(topic).slice(0, 5);
|
|
2115
|
+
const grepResults = await Promise.all(hints.map((h) => safeGrep(h)));
|
|
2116
|
+
for (let i = 0; i < hints.length; i++) {
|
|
2117
|
+
const hint = hints[i];
|
|
2118
|
+
const result = grepResults[i] ?? "";
|
|
2119
|
+
if (!result) continue;
|
|
2120
|
+
const files = result.split("\n").filter(Boolean).slice(0, 10);
|
|
2121
|
+
for (const file of files) {
|
|
2122
|
+
if (!artifacts.some((a) => a.ref === file)) {
|
|
2123
|
+
artifacts.push({
|
|
2124
|
+
id: `repo-grep-${hint}-${file}`,
|
|
2125
|
+
kind: "grep",
|
|
2126
|
+
source: "repo",
|
|
2127
|
+
title: `Match: ${hint} \u2192 ${file}`,
|
|
2128
|
+
ref: file,
|
|
2129
|
+
preview: file
|
|
2130
|
+
});
|
|
2037
2131
|
}
|
|
2038
2132
|
}
|
|
2039
2133
|
}
|
|
2040
2134
|
}
|
|
2041
2135
|
const hasGitSource = plan.sources.some((s) => s.kind === "git");
|
|
2042
2136
|
if (!hasGitSource) {
|
|
2043
|
-
const recentLog = gitLog();
|
|
2137
|
+
const recentLog = await gitLog();
|
|
2044
2138
|
if (recentLog) {
|
|
2045
2139
|
artifacts.push({
|
|
2046
2140
|
id: "repo-recent-activity",
|
|
@@ -2055,30 +2149,43 @@ var repoProvider = {
|
|
|
2055
2149
|
return artifacts;
|
|
2056
2150
|
}
|
|
2057
2151
|
};
|
|
2058
|
-
function buildTree(dir, maxDepth
|
|
2059
|
-
|
|
2152
|
+
async function buildTree(dir, maxDepth) {
|
|
2153
|
+
const lines = [];
|
|
2154
|
+
const counter = { n: 0 };
|
|
2155
|
+
await walkTree(dir, maxDepth, 0, "", lines, counter);
|
|
2156
|
+
return lines.filter(Boolean).join("\n");
|
|
2157
|
+
}
|
|
2158
|
+
async function walkTree(dir, maxDepth, depth, prefix, out, counter) {
|
|
2159
|
+
if (depth >= maxDepth) return;
|
|
2160
|
+
if (counter.n >= MAX_TREE_NODES) return;
|
|
2161
|
+
let entries;
|
|
2060
2162
|
try {
|
|
2061
|
-
|
|
2163
|
+
entries = (await readdir(dir)).filter(
|
|
2062
2164
|
(e) => !e.startsWith(".") && e !== "node_modules" && e !== "dist" && e !== "__pycache__"
|
|
2063
2165
|
);
|
|
2064
|
-
const lines = [];
|
|
2065
|
-
for (const entry of entries.slice(0, 30)) {
|
|
2066
|
-
const fullPath = join(dir, entry);
|
|
2067
|
-
const isDir = statSync(fullPath).isDirectory();
|
|
2068
|
-
lines.push(`${prefix}${isDir ? "/" : ""} ${entry}`);
|
|
2069
|
-
if (isDir && depth < maxDepth - 1) {
|
|
2070
|
-
lines.push(buildTree(fullPath, maxDepth, depth + 1, prefix + " "));
|
|
2071
|
-
}
|
|
2072
|
-
}
|
|
2073
|
-
return lines.filter(Boolean).join("\n");
|
|
2074
2166
|
} catch {
|
|
2075
|
-
return
|
|
2167
|
+
return;
|
|
2168
|
+
}
|
|
2169
|
+
for (const entry of entries.slice(0, 30)) {
|
|
2170
|
+
if (counter.n >= MAX_TREE_NODES) return;
|
|
2171
|
+
counter.n++;
|
|
2172
|
+
const fullPath = join(dir, entry);
|
|
2173
|
+
let isDir = false;
|
|
2174
|
+
try {
|
|
2175
|
+
isDir = (await stat(fullPath)).isDirectory();
|
|
2176
|
+
} catch {
|
|
2177
|
+
continue;
|
|
2178
|
+
}
|
|
2179
|
+
out.push(`${prefix}${isDir ? "/" : ""} ${entry}`);
|
|
2180
|
+
if (isDir && depth < maxDepth - 1) {
|
|
2181
|
+
await walkTree(fullPath, maxDepth, depth + 1, prefix + " ", out, counter);
|
|
2182
|
+
}
|
|
2076
2183
|
}
|
|
2077
2184
|
}
|
|
2078
|
-
function collectEntryFiles(dir) {
|
|
2185
|
+
async function collectEntryFiles(dir) {
|
|
2079
2186
|
const files = [];
|
|
2080
2187
|
try {
|
|
2081
|
-
const entries =
|
|
2188
|
+
const entries = await readdir(dir);
|
|
2082
2189
|
const priority = ["index.ts", "index.js", "main.ts", "main.js", "mod.ts", "__init__.py"];
|
|
2083
2190
|
for (const p of priority) {
|
|
2084
2191
|
if (entries.includes(p)) files.push(join(dir, p));
|
|
@@ -2110,9 +2217,9 @@ function truncate(content) {
|
|
|
2110
2217
|
return t.slice(0, lastNl) + `
|
|
2111
2218
|
... (truncated, ${content.length} chars total)`;
|
|
2112
2219
|
}
|
|
2113
|
-
function safeGrep(pattern) {
|
|
2220
|
+
async function safeGrep(pattern) {
|
|
2114
2221
|
try {
|
|
2115
|
-
const
|
|
2222
|
+
const { stdout } = await execFileAsync("grep", [
|
|
2116
2223
|
"-rl",
|
|
2117
2224
|
"--include=*.ts",
|
|
2118
2225
|
"--include=*.js",
|
|
@@ -2121,19 +2228,28 @@ function safeGrep(pattern) {
|
|
|
2121
2228
|
"-i",
|
|
2122
2229
|
pattern,
|
|
2123
2230
|
"."
|
|
2124
|
-
], { encoding: "utf-8", maxBuffer: 1024 * 1024, timeout:
|
|
2125
|
-
return
|
|
2126
|
-
} catch {
|
|
2231
|
+
], { encoding: "utf-8", maxBuffer: 1024 * 1024, timeout: GREP_TIMEOUT_MS });
|
|
2232
|
+
return stdout.trim();
|
|
2233
|
+
} catch (err) {
|
|
2234
|
+
const e = err;
|
|
2235
|
+
if (e?.code === 1) return "";
|
|
2236
|
+
logger.warn("arena.provider.grep_failed", {
|
|
2237
|
+
pattern,
|
|
2238
|
+
code: e?.code,
|
|
2239
|
+
killed: e?.killed,
|
|
2240
|
+
signal: e?.signal
|
|
2241
|
+
});
|
|
2127
2242
|
return "";
|
|
2128
2243
|
}
|
|
2129
2244
|
}
|
|
2130
|
-
function gitLog() {
|
|
2245
|
+
async function gitLog() {
|
|
2131
2246
|
try {
|
|
2132
|
-
|
|
2247
|
+
const { stdout } = await execFileAsync("git", ["log", "--oneline", "-10"], {
|
|
2133
2248
|
encoding: "utf-8",
|
|
2134
2249
|
maxBuffer: 1024 * 1024,
|
|
2135
2250
|
timeout: 1e4
|
|
2136
|
-
})
|
|
2251
|
+
});
|
|
2252
|
+
return stdout.trim();
|
|
2137
2253
|
} catch {
|
|
2138
2254
|
return "";
|
|
2139
2255
|
}
|
|
@@ -2204,7 +2320,7 @@ function extractSearchHints(topic) {
|
|
|
2204
2320
|
|
|
2205
2321
|
// src/arena/providers/docs.ts
|
|
2206
2322
|
init_esm_shims();
|
|
2207
|
-
import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync
|
|
2323
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2, readdirSync, statSync as statSync2 } from "fs";
|
|
2208
2324
|
import { join as join2, extname } from "path";
|
|
2209
2325
|
var MAX_DOC_CHARS = 1e4;
|
|
2210
2326
|
var DOC_EXTENSIONS = /* @__PURE__ */ new Set([".md", ".txt", ".rst", ".adoc", ".org"]);
|
|
@@ -2264,7 +2380,7 @@ function findDocFiles(dir, maxDepth, depth = 0) {
|
|
|
2264
2380
|
if (depth >= maxDepth) return [];
|
|
2265
2381
|
const files = [];
|
|
2266
2382
|
try {
|
|
2267
|
-
const entries =
|
|
2383
|
+
const entries = readdirSync(dir);
|
|
2268
2384
|
for (const entry of entries) {
|
|
2269
2385
|
if (entry.startsWith(".") || entry === "node_modules") continue;
|
|
2270
2386
|
const full = join2(dir, entry);
|
|
@@ -2315,20 +2431,36 @@ var PROVIDER_MAP = {
|
|
|
2315
2431
|
// web deferred to Phase 4 — falls back to none for now
|
|
2316
2432
|
none: noneProvider
|
|
2317
2433
|
};
|
|
2318
|
-
|
|
2434
|
+
var PROVIDER_TIMEOUT_MS = 8e3;
|
|
2435
|
+
async function collectEvidence(plan, topic, options = {}) {
|
|
2319
2436
|
const artifacts = [];
|
|
2320
2437
|
const quickFacts = [];
|
|
2321
2438
|
const seenSources = /* @__PURE__ */ new Set();
|
|
2439
|
+
const { onProgress, signal } = options;
|
|
2440
|
+
const tasks = [];
|
|
2322
2441
|
for (const sourceSpec of plan.sources) {
|
|
2323
2442
|
if (seenSources.has(sourceSpec.kind)) continue;
|
|
2324
2443
|
seenSources.add(sourceSpec.kind);
|
|
2325
2444
|
const provider = PROVIDER_MAP[sourceSpec.kind];
|
|
2326
2445
|
if (!provider) continue;
|
|
2327
|
-
|
|
2328
|
-
|
|
2446
|
+
onProgress?.({ type: "evidence_started", source: sourceSpec.kind });
|
|
2447
|
+
tasks.push(runProviderWithTimeout(provider, plan, topic, signal));
|
|
2448
|
+
}
|
|
2449
|
+
const results = await Promise.all(tasks);
|
|
2450
|
+
for (const r of results) {
|
|
2451
|
+
artifacts.push(...r.artifacts);
|
|
2329
2452
|
logger.info("arena.evidence_collected", {
|
|
2330
|
-
source:
|
|
2331
|
-
count:
|
|
2453
|
+
source: r.kind,
|
|
2454
|
+
count: r.artifacts.length,
|
|
2455
|
+
durationMs: r.durationMs,
|
|
2456
|
+
timedOut: r.timedOut || void 0
|
|
2457
|
+
});
|
|
2458
|
+
onProgress?.({
|
|
2459
|
+
type: "evidence_collected",
|
|
2460
|
+
source: r.kind,
|
|
2461
|
+
count: r.artifacts.length,
|
|
2462
|
+
durationMs: r.durationMs,
|
|
2463
|
+
timedOut: r.timedOut
|
|
2332
2464
|
});
|
|
2333
2465
|
}
|
|
2334
2466
|
const branchArtifact = artifacts.find((a) => a.id === "git-branch");
|
|
@@ -2343,17 +2475,61 @@ function collectEvidence(plan, topic) {
|
|
|
2343
2475
|
quickFacts.push({ label: "Lenses", value: plan.lenses.map((l) => l.name).join(", ") });
|
|
2344
2476
|
return { artifacts, quickFacts };
|
|
2345
2477
|
}
|
|
2478
|
+
async function runProviderWithTimeout(provider, plan, topic, signal) {
|
|
2479
|
+
const started = Date.now();
|
|
2480
|
+
let timedOut = false;
|
|
2481
|
+
let timer;
|
|
2482
|
+
let abortHandler;
|
|
2483
|
+
const cleanup = () => {
|
|
2484
|
+
if (timer) {
|
|
2485
|
+
clearTimeout(timer);
|
|
2486
|
+
timer = void 0;
|
|
2487
|
+
}
|
|
2488
|
+
if (abortHandler) {
|
|
2489
|
+
signal?.removeEventListener("abort", abortHandler);
|
|
2490
|
+
abortHandler = void 0;
|
|
2491
|
+
}
|
|
2492
|
+
};
|
|
2493
|
+
const work = Promise.resolve().then(() => provider.collect(plan, topic));
|
|
2494
|
+
const timeout = new Promise((resolve2) => {
|
|
2495
|
+
timer = setTimeout(() => {
|
|
2496
|
+
timedOut = true;
|
|
2497
|
+
logger.warn("arena.provider.timeout", { source: provider.kind, ms: PROVIDER_TIMEOUT_MS });
|
|
2498
|
+
resolve2([]);
|
|
2499
|
+
}, PROVIDER_TIMEOUT_MS);
|
|
2500
|
+
if (typeof timer.unref === "function") timer.unref();
|
|
2501
|
+
if (signal) {
|
|
2502
|
+
abortHandler = () => resolve2([]);
|
|
2503
|
+
signal.addEventListener("abort", abortHandler, { once: true });
|
|
2504
|
+
}
|
|
2505
|
+
});
|
|
2506
|
+
let artifacts;
|
|
2507
|
+
try {
|
|
2508
|
+
artifacts = await Promise.race([work, timeout]);
|
|
2509
|
+
} catch (err) {
|
|
2510
|
+
logger.warn("arena.provider.error", { source: provider.kind, error: err.message });
|
|
2511
|
+
artifacts = [];
|
|
2512
|
+
} finally {
|
|
2513
|
+
cleanup();
|
|
2514
|
+
}
|
|
2515
|
+
return {
|
|
2516
|
+
kind: provider.kind,
|
|
2517
|
+
artifacts,
|
|
2518
|
+
durationMs: Date.now() - started,
|
|
2519
|
+
timedOut
|
|
2520
|
+
};
|
|
2521
|
+
}
|
|
2346
2522
|
|
|
2347
2523
|
// src/arena/tools/selector.ts
|
|
2348
2524
|
init_esm_shims();
|
|
2349
2525
|
|
|
2350
2526
|
// src/arena/context/context-tools.ts
|
|
2351
2527
|
init_esm_shims();
|
|
2352
|
-
import { readFileSync as readFileSync3, existsSync as existsSync3, readdirSync as
|
|
2353
|
-
import { execFileSync as
|
|
2528
|
+
import { readFileSync as readFileSync3, existsSync as existsSync3, readdirSync as readdirSync2, statSync as statSync3 } from "fs";
|
|
2529
|
+
import { execFileSync as execFileSync2 } from "child_process";
|
|
2354
2530
|
import { resolve, join as join3 } from "path";
|
|
2355
2531
|
var MAX_TOOL_RESULT = 15e3;
|
|
2356
|
-
var MAX_TOOL_ROUNDS =
|
|
2532
|
+
var MAX_TOOL_ROUNDS = 3;
|
|
2357
2533
|
var REPO_ROOT = resolve(".");
|
|
2358
2534
|
var CONTEXT_TOOLS = [
|
|
2359
2535
|
{
|
|
@@ -2470,7 +2646,7 @@ function executeListFiles(args) {
|
|
|
2470
2646
|
const dir = args.path || ".";
|
|
2471
2647
|
if (!validatePath(dir)) return `Error: path outside repository: ${dir}`;
|
|
2472
2648
|
try {
|
|
2473
|
-
const entries =
|
|
2649
|
+
const entries = readdirSync2(dir);
|
|
2474
2650
|
const lines = [];
|
|
2475
2651
|
for (const entry of entries.slice(0, 50)) {
|
|
2476
2652
|
const fullPath = join3(dir, entry);
|
|
@@ -2514,7 +2690,7 @@ function sanitizeGitRef(ref) {
|
|
|
2514
2690
|
}
|
|
2515
2691
|
function execFileSafe(cmd, args, maxLines) {
|
|
2516
2692
|
try {
|
|
2517
|
-
const raw =
|
|
2693
|
+
const raw = execFileSync2(cmd, args, {
|
|
2518
2694
|
encoding: "utf-8",
|
|
2519
2695
|
maxBuffer: 512 * 1024,
|
|
2520
2696
|
timeout: 1e4
|
|
@@ -2679,6 +2855,16 @@ async function runParticipantResearchWithDossiers(options) {
|
|
|
2679
2855
|
content: result
|
|
2680
2856
|
});
|
|
2681
2857
|
}
|
|
2858
|
+
const remaining = MAX_TOOL_ROUNDS - round;
|
|
2859
|
+
const isLastAllowedRound = remaining <= 0;
|
|
2860
|
+
const isPenultimate = remaining === 1;
|
|
2861
|
+
if (isLastAllowedRound || isPenultimate) {
|
|
2862
|
+
const directive = isLastAllowedRound ? "STOP. You have used your tool budget. Your NEXT response MUST be the findings JSON. Do NOT call any more tools \u2014 any further tool_use will be discarded." : "FINAL ROUND. Use the tool results below plus any prior context to output the findings JSON in your NEXT response. Do not call more tools.";
|
|
2863
|
+
resultBlocks.unshift({
|
|
2864
|
+
type: "text",
|
|
2865
|
+
text: `[arena-research:${p.name}] ${directive}`
|
|
2866
|
+
});
|
|
2867
|
+
}
|
|
2682
2868
|
messages.push({ role: "user", content: resultBlocks });
|
|
2683
2869
|
}
|
|
2684
2870
|
if (!finalText) {
|
|
@@ -2693,7 +2879,7 @@ async function runParticipantResearchWithDossiers(options) {
|
|
|
2693
2879
|
...messages,
|
|
2694
2880
|
{
|
|
2695
2881
|
role: "user",
|
|
2696
|
-
content: "You have gathered enough context. Based on ALL the tool results above, output your findings NOW.\n\nRespond ONLY with
|
|
2882
|
+
content: "You have gathered enough context. Based on ALL the tool results above, output your findings NOW.\n\nRespond ONLY with the <report> XML element specified in the system prompt \u2014 output your highest-confidence findings (typically 5-15 for a substantive topic; each <summary> should be 80+ words with concrete evidence). Do NOT request any more tools. No prose outside the XML."
|
|
2697
2883
|
}
|
|
2698
2884
|
]
|
|
2699
2885
|
});
|
|
@@ -3857,8 +4043,24 @@ var Arena = class {
|
|
|
3857
4043
|
this.config.mode = plan.mode;
|
|
3858
4044
|
}
|
|
3859
4045
|
signal?.throwIfAborted();
|
|
3860
|
-
const
|
|
3861
|
-
|
|
4046
|
+
const onProgress = this.config.onProgress;
|
|
4047
|
+
const { artifacts, quickFacts } = await collectEvidence(plan, topic, {
|
|
4048
|
+
signal,
|
|
4049
|
+
onProgress: (e) => {
|
|
4050
|
+
if (e.type === "evidence_started") {
|
|
4051
|
+
onProgress?.({ type: "evidence_started", source: e.source });
|
|
4052
|
+
} else {
|
|
4053
|
+
onProgress?.({
|
|
4054
|
+
type: "evidence_source_done",
|
|
4055
|
+
source: e.source,
|
|
4056
|
+
count: e.count ?? 0,
|
|
4057
|
+
durationMs: e.durationMs ?? 0,
|
|
4058
|
+
timedOut: e.timedOut ?? false
|
|
4059
|
+
});
|
|
4060
|
+
}
|
|
4061
|
+
}
|
|
4062
|
+
});
|
|
4063
|
+
onProgress?.({ type: "evidence_collected", artifacts });
|
|
3862
4064
|
logger.info("arena.evidence", {
|
|
3863
4065
|
artifactCount: artifacts.length,
|
|
3864
4066
|
sources: plan.sources.map((s) => s.kind)
|
|
@@ -4299,6 +4501,14 @@ function createProgressRenderer(sink) {
|
|
|
4299
4501
|
`Plan: ${event.plan.mode} | lenses: ${event.plan.lenses.map((l) => l.name).join(", ")} | sources: ${event.plan.sources.map((s) => s.kind).join(", ")}` + (event.plan.confidence !== "high" ? ` (${event.plan.confidence} confidence)` : "")
|
|
4300
4502
|
));
|
|
4301
4503
|
break;
|
|
4504
|
+
case "evidence_started":
|
|
4505
|
+
sink(chalk.dim(` \xB7 collecting from ${event.source}\u2026`));
|
|
4506
|
+
break;
|
|
4507
|
+
case "evidence_source_done": {
|
|
4508
|
+
const tag = event.timedOut ? chalk.yellow(" (timed out)") : "";
|
|
4509
|
+
sink(chalk.dim(` \xB7 ${event.source}: ${event.count} artifacts in ${event.durationMs}ms${tag}`));
|
|
4510
|
+
break;
|
|
4511
|
+
}
|
|
4302
4512
|
case "evidence_collected":
|
|
4303
4513
|
sink(chalk.dim(`Evidence: ${event.artifacts.length} artifacts collected`));
|
|
4304
4514
|
break;
|