@alexeiled/pi-fusion 0.3.1 → 0.5.1
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 +34 -2
- package/agents/fusion-panelist.md +7 -1
- package/docs/user-guide.md +56 -20
- package/package.json +1 -1
- package/skills/fusion-review/SKILL.md +4 -0
- package/src/config.ts +7 -0
- package/src/fusion-rpc.ts +619 -0
- package/src/index.ts +16 -3
- package/src/orchestrator.ts +380 -53
- package/src/report.ts +171 -10
- package/src/result-extract.ts +157 -24
- package/src/run-builder.ts +32 -4
- package/src/run-observations.ts +335 -0
- package/src/run-store.ts +237 -6
- package/src/types.ts +52 -0
package/src/run-store.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
-
import type {
|
|
2
|
+
import type {
|
|
3
|
+
FusionPhase,
|
|
4
|
+
FusionRun,
|
|
5
|
+
ModelAttempt,
|
|
6
|
+
PanelDecision,
|
|
7
|
+
ProviderFailure,
|
|
8
|
+
RunObservation,
|
|
9
|
+
RunUsage,
|
|
10
|
+
} from "./types.js";
|
|
3
11
|
import { isFiniteNumber, isNonEmptyString, isRecord } from "./utils.js";
|
|
4
12
|
|
|
5
13
|
export const FUSION_RUN_ENTRY_TYPE = "fusion-run";
|
|
@@ -15,6 +23,7 @@ export type FusionRunSummary = Omit<
|
|
|
15
23
|
| "id"
|
|
16
24
|
| "prompt"
|
|
17
25
|
| "profileName"
|
|
26
|
+
| "operationId"
|
|
18
27
|
| "phase"
|
|
19
28
|
| "createdAt"
|
|
20
29
|
| "updatedAt"
|
|
@@ -31,6 +40,7 @@ export interface FusionRunStartInput {
|
|
|
31
40
|
id?: string;
|
|
32
41
|
prompt: string;
|
|
33
42
|
profileName: string;
|
|
43
|
+
operationId?: string;
|
|
34
44
|
phase?: Exclude<FusionPhase, FusionTerminalPhase>;
|
|
35
45
|
createdAt?: number;
|
|
36
46
|
}
|
|
@@ -40,8 +50,12 @@ export interface FusionRunPatch {
|
|
|
40
50
|
chainRunId?: string;
|
|
41
51
|
chainAsyncDir?: string;
|
|
42
52
|
panelRunId?: string;
|
|
53
|
+
panelAsyncDir?: string;
|
|
54
|
+
panelStopReason?: FusionRun["panelStopReason"];
|
|
55
|
+
panelStoppedIndices?: FusionRun["panelStoppedIndices"];
|
|
43
56
|
judgeRunId?: string;
|
|
44
57
|
judgeAsyncDir?: string;
|
|
58
|
+
judgeObservation?: FusionRun["judgeObservation"];
|
|
45
59
|
panelOutputs?: FusionRun["panelOutputs"];
|
|
46
60
|
panelFailures?: FusionRun["panelFailures"];
|
|
47
61
|
report?: string;
|
|
@@ -84,6 +98,8 @@ export class FusionRunStoreError extends Error {
|
|
|
84
98
|
export class FusionRunStore {
|
|
85
99
|
private activeRun: FusionRun | undefined;
|
|
86
100
|
private lastRunSummary: FusionRunSummary | undefined;
|
|
101
|
+
private readonly runsById = new Map<string, FusionRun>();
|
|
102
|
+
private readonly runIdsByOperationId = new Map<string, string>();
|
|
87
103
|
private readonly now: () => number;
|
|
88
104
|
private readonly idFactory: () => string;
|
|
89
105
|
private readonly persistence: FusionRunStorePersistence | undefined;
|
|
@@ -104,22 +120,44 @@ export class FusionRunStore {
|
|
|
104
120
|
: undefined;
|
|
105
121
|
}
|
|
106
122
|
|
|
123
|
+
getRunById(id: string): FusionRun | undefined {
|
|
124
|
+
const run = this.runsById.get(id);
|
|
125
|
+
return run ? cloneRun(run) : undefined;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
getRunByOperationId(operationId: string): FusionRun | undefined {
|
|
129
|
+
const runId = this.runIdsByOperationId.get(operationId);
|
|
130
|
+
return runId ? this.getRunById(runId) : undefined;
|
|
131
|
+
}
|
|
132
|
+
|
|
107
133
|
startRun(input: FusionRunStartInput): FusionRun {
|
|
108
134
|
if (this.activeRun) {
|
|
109
135
|
throw new FusionRunStoreError(
|
|
110
136
|
`Fusion run ${this.activeRun.id} is already active.`,
|
|
111
137
|
);
|
|
112
138
|
}
|
|
139
|
+
if (
|
|
140
|
+
input.operationId !== undefined &&
|
|
141
|
+
this.runIdsByOperationId.has(input.operationId)
|
|
142
|
+
) {
|
|
143
|
+
throw new FusionRunStoreError(
|
|
144
|
+
`Fusion operation ${input.operationId} already has a run.`,
|
|
145
|
+
);
|
|
146
|
+
}
|
|
113
147
|
const createdAt = input.createdAt ?? this.now();
|
|
114
148
|
const run: FusionRun = {
|
|
115
149
|
id: input.id ?? this.idFactory(),
|
|
116
150
|
prompt: input.prompt,
|
|
117
151
|
profileName: input.profileName,
|
|
152
|
+
...(input.operationId !== undefined
|
|
153
|
+
? { operationId: input.operationId }
|
|
154
|
+
: {}),
|
|
118
155
|
phase: input.phase ?? "chain",
|
|
119
156
|
createdAt,
|
|
120
157
|
updatedAt: createdAt,
|
|
121
158
|
};
|
|
122
159
|
this.activeRun = run;
|
|
160
|
+
this.rememberRun(run);
|
|
123
161
|
this.persistRun(run);
|
|
124
162
|
return cloneRun(run);
|
|
125
163
|
}
|
|
@@ -128,6 +166,7 @@ export class FusionRunStore {
|
|
|
128
166
|
const active = this.requireActiveRun(id);
|
|
129
167
|
const updated = applyPatch(active, patch, patch.updatedAt ?? this.now());
|
|
130
168
|
this.activeRun = updated;
|
|
169
|
+
this.rememberRun(updated);
|
|
131
170
|
this.persistRun(updated);
|
|
132
171
|
return cloneRun(updated);
|
|
133
172
|
}
|
|
@@ -159,6 +198,7 @@ export class FusionRunStore {
|
|
|
159
198
|
const summary = toRunSummary(finished);
|
|
160
199
|
this.activeRun = undefined;
|
|
161
200
|
this.lastRunSummary = summary;
|
|
201
|
+
this.rememberRun(finished);
|
|
162
202
|
this.persistRun(summary);
|
|
163
203
|
return cloneRun(finished);
|
|
164
204
|
}
|
|
@@ -166,7 +206,12 @@ export class FusionRunStore {
|
|
|
166
206
|
restoreFromEntries(
|
|
167
207
|
entries: readonly unknown[],
|
|
168
208
|
): FusionRunSummary | undefined {
|
|
169
|
-
const
|
|
209
|
+
const states = readFusionRunStates(entries);
|
|
210
|
+
this.runsById.clear();
|
|
211
|
+
this.runIdsByOperationId.clear();
|
|
212
|
+
for (const state of states) this.rememberRun(state);
|
|
213
|
+
|
|
214
|
+
const latestState = states.at(-1);
|
|
170
215
|
const summary = readLastFusionRunSummary(entries);
|
|
171
216
|
this.activeRun =
|
|
172
217
|
latestState && !isTerminalPhase(latestState.phase)
|
|
@@ -196,6 +241,16 @@ export class FusionRunStore {
|
|
|
196
241
|
this.persistence?.appendEntry(FUSION_RUN_ENTRY_TYPE, cloneRun(run));
|
|
197
242
|
}
|
|
198
243
|
|
|
244
|
+
private rememberRun(run: FusionRun): void {
|
|
245
|
+
this.runsById.set(run.id, cloneRun(run));
|
|
246
|
+
if (
|
|
247
|
+
run.operationId !== undefined &&
|
|
248
|
+
!this.runIdsByOperationId.has(run.operationId)
|
|
249
|
+
) {
|
|
250
|
+
this.runIdsByOperationId.set(run.operationId, run.id);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
|
|
199
254
|
private requireActiveRun(id: string): FusionRun {
|
|
200
255
|
if (!this.activeRun) {
|
|
201
256
|
throw new FusionRunStoreError("No active fusion run.");
|
|
@@ -260,10 +315,22 @@ function applyPatch(
|
|
|
260
315
|
updated.chainAsyncDir = patch.chainAsyncDir;
|
|
261
316
|
}
|
|
262
317
|
if (patch.panelRunId !== undefined) updated.panelRunId = patch.panelRunId;
|
|
318
|
+
if (patch.panelAsyncDir !== undefined) {
|
|
319
|
+
updated.panelAsyncDir = patch.panelAsyncDir;
|
|
320
|
+
}
|
|
321
|
+
if (patch.panelStopReason !== undefined) {
|
|
322
|
+
updated.panelStopReason = patch.panelStopReason;
|
|
323
|
+
}
|
|
324
|
+
if (patch.panelStoppedIndices !== undefined) {
|
|
325
|
+
updated.panelStoppedIndices = [...patch.panelStoppedIndices];
|
|
326
|
+
}
|
|
263
327
|
if (patch.judgeRunId !== undefined) updated.judgeRunId = patch.judgeRunId;
|
|
264
328
|
if (patch.judgeAsyncDir !== undefined) {
|
|
265
329
|
updated.judgeAsyncDir = patch.judgeAsyncDir;
|
|
266
330
|
}
|
|
331
|
+
if (patch.judgeObservation !== undefined) {
|
|
332
|
+
updated.judgeObservation = cloneObservation(patch.judgeObservation);
|
|
333
|
+
}
|
|
267
334
|
if (patch.panelOutputs !== undefined) {
|
|
268
335
|
updated.panelOutputs = clonePanelOutputs(patch.panelOutputs);
|
|
269
336
|
}
|
|
@@ -301,6 +368,7 @@ function toRunSummary(
|
|
|
301
368
|
id: run.id,
|
|
302
369
|
prompt: run.prompt,
|
|
303
370
|
profileName: run.profileName,
|
|
371
|
+
...(run.operationId !== undefined ? { operationId: run.operationId } : {}),
|
|
304
372
|
phase: run.phase,
|
|
305
373
|
createdAt: run.createdAt,
|
|
306
374
|
updatedAt: run.updatedAt,
|
|
@@ -317,6 +385,7 @@ function cloneRun(run: FusionRun): FusionRun {
|
|
|
317
385
|
id: run.id,
|
|
318
386
|
prompt: run.prompt,
|
|
319
387
|
profileName: run.profileName,
|
|
388
|
+
...(run.operationId !== undefined ? { operationId: run.operationId } : {}),
|
|
320
389
|
phase: run.phase,
|
|
321
390
|
createdAt: run.createdAt,
|
|
322
391
|
updatedAt: run.updatedAt,
|
|
@@ -325,10 +394,22 @@ function cloneRun(run: FusionRun): FusionRun {
|
|
|
325
394
|
? { chainAsyncDir: run.chainAsyncDir }
|
|
326
395
|
: {}),
|
|
327
396
|
...(run.panelRunId !== undefined ? { panelRunId: run.panelRunId } : {}),
|
|
397
|
+
...(run.panelAsyncDir !== undefined
|
|
398
|
+
? { panelAsyncDir: run.panelAsyncDir }
|
|
399
|
+
: {}),
|
|
400
|
+
...(run.panelStopReason !== undefined
|
|
401
|
+
? { panelStopReason: run.panelStopReason }
|
|
402
|
+
: {}),
|
|
403
|
+
...(run.panelStoppedIndices !== undefined
|
|
404
|
+
? { panelStoppedIndices: [...run.panelStoppedIndices] }
|
|
405
|
+
: {}),
|
|
328
406
|
...(run.judgeRunId !== undefined ? { judgeRunId: run.judgeRunId } : {}),
|
|
329
407
|
...(run.judgeAsyncDir !== undefined
|
|
330
408
|
? { judgeAsyncDir: run.judgeAsyncDir }
|
|
331
409
|
: {}),
|
|
410
|
+
...(run.judgeObservation !== undefined
|
|
411
|
+
? { judgeObservation: cloneObservation(run.judgeObservation) }
|
|
412
|
+
: {}),
|
|
332
413
|
...(run.panelOutputs !== undefined
|
|
333
414
|
? { panelOutputs: clonePanelOutputs(run.panelOutputs) }
|
|
334
415
|
: {}),
|
|
@@ -360,6 +441,9 @@ function isFusionRunState(value: unknown): value is FusionRun {
|
|
|
360
441
|
if (!isNonEmptyString(value.id)) return false;
|
|
361
442
|
if (typeof value.prompt !== "string") return false;
|
|
362
443
|
if (!isNonEmptyString(value.profileName)) return false;
|
|
444
|
+
if (value.operationId !== undefined && !isNonEmptyString(value.operationId)) {
|
|
445
|
+
return false;
|
|
446
|
+
}
|
|
363
447
|
if (!isFusionPhase(value.phase)) return false;
|
|
364
448
|
if (!isFiniteNumber(value.createdAt)) return false;
|
|
365
449
|
if (!isFiniteNumber(value.updatedAt)) return false;
|
|
@@ -375,6 +459,28 @@ function isFusionRunState(value: unknown): value is FusionRun {
|
|
|
375
459
|
if (value.panelRunId !== undefined && typeof value.panelRunId !== "string") {
|
|
376
460
|
return false;
|
|
377
461
|
}
|
|
462
|
+
if (
|
|
463
|
+
value.panelAsyncDir !== undefined &&
|
|
464
|
+
typeof value.panelAsyncDir !== "string"
|
|
465
|
+
) {
|
|
466
|
+
return false;
|
|
467
|
+
}
|
|
468
|
+
if (
|
|
469
|
+
value.panelStopReason !== undefined &&
|
|
470
|
+
value.panelStopReason !== "agreement"
|
|
471
|
+
) {
|
|
472
|
+
return false;
|
|
473
|
+
}
|
|
474
|
+
if (
|
|
475
|
+
value.panelStoppedIndices !== undefined &&
|
|
476
|
+
(!Array.isArray(value.panelStoppedIndices) ||
|
|
477
|
+
!value.panelStoppedIndices.every(
|
|
478
|
+
(index: unknown) =>
|
|
479
|
+
typeof index === "number" && Number.isInteger(index) && index >= 0,
|
|
480
|
+
))
|
|
481
|
+
) {
|
|
482
|
+
return false;
|
|
483
|
+
}
|
|
378
484
|
if (value.judgeRunId !== undefined && typeof value.judgeRunId !== "string") {
|
|
379
485
|
return false;
|
|
380
486
|
}
|
|
@@ -384,6 +490,12 @@ function isFusionRunState(value: unknown): value is FusionRun {
|
|
|
384
490
|
) {
|
|
385
491
|
return false;
|
|
386
492
|
}
|
|
493
|
+
if (
|
|
494
|
+
value.judgeObservation !== undefined &&
|
|
495
|
+
!isRunObservation(value.judgeObservation)
|
|
496
|
+
) {
|
|
497
|
+
return false;
|
|
498
|
+
}
|
|
387
499
|
if (
|
|
388
500
|
value.panelOutputs !== undefined &&
|
|
389
501
|
!isPanelOutputArray(value.panelOutputs)
|
|
@@ -440,9 +552,14 @@ function isPanelOutput(
|
|
|
440
552
|
typeof value.output === "string" &&
|
|
441
553
|
(value.id === undefined || typeof value.id === "string") &&
|
|
442
554
|
(value.label === undefined || typeof value.label === "string") &&
|
|
555
|
+
(value.configuredModel === undefined ||
|
|
556
|
+
typeof value.configuredModel === "string") &&
|
|
443
557
|
(value.artifactPath === undefined ||
|
|
444
558
|
typeof value.artifactPath === "string") &&
|
|
445
|
-
(value.sessionPath === undefined ||
|
|
559
|
+
(value.sessionPath === undefined ||
|
|
560
|
+
typeof value.sessionPath === "string") &&
|
|
561
|
+
(value.decision === undefined || isPanelDecision(value.decision)) &&
|
|
562
|
+
(value.observation === undefined || isRunObservation(value.observation))
|
|
446
563
|
);
|
|
447
564
|
}
|
|
448
565
|
|
|
@@ -462,20 +579,134 @@ function isPanelFailure(
|
|
|
462
579
|
typeof value.summary === "string" &&
|
|
463
580
|
(value.id === undefined || typeof value.id === "string") &&
|
|
464
581
|
(value.label === undefined || typeof value.label === "string") &&
|
|
582
|
+
(value.configuredModel === undefined ||
|
|
583
|
+
typeof value.configuredModel === "string") &&
|
|
465
584
|
(value.artifactPath === undefined ||
|
|
466
585
|
typeof value.artifactPath === "string") &&
|
|
467
|
-
(value.sessionPath === undefined ||
|
|
586
|
+
(value.sessionPath === undefined ||
|
|
587
|
+
typeof value.sessionPath === "string") &&
|
|
588
|
+
(value.reason === undefined || isPanelFailureReason(value.reason)) &&
|
|
589
|
+
(value.observation === undefined || isRunObservation(value.observation))
|
|
468
590
|
);
|
|
469
591
|
}
|
|
470
592
|
|
|
471
593
|
function clonePanelOutputs(
|
|
472
594
|
outputs: NonNullable<FusionRun["panelOutputs"]>,
|
|
473
595
|
): NonNullable<FusionRun["panelOutputs"]> {
|
|
474
|
-
return outputs.map((output) => ({
|
|
596
|
+
return outputs.map((output) => ({
|
|
597
|
+
...output,
|
|
598
|
+
...(output.decision
|
|
599
|
+
? { decision: clonePanelDecision(output.decision) }
|
|
600
|
+
: {}),
|
|
601
|
+
...(output.observation
|
|
602
|
+
? { observation: cloneObservation(output.observation) }
|
|
603
|
+
: {}),
|
|
604
|
+
}));
|
|
475
605
|
}
|
|
476
606
|
|
|
477
607
|
function clonePanelFailures(
|
|
478
608
|
failures: NonNullable<FusionRun["panelFailures"]>,
|
|
479
609
|
): NonNullable<FusionRun["panelFailures"]> {
|
|
480
|
-
return failures.map((failure) => ({
|
|
610
|
+
return failures.map((failure) => ({
|
|
611
|
+
...failure,
|
|
612
|
+
...(failure.observation
|
|
613
|
+
? { observation: cloneObservation(failure.observation) }
|
|
614
|
+
: {}),
|
|
615
|
+
}));
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
function cloneObservation(observation: RunObservation): RunObservation {
|
|
619
|
+
return {
|
|
620
|
+
...(observation.model ? { model: observation.model } : {}),
|
|
621
|
+
...(observation.durationMs !== undefined
|
|
622
|
+
? { durationMs: observation.durationMs }
|
|
623
|
+
: {}),
|
|
624
|
+
...(observation.usage ? { usage: { ...observation.usage } } : {}),
|
|
625
|
+
...(observation.attempts
|
|
626
|
+
? { attempts: observation.attempts.map((attempt) => ({ ...attempt })) }
|
|
627
|
+
: {}),
|
|
628
|
+
...(observation.providerFailures
|
|
629
|
+
? {
|
|
630
|
+
providerFailures: observation.providerFailures.map((failure) => ({
|
|
631
|
+
...failure,
|
|
632
|
+
})),
|
|
633
|
+
}
|
|
634
|
+
: {}),
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
|
|
638
|
+
function clonePanelDecision(decision: PanelDecision): PanelDecision {
|
|
639
|
+
return { ...decision };
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
function isRunObservation(value: unknown): value is RunObservation {
|
|
643
|
+
if (!isRecord(value)) return false;
|
|
644
|
+
if (value.model !== undefined && typeof value.model !== "string")
|
|
645
|
+
return false;
|
|
646
|
+
if (value.durationMs !== undefined && !isFiniteNumber(value.durationMs)) {
|
|
647
|
+
return false;
|
|
648
|
+
}
|
|
649
|
+
if (value.usage !== undefined && !isRunUsage(value.usage)) return false;
|
|
650
|
+
if (value.attempts !== undefined && !isModelAttemptArray(value.attempts)) {
|
|
651
|
+
return false;
|
|
652
|
+
}
|
|
653
|
+
return (
|
|
654
|
+
value.providerFailures === undefined ||
|
|
655
|
+
(Array.isArray(value.providerFailures) &&
|
|
656
|
+
value.providerFailures.every(isProviderFailure))
|
|
657
|
+
);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
function isRunUsage(value: unknown): value is RunUsage {
|
|
661
|
+
if (!isRecord(value)) return false;
|
|
662
|
+
return (
|
|
663
|
+
(value.inputTokens === undefined || isFiniteNumber(value.inputTokens)) &&
|
|
664
|
+
(value.outputTokens === undefined || isFiniteNumber(value.outputTokens)) &&
|
|
665
|
+
(value.costUsd === undefined || isFiniteNumber(value.costUsd))
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
function isModelAttemptArray(value: unknown): value is ModelAttempt[] {
|
|
670
|
+
return (
|
|
671
|
+
Array.isArray(value) &&
|
|
672
|
+
value.every((item) => {
|
|
673
|
+
if (!isRecord(item)) return false;
|
|
674
|
+
return (
|
|
675
|
+
typeof item.model === "string" &&
|
|
676
|
+
typeof item.success === "boolean" &&
|
|
677
|
+
(item.error === undefined || typeof item.error === "string")
|
|
678
|
+
);
|
|
679
|
+
})
|
|
680
|
+
);
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
function isProviderFailure(value: unknown): value is ProviderFailure {
|
|
684
|
+
if (!isRecord(value)) return false;
|
|
685
|
+
return (
|
|
686
|
+
typeof value.provider === "string" &&
|
|
687
|
+
typeof value.message === "string" &&
|
|
688
|
+
(value.model === undefined || typeof value.model === "string") &&
|
|
689
|
+
(value.count === undefined || isFiniteNumber(value.count))
|
|
690
|
+
);
|
|
691
|
+
}
|
|
692
|
+
|
|
693
|
+
function isPanelDecision(value: unknown): value is PanelDecision {
|
|
694
|
+
if (!isRecord(value)) return false;
|
|
695
|
+
return (
|
|
696
|
+
typeof value.recommendation === "string" &&
|
|
697
|
+
(value.confidence === "low" ||
|
|
698
|
+
value.confidence === "medium" ||
|
|
699
|
+
value.confidence === "high") &&
|
|
700
|
+
typeof value.needsMoreEvidence === "boolean" &&
|
|
701
|
+
typeof value.answerMarkdown === "string"
|
|
702
|
+
);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
function isPanelFailureReason(value: unknown): boolean {
|
|
706
|
+
return (
|
|
707
|
+
value === "provider" ||
|
|
708
|
+
value === "timeout" ||
|
|
709
|
+
value === "interrupted" ||
|
|
710
|
+
value === "stopped-after-agreement"
|
|
711
|
+
);
|
|
481
712
|
}
|
package/src/types.ts
CHANGED
|
@@ -31,6 +31,43 @@ export interface FusionProfile {
|
|
|
31
31
|
concurrency?: number;
|
|
32
32
|
timeoutMs?: number;
|
|
33
33
|
context?: FusionContextMode;
|
|
34
|
+
stopWhenPanelAgrees?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export type PanelConfidence = "low" | "medium" | "high";
|
|
38
|
+
|
|
39
|
+
export interface PanelDecision {
|
|
40
|
+
recommendation: string;
|
|
41
|
+
confidence: PanelConfidence;
|
|
42
|
+
needsMoreEvidence: boolean;
|
|
43
|
+
answerMarkdown: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface RunUsage {
|
|
47
|
+
inputTokens?: number;
|
|
48
|
+
outputTokens?: number;
|
|
49
|
+
costUsd?: number;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export interface ModelAttempt {
|
|
53
|
+
model: string;
|
|
54
|
+
success: boolean;
|
|
55
|
+
error?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export interface ProviderFailure {
|
|
59
|
+
provider: string;
|
|
60
|
+
model?: string;
|
|
61
|
+
message: string;
|
|
62
|
+
count?: number;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export interface RunObservation {
|
|
66
|
+
model?: string;
|
|
67
|
+
durationMs?: number;
|
|
68
|
+
usage?: RunUsage;
|
|
69
|
+
attempts?: ModelAttempt[];
|
|
70
|
+
providerFailures?: ProviderFailure[];
|
|
34
71
|
}
|
|
35
72
|
|
|
36
73
|
export interface FusionConfig {
|
|
@@ -41,6 +78,7 @@ export interface FusionConfig {
|
|
|
41
78
|
export interface ParsedFusionArgs {
|
|
42
79
|
prompt: string;
|
|
43
80
|
profile?: string;
|
|
81
|
+
operationId?: string;
|
|
44
82
|
}
|
|
45
83
|
|
|
46
84
|
export interface PanelOutput {
|
|
@@ -51,10 +89,16 @@ export interface PanelOutput {
|
|
|
51
89
|
label?: string;
|
|
52
90
|
role?: string;
|
|
53
91
|
model?: string;
|
|
92
|
+
configuredModel?: string;
|
|
93
|
+
decision?: PanelDecision;
|
|
94
|
+
observation?: RunObservation;
|
|
54
95
|
artifactPath?: string;
|
|
55
96
|
sessionPath?: string;
|
|
56
97
|
}
|
|
57
98
|
|
|
99
|
+
export type PanelFailureReason =
|
|
100
|
+
"provider" | "timeout" | "interrupted" | "stopped-after-agreement";
|
|
101
|
+
|
|
58
102
|
export interface FailedPanelSummary {
|
|
59
103
|
index: number;
|
|
60
104
|
agent: string;
|
|
@@ -63,6 +107,9 @@ export interface FailedPanelSummary {
|
|
|
63
107
|
label?: string;
|
|
64
108
|
role?: string;
|
|
65
109
|
model?: string;
|
|
110
|
+
configuredModel?: string;
|
|
111
|
+
reason?: PanelFailureReason;
|
|
112
|
+
observation?: RunObservation;
|
|
66
113
|
artifactPath?: string;
|
|
67
114
|
sessionPath?: string;
|
|
68
115
|
}
|
|
@@ -74,14 +121,19 @@ export interface FusionRun {
|
|
|
74
121
|
id: string;
|
|
75
122
|
prompt: string;
|
|
76
123
|
profileName: string;
|
|
124
|
+
operationId?: string;
|
|
77
125
|
phase: FusionPhase;
|
|
78
126
|
createdAt: number;
|
|
79
127
|
updatedAt: number;
|
|
80
128
|
chainRunId?: string;
|
|
81
129
|
chainAsyncDir?: string;
|
|
82
130
|
panelRunId?: string;
|
|
131
|
+
panelAsyncDir?: string;
|
|
132
|
+
panelStopReason?: "agreement";
|
|
133
|
+
panelStoppedIndices?: number[];
|
|
83
134
|
judgeRunId?: string;
|
|
84
135
|
judgeAsyncDir?: string;
|
|
136
|
+
judgeObservation?: RunObservation;
|
|
85
137
|
panelOutputs?: PanelOutput[];
|
|
86
138
|
panelFailures?: FailedPanelSummary[];
|
|
87
139
|
report?: string;
|