@cjhyy/code-shell-arena 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -0
- package/dist/arena.d.ts +45 -0
- package/dist/arena.js +362 -0
- package/dist/capability.d.ts +43 -0
- package/dist/capability.js +453 -0
- package/dist/context/context-tools.d.ts +16 -0
- package/dist/context/context-tools.js +272 -0
- package/dist/context/within-root.d.ts +7 -0
- package/dist/context/within-root.js +15 -0
- package/dist/detect-mode.d.ts +20 -0
- package/dist/detect-mode.js +78 -0
- package/dist/digest-builder.d.ts +25 -0
- package/dist/digest-builder.js +120 -0
- package/dist/index.d.ts +25 -0
- package/dist/index.js +23 -0
- package/dist/index.runtime.d.ts +13 -0
- package/dist/index.runtime.js +11 -0
- package/dist/iterate/convergence.d.ts +25 -0
- package/dist/iterate/convergence.js +103 -0
- package/dist/iterate/formats/index.d.ts +22 -0
- package/dist/iterate/formats/index.js +283 -0
- package/dist/iterate/index.d.ts +11 -0
- package/dist/iterate/index.js +9 -0
- package/dist/iterate/iterative-arena.d.ts +31 -0
- package/dist/iterate/iterative-arena.js +252 -0
- package/dist/iterate/parse.d.ts +42 -0
- package/dist/iterate/parse.js +123 -0
- package/dist/iterate/phases/argue.d.ts +22 -0
- package/dist/iterate/phases/argue.js +165 -0
- package/dist/iterate/phases/revise.d.ts +16 -0
- package/dist/iterate/phases/revise.js +62 -0
- package/dist/iterate/phases/tournament.d.ts +34 -0
- package/dist/iterate/phases/tournament.js +113 -0
- package/dist/iterate/tools/web-tools.d.ts +13 -0
- package/dist/iterate/tools/web-tools.js +54 -0
- package/dist/iterate/types.d.ts +152 -0
- package/dist/iterate/types.js +8 -0
- package/dist/ledger.d.ts +47 -0
- package/dist/ledger.js +159 -0
- package/dist/lenses/architecture.d.ts +5 -0
- package/dist/lenses/architecture.js +22 -0
- package/dist/lenses/engineering.d.ts +5 -0
- package/dist/lenses/engineering.js +22 -0
- package/dist/lenses/general.d.ts +5 -0
- package/dist/lenses/general.js +20 -0
- package/dist/lenses/index.d.ts +16 -0
- package/dist/lenses/index.js +47 -0
- package/dist/lenses/product.d.ts +5 -0
- package/dist/lenses/product.js +22 -0
- package/dist/model-presets.d.ts +23 -0
- package/dist/model-presets.js +44 -0
- package/dist/phases/adjudication.d.ts +25 -0
- package/dist/phases/adjudication.js +142 -0
- package/dist/phases/build-consensus.d.ts +30 -0
- package/dist/phases/build-consensus.js +85 -0
- package/dist/phases/claim-registry.d.ts +26 -0
- package/dist/phases/claim-registry.js +60 -0
- package/dist/phases/cross-review.d.ts +47 -0
- package/dist/phases/cross-review.js +224 -0
- package/dist/phases/debate-rounds.d.ts +28 -0
- package/dist/phases/debate-rounds.js +161 -0
- package/dist/phases/participant-research.d.ts +39 -0
- package/dist/phases/participant-research.js +322 -0
- package/dist/phases/planning-detail-expansion.d.ts +39 -0
- package/dist/phases/planning-detail-expansion.js +120 -0
- package/dist/planner.d.ts +28 -0
- package/dist/planner.js +312 -0
- package/dist/providers/docs.d.ts +7 -0
- package/dist/providers/docs.js +111 -0
- package/dist/providers/git.d.ts +8 -0
- package/dist/providers/git.js +174 -0
- package/dist/providers/index.d.ts +32 -0
- package/dist/providers/index.js +132 -0
- package/dist/providers/none.d.ts +7 -0
- package/dist/providers/none.js +11 -0
- package/dist/providers/repo.d.ts +7 -0
- package/dist/providers/repo.js +258 -0
- package/dist/render/session.d.ts +17 -0
- package/dist/render/session.js +190 -0
- package/dist/render/terminal.d.ts +34 -0
- package/dist/render/terminal.js +286 -0
- package/dist/strategies/discussion.d.ts +25 -0
- package/dist/strategies/discussion.js +143 -0
- package/dist/strategies/index.d.ts +15 -0
- package/dist/strategies/index.js +28 -0
- package/dist/strategies/language-wrapper.d.ts +17 -0
- package/dist/strategies/language-wrapper.js +102 -0
- package/dist/strategies/lens-wrapper.d.ts +16 -0
- package/dist/strategies/lens-wrapper.js +236 -0
- package/dist/strategies/planning.d.ts +30 -0
- package/dist/strategies/planning.js +225 -0
- package/dist/strategies/review.d.ts +26 -0
- package/dist/strategies/review.js +168 -0
- package/dist/strategies/utils.d.ts +36 -0
- package/dist/strategies/utils.js +603 -0
- package/dist/tools/selector.d.ts +17 -0
- package/dist/tools/selector.js +61 -0
- package/dist/transitions.d.ts +53 -0
- package/dist/transitions.js +97 -0
- package/dist/types.d.ts +518 -0
- package/dist/types.js +27 -0
- package/package.json +45 -0
package/README.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# @cjhyy/code-shell-arena
|
|
2
|
+
|
|
3
|
+
Optional multi-model analysis capability for `@cjhyy/code-shell-core`. Arena
|
|
4
|
+
coordinates participant research, evidence collection, review, debate,
|
|
5
|
+
adjudication, and consensus without adding multi-model policy to core.
|
|
6
|
+
|
|
7
|
+
## Host runtime
|
|
8
|
+
|
|
9
|
+
Product hosts should use the focused runtime entry:
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import {
|
|
13
|
+
Arena,
|
|
14
|
+
createArenaCapability,
|
|
15
|
+
formatArenaResultForSession,
|
|
16
|
+
} from "@cjhyy/code-shell-arena/runtime";
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
`/runtime` contains the Arena class, capability factory, model presets, result
|
|
20
|
+
renderers, and public runtime types. It intentionally excludes phase/strategy
|
|
21
|
+
internals and Iterate mode, reducing the modules evaluated by normal TUI or
|
|
22
|
+
Desktop hosts.
|
|
23
|
+
|
|
24
|
+
The package root remains fully compatible and continues to expose advanced
|
|
25
|
+
algorithms, phase helpers, transitions, ledger primitives, and `IterativeArena`.
|
|
26
|
+
Both entries are part of the same release unit.
|
|
27
|
+
|
|
28
|
+
## Composition
|
|
29
|
+
|
|
30
|
+
```ts
|
|
31
|
+
import { Engine } from "@cjhyy/code-shell-core";
|
|
32
|
+
import { createArenaCapability } from "@cjhyy/code-shell-arena/runtime";
|
|
33
|
+
|
|
34
|
+
const engine = new Engine({
|
|
35
|
+
llm: {
|
|
36
|
+
provider: "openai",
|
|
37
|
+
model: "openai/gpt-5.4",
|
|
38
|
+
apiKey: process.env.OPENAI_API_KEY!,
|
|
39
|
+
},
|
|
40
|
+
capabilities: [createArenaCapability()],
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## License
|
|
45
|
+
|
|
46
|
+
MIT.
|
package/dist/arena.d.ts
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arena — multi-model collaborative analysis engine.
|
|
3
|
+
*
|
|
4
|
+
* Evidence-Driven Pipeline:
|
|
5
|
+
* 0. Planner → understand what the user wants (mode, lenses, sources)
|
|
6
|
+
* 1. EvidenceProviders → collect artifacts from selected sources
|
|
7
|
+
* 2. Strategy + Lens → compose prompts (mode flow + perspective)
|
|
8
|
+
* 3. ToolSelector → determine which tools participants can use
|
|
9
|
+
* 4. ParticipantResearch → each model investigates independently (parallel)
|
|
10
|
+
* 4b. ClaimRegistry → register findings as claims, populate ledger
|
|
11
|
+
* 5. VerificationReview → claim-aware cross-review with evidence digests
|
|
12
|
+
* 7. DebateRounds → contested claims enter structured debate
|
|
13
|
+
* 8. Adjudication → moderator rules on contested claims
|
|
14
|
+
* 6. ConsensusBuilder → claim-aware structured consensus
|
|
15
|
+
*/
|
|
16
|
+
import type { ArenaConfig, ArenaResultV2 } from "./types.js";
|
|
17
|
+
import type { PlannerFlags } from "./planner.js";
|
|
18
|
+
export declare class Arena {
|
|
19
|
+
private config;
|
|
20
|
+
private strategy;
|
|
21
|
+
private limits;
|
|
22
|
+
private usage;
|
|
23
|
+
private readonly recordUsage;
|
|
24
|
+
constructor(config: ArenaConfig);
|
|
25
|
+
/**
|
|
26
|
+
* Run a full arena session.
|
|
27
|
+
*
|
|
28
|
+
* @param topic - User's topic/request (natural language)
|
|
29
|
+
* @param flags - Optional explicit overrides (mode, base, head)
|
|
30
|
+
*/
|
|
31
|
+
run(topic: string, flags?: PlannerFlags): Promise<ArenaResultV2>;
|
|
32
|
+
/**
|
|
33
|
+
* Planning path: merge-oriented review → roadmap consensus → detail expansion.
|
|
34
|
+
*
|
|
35
|
+
* Planning mode does NOT enter heavy debate/adjudication. Contested findings
|
|
36
|
+
* are converted to open questions or dependency risks in the roadmap.
|
|
37
|
+
*/
|
|
38
|
+
private runPlanningPath;
|
|
39
|
+
/**
|
|
40
|
+
* Review/Discussion path: verification review → debate → adjudication → consensus.
|
|
41
|
+
*
|
|
42
|
+
* This is the heavy trust loop for claim verification.
|
|
43
|
+
*/
|
|
44
|
+
private runReviewDiscussionPath;
|
|
45
|
+
}
|
package/dist/arena.js
ADDED
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arena — multi-model collaborative analysis engine.
|
|
3
|
+
*
|
|
4
|
+
* Evidence-Driven Pipeline:
|
|
5
|
+
* 0. Planner → understand what the user wants (mode, lenses, sources)
|
|
6
|
+
* 1. EvidenceProviders → collect artifacts from selected sources
|
|
7
|
+
* 2. Strategy + Lens → compose prompts (mode flow + perspective)
|
|
8
|
+
* 3. ToolSelector → determine which tools participants can use
|
|
9
|
+
* 4. ParticipantResearch → each model investigates independently (parallel)
|
|
10
|
+
* 4b. ClaimRegistry → register findings as claims, populate ledger
|
|
11
|
+
* 5. VerificationReview → claim-aware cross-review with evidence digests
|
|
12
|
+
* 7. DebateRounds → contested claims enter structured debate
|
|
13
|
+
* 8. Adjudication → moderator rules on contested claims
|
|
14
|
+
* 6. ConsensusBuilder → claim-aware structured consensus
|
|
15
|
+
*/
|
|
16
|
+
import { logger } from "@cjhyy/code-shell-core/extension";
|
|
17
|
+
import { ARENA_MODE_DEFAULTS, DEFAULT_EXECUTION_LIMITS, isStrategyPlanning } from "./types.js";
|
|
18
|
+
import { getStrategy, getStrategyForPlan } from "./strategies/index.js";
|
|
19
|
+
import { planArena } from "./planner.js";
|
|
20
|
+
import { collectEvidence } from "./providers/index.js";
|
|
21
|
+
import { selectTools } from "./tools/selector.js";
|
|
22
|
+
import { runParticipantResearchWithDossiers } from "./phases/participant-research.js";
|
|
23
|
+
import { runVerificationReview } from "./phases/cross-review.js";
|
|
24
|
+
import { runDebateRounds } from "./phases/debate-rounds.js";
|
|
25
|
+
import { runAdjudication } from "./phases/adjudication.js";
|
|
26
|
+
import { buildConsensus } from "./phases/build-consensus.js";
|
|
27
|
+
import { runDetailExpansion } from "./phases/planning-detail-expansion.js";
|
|
28
|
+
import { withLanguage } from "./strategies/language-wrapper.js";
|
|
29
|
+
import { ArenaLedger } from "./ledger.js";
|
|
30
|
+
import { registerClaims } from "./phases/claim-registry.js";
|
|
31
|
+
import { addTokenUsage } from "@cjhyy/code-shell-core/extension";
|
|
32
|
+
/** Bucket claims by status. Shared by the two consensus phases. */
|
|
33
|
+
function summarizeClaims(all) {
|
|
34
|
+
return {
|
|
35
|
+
verified: all.filter((c) => c.status === "verified"),
|
|
36
|
+
contested: all.filter((c) => c.status === "contested"),
|
|
37
|
+
unresolved: all.filter((c) => c.status === "unresolved"),
|
|
38
|
+
rejected: all.filter((c) => c.status === "rejected"),
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
export class Arena {
|
|
42
|
+
config;
|
|
43
|
+
strategy;
|
|
44
|
+
limits;
|
|
45
|
+
usage = {
|
|
46
|
+
promptTokens: 0,
|
|
47
|
+
completionTokens: 0,
|
|
48
|
+
totalTokens: 0,
|
|
49
|
+
cacheReadTokens: 0,
|
|
50
|
+
cacheCreationTokens: 0,
|
|
51
|
+
};
|
|
52
|
+
recordUsage = (usage) => {
|
|
53
|
+
if (usage)
|
|
54
|
+
this.usage = addTokenUsage(this.usage, usage);
|
|
55
|
+
};
|
|
56
|
+
constructor(config) {
|
|
57
|
+
if (config.participants.length < 2) {
|
|
58
|
+
throw new Error("Arena requires at least 2 participants");
|
|
59
|
+
}
|
|
60
|
+
const mode = config.mode ?? "review";
|
|
61
|
+
const defaults = ARENA_MODE_DEFAULTS[mode];
|
|
62
|
+
this.config = {
|
|
63
|
+
mode,
|
|
64
|
+
maxDiscussionRounds: config.maxDiscussionRounds ?? defaults.maxDiscussionRounds,
|
|
65
|
+
...config,
|
|
66
|
+
};
|
|
67
|
+
this.limits = config.executionLimits ?? DEFAULT_EXECUTION_LIMITS;
|
|
68
|
+
// Initial strategy — will be overridden in run() with lens + language wrappers
|
|
69
|
+
this.strategy = config.strategy ?? getStrategy(mode);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Run a full arena session.
|
|
73
|
+
*
|
|
74
|
+
* @param topic - User's topic/request (natural language)
|
|
75
|
+
* @param flags - Optional explicit overrides (mode, base, head)
|
|
76
|
+
*/
|
|
77
|
+
async run(topic, flags) {
|
|
78
|
+
this.usage = {
|
|
79
|
+
promptTokens: 0,
|
|
80
|
+
completionTokens: 0,
|
|
81
|
+
totalTokens: 0,
|
|
82
|
+
cacheReadTokens: 0,
|
|
83
|
+
cacheCreationTokens: 0,
|
|
84
|
+
};
|
|
85
|
+
const participantNames = this.config.participants.map((p) => p.name);
|
|
86
|
+
const signal = this.config.signal;
|
|
87
|
+
logger.info("arena.start", { mode: this.config.mode, participants: participantNames });
|
|
88
|
+
signal?.throwIfAborted();
|
|
89
|
+
// ─── Phase 0: Plan ────────────────────────────────────────
|
|
90
|
+
const llmConfig = this.config.participants[0].llm;
|
|
91
|
+
const plan = await planArena(topic, llmConfig, flags, signal, this.recordUsage);
|
|
92
|
+
this.config.onProgress?.({ type: "plan_resolved", plan });
|
|
93
|
+
logger.info("arena.plan", {
|
|
94
|
+
mode: plan.mode,
|
|
95
|
+
lenses: plan.lenses.map((l) => l.name),
|
|
96
|
+
sources: plan.sources.map((s) => s.kind),
|
|
97
|
+
subject: plan.subject.label,
|
|
98
|
+
confidence: plan.confidence,
|
|
99
|
+
});
|
|
100
|
+
if (!flags?.mode && plan.mode !== this.config.mode) {
|
|
101
|
+
this.config.mode = plan.mode;
|
|
102
|
+
}
|
|
103
|
+
signal?.throwIfAborted();
|
|
104
|
+
// ─── Phase 1: Collect Evidence ────────────────────────────
|
|
105
|
+
// Bridge collectEvidence's lifecycle events to the public
|
|
106
|
+
// ArenaProgressEvent stream so the UI sees "collecting from
|
|
107
|
+
// repo..." instead of a silent pause.
|
|
108
|
+
const onProgress = this.config.onProgress;
|
|
109
|
+
const { artifacts, quickFacts } = await collectEvidence(plan, topic, {
|
|
110
|
+
signal,
|
|
111
|
+
onProgress: (e) => {
|
|
112
|
+
if (e.type === "evidence_started") {
|
|
113
|
+
onProgress?.({ type: "evidence_started", source: e.source });
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
onProgress?.({
|
|
117
|
+
type: "evidence_source_done",
|
|
118
|
+
source: e.source,
|
|
119
|
+
count: e.count ?? 0,
|
|
120
|
+
durationMs: e.durationMs ?? 0,
|
|
121
|
+
timedOut: e.timedOut ?? false,
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
},
|
|
125
|
+
});
|
|
126
|
+
onProgress?.({ type: "evidence_collected", artifacts });
|
|
127
|
+
logger.info("arena.evidence", {
|
|
128
|
+
artifactCount: artifacts.length,
|
|
129
|
+
sources: plan.sources.map((s) => s.kind),
|
|
130
|
+
});
|
|
131
|
+
const baseContext = { plan, artifacts, quickFacts };
|
|
132
|
+
// ─── Phase 2: Compose Strategy ────────────────────────────
|
|
133
|
+
this.strategy = this.config.strategy ?? getStrategyForPlan(plan);
|
|
134
|
+
this.strategy = withLanguage(this.strategy, topic);
|
|
135
|
+
// ─── Phase 3: Select Tools ────────────────────────────────
|
|
136
|
+
const contextTools = this.config.enableContextTools !== false
|
|
137
|
+
? selectTools(plan)
|
|
138
|
+
: undefined;
|
|
139
|
+
signal?.throwIfAborted();
|
|
140
|
+
// ─── Phase 4: Participant Research (parallel) ─────────────
|
|
141
|
+
logger.info("arena.research_phase", { participants: participantNames });
|
|
142
|
+
const researchResults = await runParticipantResearchWithDossiers({
|
|
143
|
+
participants: this.config.participants,
|
|
144
|
+
strategy: this.strategy,
|
|
145
|
+
topic,
|
|
146
|
+
baseContext,
|
|
147
|
+
enableContextTools: this.config.enableContextTools ?? true,
|
|
148
|
+
contextTools,
|
|
149
|
+
signal,
|
|
150
|
+
onProgress: this.config.onProgress,
|
|
151
|
+
onUsage: this.recordUsage,
|
|
152
|
+
});
|
|
153
|
+
const reports = researchResults.map((r) => r.report);
|
|
154
|
+
const dossiers = researchResults.map((r) => r.dossier);
|
|
155
|
+
signal?.throwIfAborted();
|
|
156
|
+
// ─── Phase 4b: Claim Registry ─────────────────────────────
|
|
157
|
+
const ledger = new ArenaLedger();
|
|
158
|
+
// Populate ledger with dossiers
|
|
159
|
+
for (const dossier of dossiers) {
|
|
160
|
+
ledger.appendDossier(dossier);
|
|
161
|
+
}
|
|
162
|
+
// Register findings as claims
|
|
163
|
+
const claims = registerClaims({
|
|
164
|
+
dossiers,
|
|
165
|
+
ledger,
|
|
166
|
+
onProgress: this.config.onProgress,
|
|
167
|
+
});
|
|
168
|
+
logger.info("arena.claims_registered", {
|
|
169
|
+
claimCount: claims.length,
|
|
170
|
+
byOwner: Object.fromEntries(participantNames.map((name) => [
|
|
171
|
+
name,
|
|
172
|
+
claims.filter((c) => c.owner === name).length,
|
|
173
|
+
])),
|
|
174
|
+
});
|
|
175
|
+
signal?.throwIfAborted();
|
|
176
|
+
// ─── Phase 5: Mode Policy Router ─────────────────────────
|
|
177
|
+
//
|
|
178
|
+
// Planning mode: merge-oriented review → roadmap consensus → detail expansion
|
|
179
|
+
// Review/Discussion mode: verification review → debate → adjudication → consensus
|
|
180
|
+
const concluderName = this.config.concluder ?? participantNames[0];
|
|
181
|
+
const concluderMatch = this.config.participants.find((p) => p.name === concluderName);
|
|
182
|
+
if (!concluderMatch && this.config.concluder) {
|
|
183
|
+
logger.warn("arena.concluder_not_found", {
|
|
184
|
+
requested: this.config.concluder,
|
|
185
|
+
fallback: this.config.participants[0].name,
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
const concluder = concluderMatch ?? this.config.participants[0];
|
|
189
|
+
const enableTools = this.config.enableContextTools !== false;
|
|
190
|
+
if (this.config.mode === "planning") {
|
|
191
|
+
return this.runPlanningPath({
|
|
192
|
+
topic, participantNames, plan, baseContext, reports, dossiers, ledger,
|
|
193
|
+
concluder, contextTools, enableContextTools: enableTools, signal,
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
return this.runReviewDiscussionPath({
|
|
197
|
+
topic, participantNames, plan, baseContext, reports, dossiers, ledger, concluder, signal,
|
|
198
|
+
});
|
|
199
|
+
}
|
|
200
|
+
/**
|
|
201
|
+
* Planning path: merge-oriented review → roadmap consensus → detail expansion.
|
|
202
|
+
*
|
|
203
|
+
* Planning mode does NOT enter heavy debate/adjudication. Contested findings
|
|
204
|
+
* are converted to open questions or dependency risks in the roadmap.
|
|
205
|
+
*/
|
|
206
|
+
async runPlanningPath(ctx) {
|
|
207
|
+
const { topic, participantNames, plan, baseContext, reports, dossiers, ledger, concluder, contextTools, enableContextTools, signal, } = ctx;
|
|
208
|
+
// ─── Merge-Oriented Review ───────────────────────────────
|
|
209
|
+
logger.info("arena.planning_merge_review_phase");
|
|
210
|
+
const { reviews } = await runVerificationReview({
|
|
211
|
+
participants: this.config.participants,
|
|
212
|
+
strategy: this.strategy,
|
|
213
|
+
topic,
|
|
214
|
+
reports,
|
|
215
|
+
ledger,
|
|
216
|
+
limits: this.limits,
|
|
217
|
+
mode: "planning",
|
|
218
|
+
signal,
|
|
219
|
+
onProgress: this.config.onProgress,
|
|
220
|
+
onUsage: this.recordUsage,
|
|
221
|
+
});
|
|
222
|
+
signal?.throwIfAborted();
|
|
223
|
+
// ─── Roadmap Consensus ───────────────────────────────────
|
|
224
|
+
const allClaims = ledger.getAllClaims();
|
|
225
|
+
const claimSummary = summarizeClaims(allClaims);
|
|
226
|
+
logger.info("arena.planning_consensus_phase", { concluder: concluder.name });
|
|
227
|
+
const consensus = await buildConsensus({
|
|
228
|
+
concluder,
|
|
229
|
+
strategy: this.strategy,
|
|
230
|
+
topic,
|
|
231
|
+
reports,
|
|
232
|
+
reviews,
|
|
233
|
+
claimSummary,
|
|
234
|
+
signal,
|
|
235
|
+
onProgress: this.config.onProgress,
|
|
236
|
+
onUsage: this.recordUsage,
|
|
237
|
+
});
|
|
238
|
+
signal?.throwIfAborted();
|
|
239
|
+
// ─── Detail Expansion ────────────────────────────────────
|
|
240
|
+
if (consensus.roadmap.length > 0 && isStrategyPlanning(this.strategy)) {
|
|
241
|
+
logger.info("arena.detail_expansion_phase", { phaseCount: consensus.roadmap.length });
|
|
242
|
+
try {
|
|
243
|
+
const details = await runDetailExpansion({
|
|
244
|
+
concluder,
|
|
245
|
+
strategy: this.strategy,
|
|
246
|
+
topic,
|
|
247
|
+
phases: consensus.roadmap,
|
|
248
|
+
ledger,
|
|
249
|
+
limits: this.limits,
|
|
250
|
+
enableContextTools,
|
|
251
|
+
contextTools,
|
|
252
|
+
signal,
|
|
253
|
+
onProgress: this.config.onProgress,
|
|
254
|
+
onUsage: this.recordUsage,
|
|
255
|
+
});
|
|
256
|
+
consensus.roadmapDetails = details;
|
|
257
|
+
}
|
|
258
|
+
catch (err) {
|
|
259
|
+
// Detail expansion is non-critical — degrade gracefully
|
|
260
|
+
logger.warn("arena.detail_expansion_failed", {
|
|
261
|
+
error: err.message,
|
|
262
|
+
phaseCount: consensus.roadmap.length,
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
return {
|
|
267
|
+
topic,
|
|
268
|
+
mode: this.config.mode,
|
|
269
|
+
participants: participantNames,
|
|
270
|
+
plan,
|
|
271
|
+
baseContext,
|
|
272
|
+
reports,
|
|
273
|
+
dossiers,
|
|
274
|
+
claims: allClaims,
|
|
275
|
+
reviews,
|
|
276
|
+
consensus,
|
|
277
|
+
usage: { ...this.usage },
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Review/Discussion path: verification review → debate → adjudication → consensus.
|
|
282
|
+
*
|
|
283
|
+
* This is the heavy trust loop for claim verification.
|
|
284
|
+
*/
|
|
285
|
+
async runReviewDiscussionPath(ctx) {
|
|
286
|
+
const { topic, participantNames, plan, baseContext, reports, dossiers, ledger, concluder, signal } = ctx;
|
|
287
|
+
// ─── Verification Review (parallel) ──────────────────────
|
|
288
|
+
logger.info("arena.verification_review_phase");
|
|
289
|
+
const { reviews } = await runVerificationReview({
|
|
290
|
+
participants: this.config.participants,
|
|
291
|
+
strategy: this.strategy,
|
|
292
|
+
topic,
|
|
293
|
+
reports,
|
|
294
|
+
ledger,
|
|
295
|
+
limits: this.limits,
|
|
296
|
+
signal,
|
|
297
|
+
onProgress: this.config.onProgress,
|
|
298
|
+
onUsage: this.recordUsage,
|
|
299
|
+
});
|
|
300
|
+
signal?.throwIfAborted();
|
|
301
|
+
// ─── Debate Rounds ───────────────────────────────────────
|
|
302
|
+
logger.info("arena.debate_phase");
|
|
303
|
+
const debateRounds = await runDebateRounds({
|
|
304
|
+
participants: this.config.participants,
|
|
305
|
+
strategy: this.strategy,
|
|
306
|
+
topic,
|
|
307
|
+
ledger,
|
|
308
|
+
limits: this.limits,
|
|
309
|
+
maxRounds: this.config.maxDiscussionRounds,
|
|
310
|
+
signal,
|
|
311
|
+
onProgress: this.config.onProgress,
|
|
312
|
+
onUsage: this.recordUsage,
|
|
313
|
+
});
|
|
314
|
+
signal?.throwIfAborted();
|
|
315
|
+
// ─── Adjudication ────────────────────────────────────────
|
|
316
|
+
logger.info("arena.adjudication_phase", { concluder: concluder.name });
|
|
317
|
+
const adjudications = await runAdjudication({
|
|
318
|
+
concluder,
|
|
319
|
+
strategy: this.strategy,
|
|
320
|
+
topic,
|
|
321
|
+
ledger,
|
|
322
|
+
signal,
|
|
323
|
+
onProgress: this.config.onProgress,
|
|
324
|
+
onUsage: this.recordUsage,
|
|
325
|
+
});
|
|
326
|
+
signal?.throwIfAborted();
|
|
327
|
+
// ─── Consensus (claim-aware) ─────────────────────────────
|
|
328
|
+
const allClaims = ledger.getAllClaims();
|
|
329
|
+
const claimSummary = summarizeClaims(allClaims);
|
|
330
|
+
logger.info("arena.consensus_phase", {
|
|
331
|
+
concluder: concluder.name,
|
|
332
|
+
verified: claimSummary.verified.length,
|
|
333
|
+
unresolved: claimSummary.unresolved.length,
|
|
334
|
+
});
|
|
335
|
+
const consensus = await buildConsensus({
|
|
336
|
+
concluder,
|
|
337
|
+
strategy: this.strategy,
|
|
338
|
+
topic,
|
|
339
|
+
reports,
|
|
340
|
+
reviews,
|
|
341
|
+
claimSummary,
|
|
342
|
+
signal,
|
|
343
|
+
onProgress: this.config.onProgress,
|
|
344
|
+
onUsage: this.recordUsage,
|
|
345
|
+
});
|
|
346
|
+
return {
|
|
347
|
+
topic,
|
|
348
|
+
mode: this.config.mode,
|
|
349
|
+
participants: participantNames,
|
|
350
|
+
plan,
|
|
351
|
+
baseContext,
|
|
352
|
+
reports,
|
|
353
|
+
dossiers,
|
|
354
|
+
claims: allClaims,
|
|
355
|
+
reviews,
|
|
356
|
+
debateRounds,
|
|
357
|
+
adjudications,
|
|
358
|
+
consensus,
|
|
359
|
+
usage: { ...this.usage },
|
|
360
|
+
};
|
|
361
|
+
}
|
|
362
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in Arena tool — multi-model collaborative analysis.
|
|
3
|
+
*
|
|
4
|
+
* Launches an arena session where multiple LLM participants independently
|
|
5
|
+
* research a topic, cross-review each other's findings, and build consensus.
|
|
6
|
+
*
|
|
7
|
+
* The LLM config (baseUrl, apiKey) is injected at runtime by the Engine via
|
|
8
|
+
* setArenaLLMConfig(), following the same pattern as setAskUserFn() and
|
|
9
|
+
* setSubAgentConfig().
|
|
10
|
+
*/
|
|
11
|
+
import { type ExtensionModule, type ToolContext, type ToolDefinition } from "@cjhyy/code-shell-core/extension";
|
|
12
|
+
import { z } from "zod";
|
|
13
|
+
export declare const arenaToolDef: ToolDefinition;
|
|
14
|
+
/**
|
|
15
|
+
* Snapshot of what Arena would do right now if invoked. Used by the
|
|
16
|
+
* `/arena` REPL command (via the protocol `arena_status` query) so
|
|
17
|
+
* users can see participants/endpoint before launching a run.
|
|
18
|
+
*/
|
|
19
|
+
export interface ArenaStatus {
|
|
20
|
+
endpoint?: string;
|
|
21
|
+
defaultParticipants: Array<{
|
|
22
|
+
name: string;
|
|
23
|
+
model: string;
|
|
24
|
+
source: "pool" | "preset" | "raw";
|
|
25
|
+
compatible: boolean;
|
|
26
|
+
reason?: string;
|
|
27
|
+
}>;
|
|
28
|
+
poolSize: number;
|
|
29
|
+
}
|
|
30
|
+
export declare function getArenaStatus(): ArenaStatus;
|
|
31
|
+
/** Persist the capability-owned settings namespace; legacy `arena.*` remains read-only. */
|
|
32
|
+
export declare function saveArenaSettingsByKeys(keys: string[]): void;
|
|
33
|
+
/** Package-owned schema for the optional capability settings namespace. */
|
|
34
|
+
export declare const ArenaCapabilitySettingsSchema: z.ZodObject<{
|
|
35
|
+
participants: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
36
|
+
}, "passthrough", z.ZodTypeAny, z.objectOutputType<{
|
|
37
|
+
participants: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
38
|
+
}, z.ZodTypeAny, "passthrough">, z.objectInputType<{
|
|
39
|
+
participants: z.ZodDefault<z.ZodArray<z.ZodString, "many">>;
|
|
40
|
+
}, z.ZodTypeAny, "passthrough">>;
|
|
41
|
+
export declare function arenaTool(args: Record<string, unknown>, ctx?: ToolContext): Promise<string>;
|
|
42
|
+
/** Create the explicit Arena product capability. Core does not import this package. */
|
|
43
|
+
export declare function createArenaCapability(): ExtensionModule;
|