@zelari/core 2.7.0 → 2.9.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/dist/core/AgentHarness.d.ts +52 -0
- package/dist/core/AgentHarness.d.ts.map +1 -1
- package/dist/core/AgentHarness.js +229 -17
- package/dist/core/AgentHarness.js.map +1 -1
- package/dist/core/requestSnapshot.d.ts +5 -1
- package/dist/core/requestSnapshot.d.ts.map +1 -1
- package/dist/core/requestSnapshot.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/memory/adapters.d.ts +42 -0
- package/dist/memory/adapters.d.ts.map +1 -0
- package/dist/memory/adapters.js +160 -0
- package/dist/memory/adapters.js.map +1 -0
- package/dist/memory/context.d.ts +8 -0
- package/dist/memory/context.d.ts.map +1 -0
- package/dist/memory/context.js +65 -0
- package/dist/memory/context.js.map +1 -0
- package/dist/memory/index.d.ts +10 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +10 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/noop.d.ts +26 -0
- package/dist/memory/noop.d.ts.map +1 -0
- package/dist/memory/noop.js +51 -0
- package/dist/memory/noop.js.map +1 -0
- package/dist/memory/policies.d.ts +16 -0
- package/dist/memory/policies.d.ts.map +1 -0
- package/dist/memory/policies.js +144 -0
- package/dist/memory/policies.js.map +1 -0
- package/dist/memory/schemas.d.ts +235 -0
- package/dist/memory/schemas.d.ts.map +1 -0
- package/dist/memory/schemas.js +96 -0
- package/dist/memory/schemas.js.map +1 -0
- package/dist/memory/scoring.d.ts +22 -0
- package/dist/memory/scoring.d.ts.map +1 -0
- package/dist/memory/scoring.js +64 -0
- package/dist/memory/scoring.js.map +1 -0
- package/dist/memory/semantic.d.ts +30 -0
- package/dist/memory/semantic.d.ts.map +1 -0
- package/dist/memory/semantic.js +180 -0
- package/dist/memory/semantic.js.map +1 -0
- package/dist/memory/service.d.ts +45 -0
- package/dist/memory/service.d.ts.map +1 -0
- package/dist/memory/service.js +491 -0
- package/dist/memory/service.js.map +1 -0
- package/dist/memory/types.d.ts +364 -23
- package/dist/memory/types.d.ts.map +1 -1
- package/dist/memory/types.js +45 -9
- package/dist/memory/types.js.map +1 -1
- package/dist/session/modelSurface.d.ts +6 -4
- package/dist/session/modelSurface.d.ts.map +1 -1
- package/dist/session/modelSurface.js +8 -13
- package/dist/session/modelSurface.js.map +1 -1
- package/dist/session/types.js +2 -2
- package/dist/session/types.js.map +1 -1
- package/package.json +3 -3
|
@@ -21,6 +21,7 @@ import { EventBus } from '../shared/eventBus.js';
|
|
|
21
21
|
import { type BrainEvent, type UsageBreakdown } from '../shared/events.js';
|
|
22
22
|
import { ToolRegistry } from './tools/registry.js';
|
|
23
23
|
import { type RoutedRequestSnapshot, type ProviderGenerationOptions } from './requestSnapshot.js';
|
|
24
|
+
import type { MemoryService } from '../memory/types.js';
|
|
24
25
|
export { collapseLoopedAssistantText, detectAssistantTextLoop, detectAssistantTextLoopWindow, normalizeLoopUnit, isStatusTheaterUnit, TEXT_LOOP_RECOVERY_SYSTEM, TEXT_LOOP_RECOVERY_USER_PROMPT, type TextLoopHit, } from './textLoopDetect.js';
|
|
25
26
|
/** Inline image sent to vision-capable providers (raw base64, no data: prefix). */
|
|
26
27
|
export interface AgentImage {
|
|
@@ -76,6 +77,26 @@ export interface AgentToolSpec {
|
|
|
76
77
|
/** JSON Schema for the tool's input arguments. */
|
|
77
78
|
parameters: Record<string, unknown>;
|
|
78
79
|
}
|
|
80
|
+
/** Host-owned progress evidence for mutation-required build turns. */
|
|
81
|
+
export interface BuildProgress {
|
|
82
|
+
toolCalls: number;
|
|
83
|
+
mutationsAttempted: number;
|
|
84
|
+
mutationsSucceeded: number;
|
|
85
|
+
verificationCalls: number;
|
|
86
|
+
recoveries: number;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Provider-neutral build-liveness policy. The host decides whether the task
|
|
90
|
+
* requires an on-disk mutation; the harness owns progress detection and the
|
|
91
|
+
* bounded recovery loop. Provider-specific forcing is serialized only by the
|
|
92
|
+
* provider adapter through generation.toolChoice.
|
|
93
|
+
*/
|
|
94
|
+
export interface BuildLivenessPolicy {
|
|
95
|
+
mutationRequired: boolean;
|
|
96
|
+
/** Zero-mutation recovery turns before the run is failed. Default 2. */
|
|
97
|
+
maxRecoveries?: number;
|
|
98
|
+
}
|
|
99
|
+
export declare const BUILD_LIVENESS_RECOVERY_PROMPT: string;
|
|
79
100
|
export interface AgentHarnessConfig {
|
|
80
101
|
/** Model identifier (e.g. 'grok-4', 'MiniMax-M2.5'). */
|
|
81
102
|
model: string;
|
|
@@ -99,6 +120,14 @@ export interface AgentHarnessConfig {
|
|
|
99
120
|
* tool execution and emit a matching `tool_execution_end` event.
|
|
100
121
|
*/
|
|
101
122
|
toolRegistry?: ToolRegistry;
|
|
123
|
+
/** Enforce successful mutation evidence before a mutate/build task completes. */
|
|
124
|
+
buildLiveness?: BuildLivenessPolicy;
|
|
125
|
+
/**
|
|
126
|
+
* Volatile messages appended only to the routed request. They never enter
|
|
127
|
+
* `config.messages` or `getMessages()` and are re-read before every call.
|
|
128
|
+
* Used for current resource status without rewriting persistent history.
|
|
129
|
+
*/
|
|
130
|
+
requestTail?: () => readonly AgentMessage[];
|
|
102
131
|
/** Optional cwd for tool execution. Defaults to process.cwd(). */
|
|
103
132
|
cwd?: string;
|
|
104
133
|
/**
|
|
@@ -180,6 +209,16 @@ export interface AgentHarnessConfig {
|
|
|
180
209
|
memberId?: string;
|
|
181
210
|
/** Human-readable member label (e.g. "Caronte"). See `memberId`. */
|
|
182
211
|
memberName?: string;
|
|
212
|
+
/**
|
|
213
|
+
* Optional native project memory. The harness performs a bounded, fail-open
|
|
214
|
+
* recall before the first provider call and injects it ephemerally after the
|
|
215
|
+
* stable system prefix (it never mutates conversation history).
|
|
216
|
+
*/
|
|
217
|
+
memoryService?: MemoryService;
|
|
218
|
+
/** Explicit recall objective; defaults to the latest user message. */
|
|
219
|
+
memoryQuery?: string;
|
|
220
|
+
/** Hard character budget for the ephemeral memory block. Default 2,000. */
|
|
221
|
+
memoryContextChars?: number;
|
|
183
222
|
}
|
|
184
223
|
export type ProviderStreamFn = (params: {
|
|
185
224
|
messages: AgentMessage[];
|
|
@@ -187,6 +226,8 @@ export type ProviderStreamFn = (params: {
|
|
|
187
226
|
provider: string;
|
|
188
227
|
tools: AgentToolSpec[];
|
|
189
228
|
signal?: AbortSignal;
|
|
229
|
+
/** Stable harness/session id for provider-side conversation affinity. */
|
|
230
|
+
conversationId?: string;
|
|
190
231
|
/**
|
|
191
232
|
* v1.36.0: optional generation knobs (purpose/temperature/maxTokens).
|
|
192
233
|
* Providers that understand them apply them; others ignore them. Used by
|
|
@@ -256,6 +297,9 @@ export declare class AgentHarness {
|
|
|
256
297
|
private textToolReentries;
|
|
257
298
|
/** Fase M: per-run context-growth counters (reset on every run()). */
|
|
258
299
|
private growth;
|
|
300
|
+
/** Ephemeral per-run context; never appended to `config.messages`. */
|
|
301
|
+
private activeMemoryContext;
|
|
302
|
+
private buildProgress;
|
|
259
303
|
constructor(config: AgentHarnessConfig);
|
|
260
304
|
/**
|
|
261
305
|
* Snapshot of the live transcript (`this.config.messages`) as mutated
|
|
@@ -275,6 +319,11 @@ export declare class AgentHarness {
|
|
|
275
319
|
* @since v1.6.0
|
|
276
320
|
*/
|
|
277
321
|
getMessages(): readonly AgentMessage[];
|
|
322
|
+
/** Immutable snapshot of host-observed build progress for this run. */
|
|
323
|
+
getBuildProgress(): Readonly<BuildProgress>;
|
|
324
|
+
private toolPermissions;
|
|
325
|
+
private isMutationTool;
|
|
326
|
+
private recordSuccessfulTool;
|
|
278
327
|
/**
|
|
279
328
|
* Member identity fields (memberId + memberName) to merge into every
|
|
280
329
|
* event payload. Returns an empty object when the run is a direct
|
|
@@ -343,6 +392,9 @@ export declare class AgentHarness {
|
|
|
343
392
|
* Callers can subscribe via eventBus AND iterate the returned iterable.
|
|
344
393
|
*/
|
|
345
394
|
run(): AsyncIterable<BrainEvent>;
|
|
395
|
+
private prepareMemoryContext;
|
|
396
|
+
/** Build a provider-only view with memory after the stable system prefix. */
|
|
397
|
+
private messagesForProvider;
|
|
346
398
|
/**
|
|
347
399
|
* v1.36.0: capture a deterministic snapshot of the routed request just
|
|
348
400
|
* before it goes out. Never throws into the request path.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AgentHarness.d.ts","sourceRoot":"","sources":["../../src/core/AgentHarness.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AACjD,OAAO,EAEL,KAAK,UAAU,EASf,KAAK,cAAc,EACpB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAUnD,OAAO,EAEL,KAAK,qBAAqB,EAC1B,KAAK,yBAAyB,EAC/B,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"AgentHarness.d.ts","sourceRoot":"","sources":["../../src/core/AgentHarness.ts"],"names":[],"mappings":"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"}
|
|
@@ -24,6 +24,10 @@ import { emptyContextGrowthStats, recordRequest, recordToolResult, recordUsage,
|
|
|
24
24
|
import { createRoutedRequestSnapshot, } from './requestSnapshot.js';
|
|
25
25
|
import { collapseLoopedAssistantText, detectAssistantTextLoopWindow, TEXT_LOOP_RECOVERY_SYSTEM, TEXT_LOOP_RECOVERY_USER_PROMPT, } from './textLoopDetect.js';
|
|
26
26
|
export { collapseLoopedAssistantText, detectAssistantTextLoop, detectAssistantTextLoopWindow, normalizeLoopUnit, isStatusTheaterUnit, TEXT_LOOP_RECOVERY_SYSTEM, TEXT_LOOP_RECOVERY_USER_PROMPT, } from './textLoopDetect.js';
|
|
27
|
+
export const BUILD_LIVENESS_RECOVERY_PROMPT = '[build-liveness] The requested task requires an on-disk implementation, ' +
|
|
28
|
+
'but no successful project mutation has occurred yet. Continue working. ' +
|
|
29
|
+
'Inspect only as needed, then make the required change with an available ' +
|
|
30
|
+
'mutating tool. Do not merely describe a patch or claim completion.';
|
|
27
31
|
// --- Harness ----------------------------------------------------------------
|
|
28
32
|
export class AgentHarness {
|
|
29
33
|
config;
|
|
@@ -59,6 +63,15 @@ export class AgentHarness {
|
|
|
59
63
|
textToolReentries = 0;
|
|
60
64
|
/** Fase M: per-run context-growth counters (reset on every run()). */
|
|
61
65
|
growth = emptyContextGrowthStats();
|
|
66
|
+
/** Ephemeral per-run context; never appended to `config.messages`. */
|
|
67
|
+
activeMemoryContext = '';
|
|
68
|
+
buildProgress = {
|
|
69
|
+
toolCalls: 0,
|
|
70
|
+
mutationsAttempted: 0,
|
|
71
|
+
mutationsSucceeded: 0,
|
|
72
|
+
verificationCalls: 0,
|
|
73
|
+
recoveries: 0,
|
|
74
|
+
};
|
|
62
75
|
constructor(config) {
|
|
63
76
|
this.config = config;
|
|
64
77
|
this.eventBus = config.eventBus;
|
|
@@ -99,6 +112,37 @@ export class AgentHarness {
|
|
|
99
112
|
getMessages() {
|
|
100
113
|
return this.config.messages;
|
|
101
114
|
}
|
|
115
|
+
/** Immutable snapshot of host-observed build progress for this run. */
|
|
116
|
+
getBuildProgress() {
|
|
117
|
+
return { ...this.buildProgress };
|
|
118
|
+
}
|
|
119
|
+
toolPermissions(toolName) {
|
|
120
|
+
return this.config.toolRegistry?.get(toolName)?.permissions ?? [];
|
|
121
|
+
}
|
|
122
|
+
isMutationTool(toolName, args) {
|
|
123
|
+
const permissions = this.toolPermissions(toolName);
|
|
124
|
+
if (!permissions.includes('write'))
|
|
125
|
+
return false;
|
|
126
|
+
// Generic preview contract used by built-in and third-party mutators.
|
|
127
|
+
if (args.dryRun === true)
|
|
128
|
+
return false;
|
|
129
|
+
// Reuse the registry's argument-aware effect classification. In
|
|
130
|
+
// particular, `task agent=explore|verify` is parallel-safe/read-only even
|
|
131
|
+
// though the shared task definition advertises the superset of permissions.
|
|
132
|
+
return classifyToolConcurrency({
|
|
133
|
+
toolName,
|
|
134
|
+
args,
|
|
135
|
+
permissions,
|
|
136
|
+
registered: Boolean(this.config.toolRegistry?.get(toolName)),
|
|
137
|
+
}) === 'exclusive';
|
|
138
|
+
}
|
|
139
|
+
recordSuccessfulTool(toolName, args) {
|
|
140
|
+
const permissions = this.toolPermissions(toolName);
|
|
141
|
+
if (this.isMutationTool(toolName, args))
|
|
142
|
+
this.buildProgress.mutationsSucceeded += 1;
|
|
143
|
+
if (permissions.includes('execute'))
|
|
144
|
+
this.buildProgress.verificationCalls += 1;
|
|
145
|
+
}
|
|
102
146
|
/**
|
|
103
147
|
* Member identity fields (memberId + memberName) to merge into every
|
|
104
148
|
* event payload. Returns an empty object when the run is a direct
|
|
@@ -356,6 +400,14 @@ export class AgentHarness {
|
|
|
356
400
|
this.toolCallCounts = new Map();
|
|
357
401
|
this.textToolReentries = 0;
|
|
358
402
|
this.growth = emptyContextGrowthStats();
|
|
403
|
+
this.buildProgress = {
|
|
404
|
+
toolCalls: 0,
|
|
405
|
+
mutationsAttempted: 0,
|
|
406
|
+
mutationsSucceeded: 0,
|
|
407
|
+
verificationCalls: 0,
|
|
408
|
+
recoveries: 0,
|
|
409
|
+
};
|
|
410
|
+
const memoryWarning = await this.prepareMemoryContext();
|
|
359
411
|
// Emit agent_start
|
|
360
412
|
const startEvent = createBrainEvent('agent_start', this.sessionId, {
|
|
361
413
|
model: this.config.model,
|
|
@@ -364,6 +416,15 @@ export class AgentHarness {
|
|
|
364
416
|
});
|
|
365
417
|
this.emit(startEvent);
|
|
366
418
|
yield startEvent;
|
|
419
|
+
if (memoryWarning) {
|
|
420
|
+
const warning = createBrainEvent('error', this.sessionId, {
|
|
421
|
+
severity: 'recoverable',
|
|
422
|
+
message: memoryWarning,
|
|
423
|
+
code: 'memory_recall_failed',
|
|
424
|
+
});
|
|
425
|
+
this.emit(warning);
|
|
426
|
+
yield warning;
|
|
427
|
+
}
|
|
367
428
|
// === Initial turn (always runs to preserve Phase 12.x behavior) ===
|
|
368
429
|
// The harness processes the messages buffer that was provided in
|
|
369
430
|
// the config. Backward compat: existing callers expect a single
|
|
@@ -375,7 +436,11 @@ export class AgentHarness {
|
|
|
375
436
|
this.emit(initialMsgStart);
|
|
376
437
|
yield initialMsgStart;
|
|
377
438
|
let initialTurnLength = 0;
|
|
378
|
-
const initialFinishRef = {
|
|
439
|
+
const initialFinishRef = {
|
|
440
|
+
value: 'stop',
|
|
441
|
+
clarificationRequested: false,
|
|
442
|
+
providerError: false,
|
|
443
|
+
};
|
|
379
444
|
// Task G.4.3 — capture real provider usage for this turn. The ref
|
|
380
445
|
// is read after runSingleTurn returns and attached to message_end.
|
|
381
446
|
const initialUsageRef = { value: null };
|
|
@@ -404,7 +469,7 @@ export class AgentHarness {
|
|
|
404
469
|
});
|
|
405
470
|
this.emit(initialMsgEnd);
|
|
406
471
|
yield initialMsgEnd;
|
|
407
|
-
// === Agentic tool-call loop ===
|
|
472
|
+
// === Agentic tool-call + bounded build-liveness recovery loop ===
|
|
408
473
|
// Soft budget (maxToolLoopIterations) can auto-extend up to the hard cap
|
|
409
474
|
// when the model still wants tools — multi-step work finishes instead of
|
|
410
475
|
// dying mid-task with "budget exhausted". Absolute hard cap still bounds
|
|
@@ -414,19 +479,56 @@ export class AgentHarness {
|
|
|
414
479
|
const hardCap = this.maxToolLoopHardCap;
|
|
415
480
|
let extensions = 0;
|
|
416
481
|
const maxExtensions = 8;
|
|
482
|
+
const maxBuildRecoveries = Math.max(0, Math.min(10, this.config.buildLiveness?.maxRecoveries ?? 2));
|
|
483
|
+
const planBuildRecovery = (turn) => {
|
|
484
|
+
if (!this.config.buildLiveness?.mutationRequired)
|
|
485
|
+
return null;
|
|
486
|
+
if (this.buildProgress.mutationsSucceeded > 0)
|
|
487
|
+
return null;
|
|
488
|
+
if (turn.value !== 'stop' || turn.clarificationRequested || turn.providerError)
|
|
489
|
+
return null;
|
|
490
|
+
if (this.buildProgress.recoveries >= maxBuildRecoveries)
|
|
491
|
+
return null;
|
|
492
|
+
this.buildProgress.recoveries += 1;
|
|
493
|
+
this.config.messages.push({ role: 'user', content: BUILD_LIVENESS_RECOVERY_PROMPT });
|
|
494
|
+
return {
|
|
495
|
+
purpose: 'build-recovery',
|
|
496
|
+
toolChoice: 'required',
|
|
497
|
+
recoveryAttempt: this.buildProgress.recoveries,
|
|
498
|
+
};
|
|
499
|
+
};
|
|
500
|
+
let lastTurnState = initialFinishRef;
|
|
501
|
+
let recoveryGeneration = planBuildRecovery(initialFinishRef);
|
|
417
502
|
while (!this.cancelled &&
|
|
418
503
|
!hadError &&
|
|
419
|
-
toolLoopTurns <
|
|
420
|
-
|
|
504
|
+
toolLoopTurns < hardCap &&
|
|
505
|
+
(toolLoopTurns < softCap || recoveryGeneration !== null) &&
|
|
506
|
+
(initialFinishRef.value === 'tool_calls' || recoveryGeneration !== null)) {
|
|
421
507
|
toolLoopTurns++;
|
|
508
|
+
if (recoveryGeneration) {
|
|
509
|
+
const recoveryEvent = createBrainEvent('error', this.sessionId, {
|
|
510
|
+
severity: 'recoverable',
|
|
511
|
+
message: `BUILD liveness recovery ${recoveryGeneration.recoveryAttempt}/${maxBuildRecoveries}: ` +
|
|
512
|
+
'no successful mutation observed; continuing instead of completing.',
|
|
513
|
+
code: 'build_liveness_recovery',
|
|
514
|
+
});
|
|
515
|
+
this.emit(recoveryEvent);
|
|
516
|
+
yield recoveryEvent;
|
|
517
|
+
}
|
|
422
518
|
const turnMessageId = crypto.randomUUID();
|
|
423
519
|
const msgStart = createBrainEvent('message_start', this.sessionId, { messageId: turnMessageId, role: 'assistant', ...this.memberFields() });
|
|
424
520
|
this.emit(msgStart);
|
|
425
521
|
yield msgStart;
|
|
426
522
|
let turnLength = 0;
|
|
427
|
-
const turnFinishRef = {
|
|
523
|
+
const turnFinishRef = {
|
|
524
|
+
value: 'stop',
|
|
525
|
+
clarificationRequested: false,
|
|
526
|
+
providerError: false,
|
|
527
|
+
};
|
|
428
528
|
const turnUsageRef = { value: null };
|
|
429
|
-
|
|
529
|
+
const generation = recoveryGeneration ?? undefined;
|
|
530
|
+
recoveryGeneration = null;
|
|
531
|
+
for await (const ev of this.runSingleTurn(turnMessageId, turnFinishRef, turnUsageRef, generation)) {
|
|
430
532
|
if (ev.type === 'message_delta') {
|
|
431
533
|
turnLength += ev.delta.length;
|
|
432
534
|
}
|
|
@@ -449,6 +551,10 @@ export class AgentHarness {
|
|
|
449
551
|
yield msgEnd;
|
|
450
552
|
// Drive the loop: keep going only if this turn again requested tool calls.
|
|
451
553
|
initialFinishRef.value = turnFinishRef.value;
|
|
554
|
+
initialFinishRef.clarificationRequested = turnFinishRef.clarificationRequested;
|
|
555
|
+
initialFinishRef.providerError = turnFinishRef.providerError;
|
|
556
|
+
lastTurnState = turnFinishRef;
|
|
557
|
+
recoveryGeneration = planBuildRecovery(turnFinishRef);
|
|
452
558
|
if (hadError || this.cancelled)
|
|
453
559
|
break;
|
|
454
560
|
// Soft-cap hit but model still wants tools → extend until hard cap.
|
|
@@ -486,6 +592,27 @@ export class AgentHarness {
|
|
|
486
592
|
hitHardCap) {
|
|
487
593
|
yield* this.runFinalAnswerTurn();
|
|
488
594
|
}
|
|
595
|
+
// A mutate/build task may never report successful completion without a
|
|
596
|
+
// successful write-permission tool result. Recovery is bounded above, so
|
|
597
|
+
// an uncooperative provider fails explicitly instead of looping forever.
|
|
598
|
+
if (!this.cancelled &&
|
|
599
|
+
!hadError &&
|
|
600
|
+
this.config.buildLiveness?.mutationRequired &&
|
|
601
|
+
this.buildProgress.mutationsSucceeded === 0 &&
|
|
602
|
+
!lastTurnState.clarificationRequested) {
|
|
603
|
+
hadError = true;
|
|
604
|
+
const providerFailed = lastTurnState.providerError;
|
|
605
|
+
const stalled = createBrainEvent('error', this.sessionId, {
|
|
606
|
+
severity: 'fatal',
|
|
607
|
+
message: providerFailed
|
|
608
|
+
? 'BUILD provider call failed before any successful on-disk mutation was observed.'
|
|
609
|
+
: `BUILD stalled after ${this.buildProgress.recoveries} recovery turn(s): ` +
|
|
610
|
+
'the task required an on-disk mutation, but no successful mutation was observed.',
|
|
611
|
+
code: providerFailed ? 'build_liveness_provider_error' : 'build_liveness_stalled',
|
|
612
|
+
});
|
|
613
|
+
this.emit(stalled);
|
|
614
|
+
yield stalled;
|
|
615
|
+
}
|
|
489
616
|
// === Queue drain (Task 18.1) ===
|
|
490
617
|
// After the initial turn, drain queued user prompts up to
|
|
491
618
|
// maxQueuedIterations. Each iteration appends the next dequeued
|
|
@@ -495,6 +622,8 @@ export class AgentHarness {
|
|
|
495
622
|
while (turns < this.maxQueuedIterations) {
|
|
496
623
|
if (this.cancelled)
|
|
497
624
|
break;
|
|
625
|
+
if (hadError)
|
|
626
|
+
break;
|
|
498
627
|
if (this.queue.length === 0)
|
|
499
628
|
break;
|
|
500
629
|
const queuedPrompt = this.dequeueNext();
|
|
@@ -511,7 +640,11 @@ export class AgentHarness {
|
|
|
511
640
|
this.emit(msgStart);
|
|
512
641
|
yield msgStart;
|
|
513
642
|
let turnLength = 0;
|
|
514
|
-
const turnFinishRef = {
|
|
643
|
+
const turnFinishRef = {
|
|
644
|
+
value: 'stop',
|
|
645
|
+
clarificationRequested: false,
|
|
646
|
+
providerError: false,
|
|
647
|
+
};
|
|
515
648
|
const turnUsageRef = { value: null };
|
|
516
649
|
for await (const ev of this.runSingleTurn(turnMessageId, turnFinishRef, turnUsageRef)) {
|
|
517
650
|
if (ev.type === 'message_delta') {
|
|
@@ -551,17 +684,68 @@ export class AgentHarness {
|
|
|
551
684
|
this.emit(agentEnd);
|
|
552
685
|
yield agentEnd;
|
|
553
686
|
this.activeController = null;
|
|
687
|
+
this.activeMemoryContext = '';
|
|
688
|
+
}
|
|
689
|
+
async prepareMemoryContext() {
|
|
690
|
+
this.activeMemoryContext = '';
|
|
691
|
+
const memory = this.config.memoryService;
|
|
692
|
+
if (!memory)
|
|
693
|
+
return null;
|
|
694
|
+
const latestUser = [...this.config.messages]
|
|
695
|
+
.reverse()
|
|
696
|
+
.find((message) => message.role === 'user')?.content;
|
|
697
|
+
const query = (this.config.memoryQuery ?? latestUser ?? '').trim();
|
|
698
|
+
if (!query)
|
|
699
|
+
return null;
|
|
700
|
+
try {
|
|
701
|
+
const context = await memory.buildContext({
|
|
702
|
+
text: query,
|
|
703
|
+
useGraph: true,
|
|
704
|
+
maxChars: this.config.memoryContextChars ?? 2_000,
|
|
705
|
+
maxMemories: 8,
|
|
706
|
+
});
|
|
707
|
+
this.activeMemoryContext = context.text;
|
|
708
|
+
return null;
|
|
709
|
+
}
|
|
710
|
+
catch (error) {
|
|
711
|
+
return `[memory] recall failed; continuing without memory (${error instanceof Error ? error.message : String(error)}).`;
|
|
712
|
+
}
|
|
713
|
+
}
|
|
714
|
+
/** Build a provider-only view with memory after the stable system prefix. */
|
|
715
|
+
messagesForProvider() {
|
|
716
|
+
let messages = this.config.messages;
|
|
717
|
+
let prefixEnd = 0;
|
|
718
|
+
if (this.activeMemoryContext) {
|
|
719
|
+
while (prefixEnd < messages.length && messages[prefixEnd]?.role === 'system') {
|
|
720
|
+
prefixEnd += 1;
|
|
721
|
+
}
|
|
722
|
+
messages = [
|
|
723
|
+
...messages.slice(0, prefixEnd),
|
|
724
|
+
{ role: 'system', content: this.activeMemoryContext },
|
|
725
|
+
...messages.slice(prefixEnd),
|
|
726
|
+
];
|
|
727
|
+
}
|
|
728
|
+
if (!this.config.requestTail)
|
|
729
|
+
return messages;
|
|
730
|
+
try {
|
|
731
|
+
const tail = this.config.requestTail();
|
|
732
|
+
return tail.length > 0 ? [...messages, ...tail] : messages;
|
|
733
|
+
}
|
|
734
|
+
catch {
|
|
735
|
+
// Runtime status is advisory — never fail a provider request for it.
|
|
736
|
+
return messages;
|
|
737
|
+
}
|
|
554
738
|
}
|
|
555
739
|
/**
|
|
556
740
|
* v1.36.0: capture a deterministic snapshot of the routed request just
|
|
557
741
|
* before it goes out. Never throws into the request path.
|
|
558
742
|
*/
|
|
559
|
-
emitSnapshot(tools, generation) {
|
|
743
|
+
emitSnapshot(tools, generation, messages = this.messagesForProvider()) {
|
|
560
744
|
if (!this.config.onRequestSnapshot)
|
|
561
745
|
return;
|
|
562
746
|
try {
|
|
563
747
|
this.config.onRequestSnapshot(createRoutedRequestSnapshot({
|
|
564
|
-
messages
|
|
748
|
+
messages,
|
|
565
749
|
model: this.config.model,
|
|
566
750
|
provider: this.config.provider,
|
|
567
751
|
tools,
|
|
@@ -586,16 +770,19 @@ export class AgentHarness {
|
|
|
586
770
|
* Extracted from the original monolithic `run()` body to enable
|
|
587
771
|
* the queue-draining loop in Task 18.1.
|
|
588
772
|
*/
|
|
589
|
-
async *runSingleTurn(messageId, finishRef, usageRef) {
|
|
773
|
+
async *runSingleTurn(messageId, finishRef, usageRef, generation) {
|
|
590
774
|
try {
|
|
591
|
-
this.
|
|
592
|
-
|
|
775
|
+
const requestMessages = this.messagesForProvider();
|
|
776
|
+
this.emitSnapshot(this.config.tools, generation, requestMessages);
|
|
777
|
+
recordRequest(this.growth, requestMessages);
|
|
593
778
|
const stream = this.config.providerStream({
|
|
594
|
-
messages:
|
|
779
|
+
messages: requestMessages,
|
|
595
780
|
model: this.config.model,
|
|
596
781
|
provider: this.config.provider,
|
|
597
782
|
tools: this.config.tools,
|
|
598
783
|
signal: this.activeController?.signal,
|
|
784
|
+
conversationId: this.sessionId,
|
|
785
|
+
generation,
|
|
599
786
|
});
|
|
600
787
|
// Per-turn tool call counter (Task G.2). Reset on every turn so
|
|
601
788
|
// queue-drained turns don't accumulate across prompts.
|
|
@@ -698,6 +885,10 @@ export class AgentHarness {
|
|
|
698
885
|
}
|
|
699
886
|
else if (delta.kind === 'tool_call') {
|
|
700
887
|
toolCallsThisTurn++;
|
|
888
|
+
this.buildProgress.toolCalls += 1;
|
|
889
|
+
if (this.isMutationTool(delta.toolName, delta.args)) {
|
|
890
|
+
this.buildProgress.mutationsAttempted += 1;
|
|
891
|
+
}
|
|
701
892
|
// Record this tool call so the assistant message (appended after the
|
|
702
893
|
// turn) carries the full tool_calls list the model emitted.
|
|
703
894
|
turnToolCalls.push({ id: delta.toolCallId, name: delta.toolName, args: delta.args });
|
|
@@ -762,6 +953,12 @@ export class AgentHarness {
|
|
|
762
953
|
this.toolCallCache.set(item.cacheKey, item.content);
|
|
763
954
|
}
|
|
764
955
|
}
|
|
956
|
+
for (let i = 0; i < executed.length; i++) {
|
|
957
|
+
const item = executed[i];
|
|
958
|
+
const pending = pendingNativeTools[i];
|
|
959
|
+
if (!item.isError)
|
|
960
|
+
this.recordSuccessfulTool(pending.toolName, pending.args);
|
|
961
|
+
}
|
|
765
962
|
pendingNativeTools.length = 0;
|
|
766
963
|
}
|
|
767
964
|
// Clarification pause: if the model posed a ---QUESTION--- with choices,
|
|
@@ -771,6 +968,7 @@ export class AgentHarness {
|
|
|
771
968
|
/"choices"\s*:\s*\[/.test(turnText);
|
|
772
969
|
if (clarificationPause) {
|
|
773
970
|
finishRef.value = 'stop';
|
|
971
|
+
finishRef.clarificationRequested = true;
|
|
774
972
|
}
|
|
775
973
|
// Fallback text-format tools: ---TOOLS--- JSON, MiniMax invoke XML,
|
|
776
974
|
// and garbled invoke dumps. Run any text tools not already executed
|
|
@@ -812,6 +1010,10 @@ export class AgentHarness {
|
|
|
812
1010
|
if (typeof maxToolCalls === 'number' && toolCallsThisTurn + 1 > maxToolCalls)
|
|
813
1011
|
break;
|
|
814
1012
|
toolCallsThisTurn++;
|
|
1013
|
+
this.buildProgress.toolCalls += 1;
|
|
1014
|
+
if (this.isMutationTool(tt.name, tt.args)) {
|
|
1015
|
+
this.buildProgress.mutationsAttempted += 1;
|
|
1016
|
+
}
|
|
815
1017
|
const toolCallId = `text-${crypto.randomUUID().slice(0, 8)}`;
|
|
816
1018
|
turnToolCalls.push({ id: toolCallId, name: tt.name, args: tt.args });
|
|
817
1019
|
const startEv = createBrainEvent('tool_execution_start', this.sessionId, {
|
|
@@ -885,6 +1087,8 @@ export class AgentHarness {
|
|
|
885
1087
|
this.emit(endEv);
|
|
886
1088
|
yield endEv;
|
|
887
1089
|
turnToolResults.push({ toolCallId, content: resultStr });
|
|
1090
|
+
if (!isError)
|
|
1091
|
+
this.recordSuccessfulTool(tt.name, tt.args);
|
|
888
1092
|
executedAny = true;
|
|
889
1093
|
}
|
|
890
1094
|
if (executedAny) {
|
|
@@ -957,6 +1161,7 @@ export class AgentHarness {
|
|
|
957
1161
|
break;
|
|
958
1162
|
}
|
|
959
1163
|
else if (delta.kind === 'error') {
|
|
1164
|
+
finishRef.providerError = true;
|
|
960
1165
|
const errEvent = createBrainEvent('error', this.sessionId, {
|
|
961
1166
|
severity: 'recoverable',
|
|
962
1167
|
message: delta.message,
|
|
@@ -977,6 +1182,7 @@ export class AgentHarness {
|
|
|
977
1182
|
}
|
|
978
1183
|
}
|
|
979
1184
|
catch (err) {
|
|
1185
|
+
finishRef.providerError = true;
|
|
980
1186
|
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
981
1187
|
const errEvent = createBrainEvent('error', this.sessionId, {
|
|
982
1188
|
severity: 'recoverable',
|
|
@@ -1024,21 +1230,27 @@ export class AgentHarness {
|
|
|
1024
1230
|
content: '[system] Hard tool-iteration ceiling reached. Stop calling tools and give a clear status: what is DONE, what remains, and the exact next steps. Use what you already gathered. Do not apologize for the tools.',
|
|
1025
1231
|
});
|
|
1026
1232
|
let totalLength = 0;
|
|
1027
|
-
const finishRef = {
|
|
1233
|
+
const finishRef = {
|
|
1234
|
+
value: 'stop',
|
|
1235
|
+
clarificationRequested: false,
|
|
1236
|
+
providerError: false,
|
|
1237
|
+
};
|
|
1028
1238
|
const usageRef = { value: null };
|
|
1029
1239
|
// Temporarily drop tools for this call by building a no-tools provider
|
|
1030
1240
|
// invocation. We re-enter runSingleTurn but with an empty tools list via
|
|
1031
1241
|
// a throwaway config override is not possible (config is readonly), so we
|
|
1032
1242
|
// call the providerStream directly with tools: [].
|
|
1033
|
-
|
|
1243
|
+
const requestMessages = this.messagesForProvider();
|
|
1244
|
+
recordRequest(this.growth, requestMessages);
|
|
1034
1245
|
try {
|
|
1035
|
-
this.emitSnapshot([]);
|
|
1246
|
+
this.emitSnapshot([], undefined, requestMessages);
|
|
1036
1247
|
const stream = this.config.providerStream({
|
|
1037
|
-
messages:
|
|
1248
|
+
messages: requestMessages,
|
|
1038
1249
|
model: this.config.model,
|
|
1039
1250
|
provider: this.config.provider,
|
|
1040
1251
|
tools: [],
|
|
1041
1252
|
signal: this.activeController?.signal,
|
|
1253
|
+
conversationId: this.sessionId,
|
|
1042
1254
|
});
|
|
1043
1255
|
for await (const delta of stream) {
|
|
1044
1256
|
if (this.cancelled)
|