@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
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claim state machine — centralized transition rules.
|
|
3
|
+
*
|
|
4
|
+
* All claim status changes go through this module to enforce
|
|
5
|
+
* consistent state transitions across phases.
|
|
6
|
+
*
|
|
7
|
+
* State machine:
|
|
8
|
+
* proposed → under_review | unresolved
|
|
9
|
+
* under_review → verified | contested | rejected | unresolved
|
|
10
|
+
* contested → under_review | unresolved | verified | rejected
|
|
11
|
+
*
|
|
12
|
+
* `unresolved` is reachable from proposed/under_review (not just contested):
|
|
13
|
+
* adjudication sweeps any claims left in those states when the round/budget
|
|
14
|
+
* is exhausted (adjudication.ts) — without these edges markUnresolved() would
|
|
15
|
+
* silently no-op and the claims would be dropped from the consensus summary.
|
|
16
|
+
*/
|
|
17
|
+
import type { ClaimRecord, ClaimStatus, ClaimChallenge } from "./types.js";
|
|
18
|
+
/**
|
|
19
|
+
* Attempt to transition a claim to a new status.
|
|
20
|
+
* Returns true if the transition was applied, false if invalid.
|
|
21
|
+
*/
|
|
22
|
+
export declare function transitionClaim(claim: ClaimRecord, to: ClaimStatus): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Determine the next status for a claim based on its challenges.
|
|
25
|
+
*
|
|
26
|
+
* Rules:
|
|
27
|
+
* - No challenges → stays as-is (unreviewed is NOT verified)
|
|
28
|
+
* - Any "disagree" → contested
|
|
29
|
+
* - Any "needs_evidence" → contested
|
|
30
|
+
* - Pending checks exist → contested
|
|
31
|
+
* - At least one explicit "agree" and all others "agree"/"refine" → verified
|
|
32
|
+
*/
|
|
33
|
+
export declare function resolveClaimStatus(claim: ClaimRecord, challenges: ClaimChallenge[], hasPendingChecks: boolean): ClaimStatus;
|
|
34
|
+
/**
|
|
35
|
+
* Mark a claim as entering review.
|
|
36
|
+
*/
|
|
37
|
+
export declare function markUnderReview(claim: ClaimRecord): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Apply review results to a claim and transition appropriately.
|
|
40
|
+
*/
|
|
41
|
+
export declare function applyReviewResult(claim: ClaimRecord, challenges: ClaimChallenge[], hasPendingChecks: boolean): void;
|
|
42
|
+
/**
|
|
43
|
+
* Mark a contested claim as unresolved (budget/round exhausted).
|
|
44
|
+
*/
|
|
45
|
+
export declare function markUnresolved(claim: ClaimRecord): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Check if a claim is in a terminal state (no further transitions possible).
|
|
48
|
+
*/
|
|
49
|
+
export declare function isTerminal(claim: ClaimRecord): boolean;
|
|
50
|
+
/**
|
|
51
|
+
* Get valid next statuses for a claim.
|
|
52
|
+
*/
|
|
53
|
+
export declare function validTransitions(claim: ClaimRecord): ClaimStatus[];
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claim state machine — centralized transition rules.
|
|
3
|
+
*
|
|
4
|
+
* All claim status changes go through this module to enforce
|
|
5
|
+
* consistent state transitions across phases.
|
|
6
|
+
*
|
|
7
|
+
* State machine:
|
|
8
|
+
* proposed → under_review | unresolved
|
|
9
|
+
* under_review → verified | contested | rejected | unresolved
|
|
10
|
+
* contested → under_review | unresolved | verified | rejected
|
|
11
|
+
*
|
|
12
|
+
* `unresolved` is reachable from proposed/under_review (not just contested):
|
|
13
|
+
* adjudication sweeps any claims left in those states when the round/budget
|
|
14
|
+
* is exhausted (adjudication.ts) — without these edges markUnresolved() would
|
|
15
|
+
* silently no-op and the claims would be dropped from the consensus summary.
|
|
16
|
+
*/
|
|
17
|
+
/** Valid transitions from each status */
|
|
18
|
+
const VALID_TRANSITIONS = {
|
|
19
|
+
proposed: ["under_review", "unresolved"],
|
|
20
|
+
under_review: ["verified", "contested", "rejected", "unresolved"],
|
|
21
|
+
contested: ["under_review", "unresolved", "verified", "rejected"],
|
|
22
|
+
verified: [],
|
|
23
|
+
rejected: [],
|
|
24
|
+
unresolved: [],
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Attempt to transition a claim to a new status.
|
|
28
|
+
* Returns true if the transition was applied, false if invalid.
|
|
29
|
+
*/
|
|
30
|
+
export function transitionClaim(claim, to) {
|
|
31
|
+
const allowed = VALID_TRANSITIONS[claim.status];
|
|
32
|
+
if (!allowed.includes(to)) {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
claim.status = to;
|
|
36
|
+
return true;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Determine the next status for a claim based on its challenges.
|
|
40
|
+
*
|
|
41
|
+
* Rules:
|
|
42
|
+
* - No challenges → stays as-is (unreviewed is NOT verified)
|
|
43
|
+
* - Any "disagree" → contested
|
|
44
|
+
* - Any "needs_evidence" → contested
|
|
45
|
+
* - Pending checks exist → contested
|
|
46
|
+
* - At least one explicit "agree" and all others "agree"/"refine" → verified
|
|
47
|
+
*/
|
|
48
|
+
export function resolveClaimStatus(claim, challenges, hasPendingChecks) {
|
|
49
|
+
// No challenges = no review happened — do not auto-verify
|
|
50
|
+
if (challenges.length === 0)
|
|
51
|
+
return claim.status;
|
|
52
|
+
const verdicts = challenges.map((c) => c.verdict);
|
|
53
|
+
if (verdicts.includes("disagree") || verdicts.includes("needs_evidence")) {
|
|
54
|
+
return "contested";
|
|
55
|
+
}
|
|
56
|
+
if (hasPendingChecks) {
|
|
57
|
+
return "contested";
|
|
58
|
+
}
|
|
59
|
+
// Require at least one explicit "agree" to mark as verified
|
|
60
|
+
// (not just all "refine" with no agreement)
|
|
61
|
+
if (verdicts.includes("agree")) {
|
|
62
|
+
return "verified";
|
|
63
|
+
}
|
|
64
|
+
// All "refine" without any "agree" — keep under review, not yet verified
|
|
65
|
+
return claim.status;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Mark a claim as entering review.
|
|
69
|
+
*/
|
|
70
|
+
export function markUnderReview(claim) {
|
|
71
|
+
return transitionClaim(claim, "under_review");
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Apply review results to a claim and transition appropriately.
|
|
75
|
+
*/
|
|
76
|
+
export function applyReviewResult(claim, challenges, hasPendingChecks) {
|
|
77
|
+
const nextStatus = resolveClaimStatus(claim, challenges, hasPendingChecks);
|
|
78
|
+
transitionClaim(claim, nextStatus);
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Mark a contested claim as unresolved (budget/round exhausted).
|
|
82
|
+
*/
|
|
83
|
+
export function markUnresolved(claim) {
|
|
84
|
+
return transitionClaim(claim, "unresolved");
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Check if a claim is in a terminal state (no further transitions possible).
|
|
88
|
+
*/
|
|
89
|
+
export function isTerminal(claim) {
|
|
90
|
+
return VALID_TRANSITIONS[claim.status].length === 0;
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get valid next statuses for a claim.
|
|
94
|
+
*/
|
|
95
|
+
export function validTransitions(claim) {
|
|
96
|
+
return VALID_TRANSITIONS[claim.status];
|
|
97
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,518 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arena types — multi-model review, discussion, and planning.
|
|
3
|
+
*
|
|
4
|
+
* V2 architecture: shared facts → independent research → findings → cross-review → consensus.
|
|
5
|
+
*/
|
|
6
|
+
import type { ClientDefaults, LLMConfig, TokenUsage } from "@cjhyy/code-shell-core/extension";
|
|
7
|
+
/** Receives usage for each completed Arena provider request. */
|
|
8
|
+
export type ArenaUsageRecorder = (usage: TokenUsage | undefined) => void;
|
|
9
|
+
/** Arena operating mode — determines prompts, output format, and default rounds */
|
|
10
|
+
export type ArenaMode = "review" | "discussion" | "planning";
|
|
11
|
+
/** Analysis lens — the perspective from which participants analyze */
|
|
12
|
+
export type ArenaLensName = "engineering" | "product" | "architecture" | "general";
|
|
13
|
+
/** Lens reference with optional weight for multi-lens scenarios */
|
|
14
|
+
export interface ArenaLensRef {
|
|
15
|
+
name: ArenaLensName;
|
|
16
|
+
weight?: number;
|
|
17
|
+
}
|
|
18
|
+
/** A lens defines roles, criteria, and emphasis for a given perspective */
|
|
19
|
+
export interface ArenaLens {
|
|
20
|
+
name: ArenaLensName;
|
|
21
|
+
label: string;
|
|
22
|
+
participantRole: string;
|
|
23
|
+
reviewerRole: string;
|
|
24
|
+
moderatorRole: string;
|
|
25
|
+
summaryLabel: string;
|
|
26
|
+
criteria: string[];
|
|
27
|
+
preferredFindingKinds: FindingKind[];
|
|
28
|
+
}
|
|
29
|
+
/** Evidence source kind — where to collect facts */
|
|
30
|
+
export type ArenaSourceKind = "git" | "repo" | "docs" | "web" | "none";
|
|
31
|
+
/** Source specification with optional targets and tool pack */
|
|
32
|
+
export interface ArenaSourceSpec {
|
|
33
|
+
kind: ArenaSourceKind;
|
|
34
|
+
targets?: string[];
|
|
35
|
+
toolPack?: string;
|
|
36
|
+
}
|
|
37
|
+
/** Subject of the arena session */
|
|
38
|
+
export interface ArenaSubject {
|
|
39
|
+
kind: "changes" | "files" | "docs" | "topic" | "mixed";
|
|
40
|
+
label: string;
|
|
41
|
+
targets?: string[];
|
|
42
|
+
}
|
|
43
|
+
/** Output shape hints for rendering */
|
|
44
|
+
export interface ArenaOutputShape {
|
|
45
|
+
overviewLabel: string;
|
|
46
|
+
emphasize: Array<"strength" | "improvement" | "risk" | "question">;
|
|
47
|
+
}
|
|
48
|
+
/** The full plan produced by the Planner — drives the entire pipeline */
|
|
49
|
+
export interface ArenaPlan {
|
|
50
|
+
mode: ArenaMode;
|
|
51
|
+
lenses: ArenaLensRef[];
|
|
52
|
+
sources: ArenaSourceSpec[];
|
|
53
|
+
subject: ArenaSubject;
|
|
54
|
+
outputShape: ArenaOutputShape;
|
|
55
|
+
confidence: "high" | "medium" | "low";
|
|
56
|
+
followUpQuestion?: string;
|
|
57
|
+
}
|
|
58
|
+
/** Unified artifact — all providers output this, replacing codeFacts/gitFacts split */
|
|
59
|
+
export interface ArenaArtifact {
|
|
60
|
+
id: string;
|
|
61
|
+
kind: "diff" | "file" | "tree" | "grep" | "doc" | "web";
|
|
62
|
+
source: ArenaSourceKind;
|
|
63
|
+
title: string;
|
|
64
|
+
ref?: string;
|
|
65
|
+
preview: string;
|
|
66
|
+
metadata?: Record<string, unknown>;
|
|
67
|
+
}
|
|
68
|
+
/** Tool pack — a named set of tools available during research */
|
|
69
|
+
export interface ArenaToolPack {
|
|
70
|
+
name: string;
|
|
71
|
+
toolNames: string[];
|
|
72
|
+
}
|
|
73
|
+
/** Context provider interface — collects evidence from a source */
|
|
74
|
+
export interface ArenaContextProvider {
|
|
75
|
+
kind: ArenaSourceKind;
|
|
76
|
+
collect(plan: ArenaPlan, topic: string): ArenaArtifact[] | Promise<ArenaArtifact[]>;
|
|
77
|
+
}
|
|
78
|
+
/** Quick fact — high-signal summary entry */
|
|
79
|
+
export interface ArenaQuickFact {
|
|
80
|
+
label: string;
|
|
81
|
+
value: string;
|
|
82
|
+
}
|
|
83
|
+
/** Default max discussion rounds per mode */
|
|
84
|
+
export declare const ARENA_MODE_DEFAULTS: Record<ArenaMode, {
|
|
85
|
+
maxDiscussionRounds: number;
|
|
86
|
+
convergenceThreshold: number;
|
|
87
|
+
}>;
|
|
88
|
+
/** A participant in the arena (a model instance) */
|
|
89
|
+
export interface ArenaParticipant {
|
|
90
|
+
/** Display name, e.g. "Claude Sonnet", "GPT-4o" */
|
|
91
|
+
name: string;
|
|
92
|
+
/** LLM config for this participant (pure model identity) */
|
|
93
|
+
llm: LLMConfig;
|
|
94
|
+
/**
|
|
95
|
+
* Cross-model client knobs (temperature/timeout/etc.). Arena hardcodes
|
|
96
|
+
* temperature here so debate participants speak with consistent sampling
|
|
97
|
+
* regardless of the user's session preference.
|
|
98
|
+
*/
|
|
99
|
+
clientDefaults?: ClientDefaults;
|
|
100
|
+
}
|
|
101
|
+
export interface ArenaBaseContext {
|
|
102
|
+
/** Evidence-driven plan that drives the session */
|
|
103
|
+
plan: ArenaPlan;
|
|
104
|
+
/** Unified artifacts from all providers */
|
|
105
|
+
artifacts: ArenaArtifact[];
|
|
106
|
+
/** High-signal summary facts */
|
|
107
|
+
quickFacts: ArenaQuickFact[];
|
|
108
|
+
}
|
|
109
|
+
export type FindingKind = "strength" | "improvement" | "risk" | "question";
|
|
110
|
+
export interface ArenaFinding {
|
|
111
|
+
id: string;
|
|
112
|
+
kind: FindingKind;
|
|
113
|
+
title: string;
|
|
114
|
+
summary: string;
|
|
115
|
+
severity?: "high" | "medium" | "low";
|
|
116
|
+
confidence: number;
|
|
117
|
+
evidence: Array<{
|
|
118
|
+
type: "file" | "diff" | "grep" | "git" | "doc";
|
|
119
|
+
ref: string;
|
|
120
|
+
note: string;
|
|
121
|
+
}>;
|
|
122
|
+
affectedFiles: string[];
|
|
123
|
+
suggestedChange?: string;
|
|
124
|
+
}
|
|
125
|
+
export interface ParticipantContextRequest {
|
|
126
|
+
participant: string;
|
|
127
|
+
requests: Array<{
|
|
128
|
+
tool: string;
|
|
129
|
+
reason: string;
|
|
130
|
+
args: Record<string, unknown>;
|
|
131
|
+
}>;
|
|
132
|
+
}
|
|
133
|
+
export interface ParticipantReport {
|
|
134
|
+
participant: string;
|
|
135
|
+
contextSummary: string;
|
|
136
|
+
findings: ArenaFinding[];
|
|
137
|
+
}
|
|
138
|
+
/** Record of a single tool invocation during research or review */
|
|
139
|
+
export interface ToolTrace {
|
|
140
|
+
round: number;
|
|
141
|
+
toolName: string;
|
|
142
|
+
args: Record<string, unknown>;
|
|
143
|
+
resultRef?: string;
|
|
144
|
+
keptAsEvidence?: boolean;
|
|
145
|
+
}
|
|
146
|
+
/** A discrete packet of evidence collected during research or review */
|
|
147
|
+
export interface EvidencePacket {
|
|
148
|
+
packetId: string;
|
|
149
|
+
participant: string;
|
|
150
|
+
source: ArenaSourceKind;
|
|
151
|
+
title: string;
|
|
152
|
+
refs: string[];
|
|
153
|
+
summary: string;
|
|
154
|
+
excerpts: Array<{
|
|
155
|
+
ref: string;
|
|
156
|
+
snippet: string;
|
|
157
|
+
note: string;
|
|
158
|
+
}>;
|
|
159
|
+
}
|
|
160
|
+
/** Explicit link between a finding and its supporting evidence packets */
|
|
161
|
+
export interface FindingEvidenceLink {
|
|
162
|
+
findingId: string;
|
|
163
|
+
evidencePacketIds: string[];
|
|
164
|
+
}
|
|
165
|
+
/** Full research output — preserves evidence trail alongside findings */
|
|
166
|
+
export interface ResearchDossier {
|
|
167
|
+
participant: string;
|
|
168
|
+
contextSummary: string;
|
|
169
|
+
findings: ArenaFinding[];
|
|
170
|
+
toolTrace: ToolTrace[];
|
|
171
|
+
evidencePackets: EvidencePacket[];
|
|
172
|
+
findingEvidenceLinks: FindingEvidenceLink[];
|
|
173
|
+
}
|
|
174
|
+
export type PeerVerdict = "agree" | "refine" | "disagree" | "needs_evidence";
|
|
175
|
+
export type ClaimStatus = "proposed" | "under_review" | "contested" | "verified" | "rejected" | "unresolved";
|
|
176
|
+
export interface RequestedCheck {
|
|
177
|
+
requestId: string;
|
|
178
|
+
claimId: string;
|
|
179
|
+
requester: string;
|
|
180
|
+
description: string;
|
|
181
|
+
refs?: string[];
|
|
182
|
+
priority?: "high" | "medium" | "low";
|
|
183
|
+
}
|
|
184
|
+
export interface ClaimChallenge {
|
|
185
|
+
reviewer: string;
|
|
186
|
+
claimId: string;
|
|
187
|
+
verdict: PeerVerdict;
|
|
188
|
+
reason: string;
|
|
189
|
+
supportingEvidenceRefs?: string[];
|
|
190
|
+
requestedChecks?: RequestedCheck[];
|
|
191
|
+
}
|
|
192
|
+
export interface DebateTurn {
|
|
193
|
+
participant: string;
|
|
194
|
+
stance: "support" | "oppose" | "narrow" | "uncertain";
|
|
195
|
+
summary: string;
|
|
196
|
+
newEvidenceRefs?: string[];
|
|
197
|
+
}
|
|
198
|
+
export interface DebateRound {
|
|
199
|
+
round: number;
|
|
200
|
+
claimId: string;
|
|
201
|
+
participants: DebateTurn[];
|
|
202
|
+
resolved: boolean;
|
|
203
|
+
resolutionNote?: string;
|
|
204
|
+
}
|
|
205
|
+
export interface ClaimAdjudication {
|
|
206
|
+
claimId: string;
|
|
207
|
+
outcome: "accepted" | "accepted_with_revision" | "rejected" | "unresolved";
|
|
208
|
+
rationale: string;
|
|
209
|
+
finalSummary: string;
|
|
210
|
+
supportingEvidenceRefs: string[];
|
|
211
|
+
}
|
|
212
|
+
/** The minimum unit of debate — a finding elevated to a trackable claim */
|
|
213
|
+
export interface ClaimRecord {
|
|
214
|
+
claimId: string;
|
|
215
|
+
owner: string;
|
|
216
|
+
finding: ArenaFinding;
|
|
217
|
+
evidenceRefs: string[];
|
|
218
|
+
evidencePacketIds: string[];
|
|
219
|
+
status: ClaimStatus;
|
|
220
|
+
challenges: ClaimChallenge[];
|
|
221
|
+
debateRounds: DebateRound[];
|
|
222
|
+
adjudication?: ClaimAdjudication;
|
|
223
|
+
}
|
|
224
|
+
/** Append-only shared state across all rounds of research, review, debate */
|
|
225
|
+
export interface SharedResearchLedger {
|
|
226
|
+
dossiers: ResearchDossier[];
|
|
227
|
+
evidencePackets: EvidencePacket[];
|
|
228
|
+
toolTraces: ToolTrace[];
|
|
229
|
+
claims: ClaimRecord[];
|
|
230
|
+
challenges: ClaimChallenge[];
|
|
231
|
+
requestedChecks: RequestedCheck[];
|
|
232
|
+
adjudications: ClaimAdjudication[];
|
|
233
|
+
}
|
|
234
|
+
/** Per-round digest — a filtered view of the ledger for prompt injection */
|
|
235
|
+
export interface RoundResearchDigest {
|
|
236
|
+
round: number;
|
|
237
|
+
relevantClaimIds: string[];
|
|
238
|
+
evidencePackets: EvidencePacket[];
|
|
239
|
+
toolTraceSummary: Array<{
|
|
240
|
+
participant: string;
|
|
241
|
+
toolName: string;
|
|
242
|
+
ref?: string;
|
|
243
|
+
}>;
|
|
244
|
+
recentChallenges: ClaimChallenge[];
|
|
245
|
+
requestedChecks: RequestedCheck[];
|
|
246
|
+
priorAdjudications: ClaimAdjudication[];
|
|
247
|
+
}
|
|
248
|
+
/** Task for executing a targeted re-research check */
|
|
249
|
+
export interface TargetedCheckTask {
|
|
250
|
+
request: RequestedCheck;
|
|
251
|
+
assignee: string;
|
|
252
|
+
status: "pending" | "running" | "done" | "skipped";
|
|
253
|
+
producedPacketIds: string[];
|
|
254
|
+
}
|
|
255
|
+
/** Global caps to prevent cost explosion in review/debate phases */
|
|
256
|
+
export interface ArenaExecutionLimits {
|
|
257
|
+
maxClaimsForReview: number;
|
|
258
|
+
maxContestedClaimsForDebate: number;
|
|
259
|
+
maxRequestedChecksPerClaimPerRound: number;
|
|
260
|
+
maxReviewersPerClaim: number;
|
|
261
|
+
/** Max roadmap phases in planning mode */
|
|
262
|
+
maxRoadmapPhases: number;
|
|
263
|
+
/** Max phases to expand with detail in planning mode */
|
|
264
|
+
maxExpandedPhasesPerRun: number;
|
|
265
|
+
}
|
|
266
|
+
export declare const DEFAULT_EXECUTION_LIMITS: ArenaExecutionLimits;
|
|
267
|
+
export interface FindingReview {
|
|
268
|
+
reviewer: string;
|
|
269
|
+
findingId: string;
|
|
270
|
+
verdict: PeerVerdict;
|
|
271
|
+
reason: string;
|
|
272
|
+
extraEvidence?: string[];
|
|
273
|
+
}
|
|
274
|
+
export interface ArenaConsensusItem {
|
|
275
|
+
title: string;
|
|
276
|
+
summary: string;
|
|
277
|
+
support: string[];
|
|
278
|
+
challenge: string[];
|
|
279
|
+
confidence: number;
|
|
280
|
+
evidenceRefs: string[];
|
|
281
|
+
}
|
|
282
|
+
export interface ArenaRoadmapPhase {
|
|
283
|
+
title: string;
|
|
284
|
+
priority: "high" | "medium" | "low";
|
|
285
|
+
goal: string;
|
|
286
|
+
scope: string[];
|
|
287
|
+
deliverables: string[];
|
|
288
|
+
dependencies: string[];
|
|
289
|
+
risks: string[];
|
|
290
|
+
successCriteria: string[];
|
|
291
|
+
relatedFindings: string[];
|
|
292
|
+
}
|
|
293
|
+
/** Repo-level implementation detail for a roadmap phase (planning mode) */
|
|
294
|
+
export interface ArenaRoadmapPhaseDetail {
|
|
295
|
+
phaseTitle: string;
|
|
296
|
+
objective: string;
|
|
297
|
+
targetFiles: string[];
|
|
298
|
+
codeChanges: string[];
|
|
299
|
+
interfaces: string[];
|
|
300
|
+
migrationSteps: string[];
|
|
301
|
+
validation: string[];
|
|
302
|
+
effort: "small" | "medium" | "large";
|
|
303
|
+
blockers: string[];
|
|
304
|
+
evidenceRefs: string[];
|
|
305
|
+
}
|
|
306
|
+
export interface ArenaConsensus {
|
|
307
|
+
/** Overall assessment */
|
|
308
|
+
summary: string;
|
|
309
|
+
/** Subject summary — rendered as "What Changed" / "Current Scope" / "Problem Framing" per mode */
|
|
310
|
+
subjectSummary?: string;
|
|
311
|
+
strengths: ArenaConsensusItem[];
|
|
312
|
+
improvements: ArenaConsensusItem[];
|
|
313
|
+
risks: ArenaConsensusItem[];
|
|
314
|
+
openQuestions: ArenaConsensusItem[];
|
|
315
|
+
roadmap: ArenaRoadmapPhase[];
|
|
316
|
+
/** Repo-level implementation details per roadmap phase (planning mode) */
|
|
317
|
+
roadmapDetails?: ArenaRoadmapPhaseDetail[];
|
|
318
|
+
nextActions: Array<{
|
|
319
|
+
title: string;
|
|
320
|
+
priority: "high" | "medium" | "low";
|
|
321
|
+
rationale: string;
|
|
322
|
+
relatedFindings: string[];
|
|
323
|
+
}>;
|
|
324
|
+
}
|
|
325
|
+
export interface ArenaResultV2 {
|
|
326
|
+
topic: string;
|
|
327
|
+
mode: ArenaMode;
|
|
328
|
+
participants: string[];
|
|
329
|
+
plan: ArenaPlan;
|
|
330
|
+
baseContext: ArenaBaseContext;
|
|
331
|
+
reports: ParticipantReport[];
|
|
332
|
+
/** Research dossiers with evidence trails (Phase 3+) */
|
|
333
|
+
dossiers?: ResearchDossier[];
|
|
334
|
+
/** Registered claims derived from findings (Phase 3+) */
|
|
335
|
+
claims?: ClaimRecord[];
|
|
336
|
+
reviews: FindingReview[];
|
|
337
|
+
/** Debate rounds for contested claims (Phase 3+) */
|
|
338
|
+
debateRounds?: DebateRound[];
|
|
339
|
+
/** Claim adjudications (Phase 3+) */
|
|
340
|
+
adjudications?: ClaimAdjudication[];
|
|
341
|
+
consensus: ArenaConsensus;
|
|
342
|
+
/** Aggregate of every provider request made by this Arena run. */
|
|
343
|
+
usage: TokenUsage;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* ArenaStrategy — encapsulates mode-specific behavior for prompts and parsing.
|
|
347
|
+
*
|
|
348
|
+
* V2 strategies produce structured findings instead of free-text opinions.
|
|
349
|
+
*/
|
|
350
|
+
export interface ArenaStrategy {
|
|
351
|
+
/** Build the system prompt for participant research phase */
|
|
352
|
+
researchSystemPrompt(participantName: string): string;
|
|
353
|
+
/** Build the user prompt for participant research, given base context */
|
|
354
|
+
researchUserPrompt(topic: string, baseContext: ArenaBaseContext): string;
|
|
355
|
+
/** Parse participant research response into structured report */
|
|
356
|
+
parseResearchResponse(participant: string, text: string): ParticipantReport;
|
|
357
|
+
/** Build the system prompt for cross-review phase */
|
|
358
|
+
crossReviewSystemPrompt(reviewerName: string): string;
|
|
359
|
+
/** Build the user prompt for cross-reviewing other participants' findings */
|
|
360
|
+
crossReviewUserPrompt(topic: string, myReport: ParticipantReport, otherReports: ParticipantReport[]): string;
|
|
361
|
+
/** Parse cross-review response into finding reviews */
|
|
362
|
+
parseCrossReviewResponse(reviewer: string, text: string): FindingReview[];
|
|
363
|
+
/** Build the system prompt for consensus building */
|
|
364
|
+
consensusSystemPrompt(): string;
|
|
365
|
+
/** Build the user prompt for consensus building */
|
|
366
|
+
consensusUserPrompt(topic: string, reports: ParticipantReport[], reviews: FindingReview[]): string;
|
|
367
|
+
/** Parse consensus response */
|
|
368
|
+
parseConsensusResponse(text: string): ArenaConsensus;
|
|
369
|
+
/** Finding kinds this mode emphasizes */
|
|
370
|
+
preferredFindingKinds(): FindingKind[];
|
|
371
|
+
}
|
|
372
|
+
/**
|
|
373
|
+
* ArenaStrategyV2 — extends ArenaStrategy with claim-aware prompt methods.
|
|
374
|
+
*
|
|
375
|
+
* Strategies implementing V2 participate in the full evidence-driven loop:
|
|
376
|
+
* verification review, debate, adjudication, and claim-aware consensus.
|
|
377
|
+
*
|
|
378
|
+
* Strategies that only implement ArenaStrategy continue to work via
|
|
379
|
+
* automatic fallback paths in each phase.
|
|
380
|
+
*/
|
|
381
|
+
export interface ArenaStrategyV2 extends ArenaStrategy {
|
|
382
|
+
/** Build verification-review user prompt with claim data and digest */
|
|
383
|
+
verificationReviewUserPrompt(topic: string, myReport: ParticipantReport, claimsToReview: ClaimRecord[], digest: RoundResearchDigest): string;
|
|
384
|
+
/** Parse verification review into ClaimChallenge records */
|
|
385
|
+
parseVerificationReviewResponse(reviewer: string, text: string): ClaimChallenge[];
|
|
386
|
+
/** Build debate turn prompt for a participant on a specific claim */
|
|
387
|
+
debateTurnUserPrompt(topic: string, claim: ClaimRecord, priorTurns: DebateTurn[], digest: RoundResearchDigest): string;
|
|
388
|
+
/** Parse a debate turn response */
|
|
389
|
+
parseDebateTurnResponse(participant: string, text: string): DebateTurn;
|
|
390
|
+
/** Build adjudication prompt for the moderator */
|
|
391
|
+
adjudicationUserPrompt(topic: string, claim: ClaimRecord, debateRounds: DebateRound[], digest: RoundResearchDigest): string;
|
|
392
|
+
/** Parse adjudication response */
|
|
393
|
+
parseAdjudicationResponse(text: string): ClaimAdjudication;
|
|
394
|
+
/** Build claim-aware consensus prompt */
|
|
395
|
+
claimAwareConsensusUserPrompt(topic: string, reports: ParticipantReport[], reviews: FindingReview[], claimSummary: ClaimStatusSummary): string;
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* ArenaStrategyPlanning — extends ArenaStrategyV2 with planning-specific methods.
|
|
399
|
+
*
|
|
400
|
+
* Strategies implementing this participate in the planning-specific flow:
|
|
401
|
+
* merge-oriented review and detail expansion.
|
|
402
|
+
*/
|
|
403
|
+
export interface ArenaStrategyPlanning extends ArenaStrategyV2 {
|
|
404
|
+
/** Build merge-oriented review prompt for planning mode */
|
|
405
|
+
mergeReviewUserPrompt(topic: string, myReport: ParticipantReport, claimsToReview: ClaimRecord[], digest: RoundResearchDigest): string;
|
|
406
|
+
/** Parse merge-review response into challenges with planning semantics */
|
|
407
|
+
parseMergeReviewResponse(reviewer: string, text: string): ClaimChallenge[];
|
|
408
|
+
/** Build detail expansion system prompt */
|
|
409
|
+
detailExpansionSystemPrompt(): string;
|
|
410
|
+
/** Build detail expansion user prompt for a single roadmap phase */
|
|
411
|
+
detailExpansionUserPrompt(topic: string, phase: ArenaRoadmapPhase, digest: RoundResearchDigest): string;
|
|
412
|
+
/** Parse detail expansion response */
|
|
413
|
+
parseDetailExpansionResponse(text: string): ArenaRoadmapPhaseDetail;
|
|
414
|
+
}
|
|
415
|
+
/** Type guard: does a strategy implement ArenaStrategyPlanning? */
|
|
416
|
+
export declare function isStrategyPlanning(s: ArenaStrategy): s is ArenaStrategyPlanning;
|
|
417
|
+
/** Grouped claims by terminal status — used in claim-aware consensus */
|
|
418
|
+
export interface ClaimStatusSummary {
|
|
419
|
+
verified: ClaimRecord[];
|
|
420
|
+
contested: ClaimRecord[];
|
|
421
|
+
unresolved: ClaimRecord[];
|
|
422
|
+
rejected: ClaimRecord[];
|
|
423
|
+
}
|
|
424
|
+
/** Type guard: does a strategy implement ArenaStrategyV2? */
|
|
425
|
+
export declare function isStrategyV2(s: ArenaStrategy): s is ArenaStrategyV2;
|
|
426
|
+
/** Arena configuration */
|
|
427
|
+
export interface ArenaConfig {
|
|
428
|
+
/** Participants (models) in the arena */
|
|
429
|
+
participants: ArenaParticipant[];
|
|
430
|
+
/** Arena mode (default: "review") */
|
|
431
|
+
mode?: ArenaMode;
|
|
432
|
+
/** Maximum discussion rounds after initial opinions (overrides mode default if set) */
|
|
433
|
+
maxDiscussionRounds?: number;
|
|
434
|
+
/** Which participant generates the final conclusion (default: first) */
|
|
435
|
+
concluder?: string;
|
|
436
|
+
/** Optional custom strategy — overrides mode-based strategy selection */
|
|
437
|
+
strategy?: ArenaStrategy;
|
|
438
|
+
/**
|
|
439
|
+
* Enable read-only context tools (read_file, grep_code, list_files) during
|
|
440
|
+
* participant research. Participants can request additional source context.
|
|
441
|
+
*/
|
|
442
|
+
enableContextTools?: boolean;
|
|
443
|
+
/** Execution limits for review/debate/adjudication phases */
|
|
444
|
+
executionLimits?: ArenaExecutionLimits;
|
|
445
|
+
/** Callback for streaming arena progress */
|
|
446
|
+
onProgress?: (event: ArenaProgressEvent) => void;
|
|
447
|
+
/** AbortSignal for cancelling a running arena session */
|
|
448
|
+
signal?: AbortSignal;
|
|
449
|
+
}
|
|
450
|
+
export type ArenaProgressEvent = {
|
|
451
|
+
type: "plan_resolved";
|
|
452
|
+
plan: ArenaPlan;
|
|
453
|
+
} | {
|
|
454
|
+
type: "evidence_started";
|
|
455
|
+
source: ArenaSourceKind;
|
|
456
|
+
} | {
|
|
457
|
+
type: "evidence_source_done";
|
|
458
|
+
source: ArenaSourceKind;
|
|
459
|
+
count: number;
|
|
460
|
+
durationMs: number;
|
|
461
|
+
timedOut: boolean;
|
|
462
|
+
} | {
|
|
463
|
+
type: "evidence_collected";
|
|
464
|
+
artifacts: ArenaArtifact[];
|
|
465
|
+
} | {
|
|
466
|
+
type: "research_start";
|
|
467
|
+
participant: string;
|
|
468
|
+
} | {
|
|
469
|
+
type: "research_done";
|
|
470
|
+
participant: string;
|
|
471
|
+
report: ParticipantReport;
|
|
472
|
+
} | {
|
|
473
|
+
type: "context_lookup";
|
|
474
|
+
participant: string;
|
|
475
|
+
tools: string[];
|
|
476
|
+
} | {
|
|
477
|
+
type: "claims_registered";
|
|
478
|
+
claimCount: number;
|
|
479
|
+
} | {
|
|
480
|
+
type: "cross_review_start";
|
|
481
|
+
round: number;
|
|
482
|
+
} | {
|
|
483
|
+
type: "cross_review_done";
|
|
484
|
+
reviews: FindingReview[];
|
|
485
|
+
} | {
|
|
486
|
+
type: "verification_start";
|
|
487
|
+
} | {
|
|
488
|
+
type: "verification_done";
|
|
489
|
+
challengeCount: number;
|
|
490
|
+
} | {
|
|
491
|
+
type: "debate_round_start";
|
|
492
|
+
round: number;
|
|
493
|
+
claims: string[];
|
|
494
|
+
} | {
|
|
495
|
+
type: "debate_round_done";
|
|
496
|
+
round: number;
|
|
497
|
+
resolved: number;
|
|
498
|
+
} | {
|
|
499
|
+
type: "adjudication_done";
|
|
500
|
+
accepted: number;
|
|
501
|
+
unresolved: number;
|
|
502
|
+
} | {
|
|
503
|
+
type: "planning_merge_review_start";
|
|
504
|
+
} | {
|
|
505
|
+
type: "planning_merge_review_done";
|
|
506
|
+
mergeCount: number;
|
|
507
|
+
} | {
|
|
508
|
+
type: "roadmap_expansion_start";
|
|
509
|
+
phaseCount: number;
|
|
510
|
+
} | {
|
|
511
|
+
type: "roadmap_expansion_done";
|
|
512
|
+
detailCount: number;
|
|
513
|
+
} | {
|
|
514
|
+
type: "consensus_start";
|
|
515
|
+
} | {
|
|
516
|
+
type: "consensus_done";
|
|
517
|
+
consensus: ArenaConsensus;
|
|
518
|
+
};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Arena types — multi-model review, discussion, and planning.
|
|
3
|
+
*
|
|
4
|
+
* V2 architecture: shared facts → independent research → findings → cross-review → consensus.
|
|
5
|
+
*/
|
|
6
|
+
/** Default max discussion rounds per mode */
|
|
7
|
+
export const ARENA_MODE_DEFAULTS = {
|
|
8
|
+
review: { maxDiscussionRounds: 3, convergenceThreshold: 200 },
|
|
9
|
+
discussion: { maxDiscussionRounds: 4, convergenceThreshold: 300 },
|
|
10
|
+
planning: { maxDiscussionRounds: 5, convergenceThreshold: 400 },
|
|
11
|
+
};
|
|
12
|
+
export const DEFAULT_EXECUTION_LIMITS = {
|
|
13
|
+
maxClaimsForReview: 12,
|
|
14
|
+
maxContestedClaimsForDebate: 5,
|
|
15
|
+
maxRequestedChecksPerClaimPerRound: 2,
|
|
16
|
+
maxReviewersPerClaim: 2,
|
|
17
|
+
maxRoadmapPhases: 6,
|
|
18
|
+
maxExpandedPhasesPerRun: 6,
|
|
19
|
+
};
|
|
20
|
+
/** Type guard: does a strategy implement ArenaStrategyPlanning? */
|
|
21
|
+
export function isStrategyPlanning(s) {
|
|
22
|
+
return typeof s.detailExpansionUserPrompt === "function";
|
|
23
|
+
}
|
|
24
|
+
/** Type guard: does a strategy implement ArenaStrategyV2? */
|
|
25
|
+
export function isStrategyV2(s) {
|
|
26
|
+
return typeof s.verificationReviewUserPrompt === "function";
|
|
27
|
+
}
|