newmark-agent 0.6.3 → 0.6.7
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/config.example.json +13 -3
- package/dist/cli-commands.d.ts +1 -1
- package/dist/cli-commands.js +53 -2
- package/dist/cli-discovery.js +3 -0
- package/dist/conversation-utility-host.bundle.cjs +3046 -1038
- package/dist/conversation-utility-host.js +94 -7
- package/dist/core/agent.d.ts +149 -12
- package/dist/core/agent.js +843 -176
- package/dist/core/agentKernelRunner.d.ts +7 -1
- package/dist/core/agentKernelRunner.js +171 -22
- package/dist/core/autoRouter.d.ts +49 -44
- package/dist/core/autoRouter.js +117 -302
- package/dist/core/branchIdentity.d.ts +29 -0
- package/dist/core/branchIdentity.js +54 -0
- package/dist/core/config.js +27 -11
- package/dist/core/continuation/contracts.d.ts +1 -1
- package/dist/core/continuation/store.d.ts +119 -1
- package/dist/core/continuation/store.js +337 -19
- package/dist/core/conversationKernel.d.ts +62 -8
- package/dist/core/conversationKernel.js +361 -47
- package/dist/core/conversationStateDocument.d.ts +18 -0
- package/dist/core/conversationStateDocument.js +88 -0
- package/dist/core/conversationVisualBudget.d.ts +74 -0
- package/dist/core/conversationVisualBudget.js +153 -0
- package/dist/core/electronUtilityAgentClient.d.ts +3 -2
- package/dist/core/electronUtilityAgentClient.js +32 -8
- package/dist/core/electronUtilityRuntimePool.d.ts +28 -3
- package/dist/core/electronUtilityRuntimePool.js +93 -24
- package/dist/core/hostRuntimeHooks.d.ts +23 -0
- package/dist/core/hostRuntimeHooks.js +17 -0
- package/dist/core/jevDecision.d.ts +144 -0
- package/dist/core/jevDecision.js +226 -0
- package/dist/core/memoryProbe.d.ts +24 -0
- package/dist/core/memoryProbe.js +104 -0
- package/dist/core/mobilePairing.d.ts +7 -1
- package/dist/core/mobilePairing.js +9 -1
- package/dist/core/performanceDiagnostics.d.ts +1 -1
- package/dist/core/routeDecisionValidator.d.ts +86 -0
- package/dist/core/routeDecisionValidator.js +249 -0
- package/dist/core/routeEligibility.d.ts +52 -0
- package/dist/core/routeEligibility.js +108 -0
- package/dist/core/runtimeMemoryBudget.d.ts +6 -0
- package/dist/core/runtimeMemoryBudget.js +12 -0
- package/dist/core/utilityAgentProtocol.d.ts +8 -10
- package/dist/core/utilityHostToolRouter.js +2 -0
- package/dist/core/visualDownscale.d.ts +6 -0
- package/dist/core/visualDownscale.js +137 -0
- package/dist/core/wslAgentClient.d.ts +1 -2
- package/dist/core/wslAgentClient.js +0 -8
- package/dist/core/wslAgentProtocol.d.ts +1 -10
- package/dist/core/wslAgentRuntimePool.d.ts +1 -3
- package/dist/core/wslAgentRuntimePool.js +17 -22
- package/dist/llm/provider.d.ts +3 -1
- package/dist/llm/provider.js +53 -9
- package/dist/main.js +108 -31
- package/dist/preload.js +3 -1
- package/dist/server.js +30 -18
- package/dist/tools/computerUse.d.ts +4 -0
- package/dist/tools/computerUse.js +202 -4
- package/dist/tools/computerUsePowerShellHost.d.ts +6 -1
- package/dist/tools/computerUsePowerShellHost.js +105 -31
- package/dist/tools/index.js +4 -1
- package/dist/tui/src/adapters/core-runtime-adapter.js +13 -1
- package/dist/tui/src/i18n.js +12 -1
- package/dist/tui/src/render.js +9 -2
- package/dist/tui/src/settings-schema.js +19 -0
- package/dist/tui/src/state.js +69 -1
- package/dist/ui/index.html +994 -277
- package/dist/ui/lucide-sprite.svg +0 -8
- package/dist/wsl-agent-host.bundle.cjs +2851 -1013
- package/dist/wsl-agent-host.js +0 -3
- package/package.json +38 -9
|
@@ -7,6 +7,8 @@ const conversationTarget_1 = require("./core/conversationTarget");
|
|
|
7
7
|
const utilityHostToolBridge_1 = require("./core/utilityHostToolBridge");
|
|
8
8
|
const terminalTakeover_1 = require("./tools/terminalTakeover");
|
|
9
9
|
const runtimeLifecycle_1 = require("./core/runtimeLifecycle");
|
|
10
|
+
const memoryProbe_1 = require("./core/memoryProbe");
|
|
11
|
+
const workEventCoalescer_1 = require("./core/workEventCoalescer");
|
|
10
12
|
const root = String(process.env.NEWMARK_RUNTIME_ROOT || '');
|
|
11
13
|
const expectedRuntimeKey = String(process.env.NEWMARK_RUNTIME_KEY || '');
|
|
12
14
|
if (!root)
|
|
@@ -17,6 +19,11 @@ const parentPort = process.parentPort;
|
|
|
17
19
|
if (!parentPort)
|
|
18
20
|
throw new Error('Electron utility parentPort is unavailable');
|
|
19
21
|
const host = new agent_1.Agent(root, { runtimeLifecycleRole: 'utility' });
|
|
22
|
+
/**
|
|
23
|
+
* Diagnostic probe (source-only, env-gated). `memoryProbe.disabled.ts` replaces
|
|
24
|
+
* this module in packaged builds, so no probe code ships in the final artifact.
|
|
25
|
+
*/
|
|
26
|
+
const hostHooks = (0, memoryProbe_1.installHostRuntimeHooks)({ root });
|
|
20
27
|
host.tools.setHostProfile({
|
|
21
28
|
kind: 'electron-utility',
|
|
22
29
|
platform: process.platform,
|
|
@@ -26,9 +33,35 @@ host.tools.setHostProfile({
|
|
|
26
33
|
const kernel = new conversationKernel_1.ConversationKernel(root, host, null);
|
|
27
34
|
let activeTarget = null;
|
|
28
35
|
function post(value) {
|
|
29
|
-
|
|
36
|
+
hostHooks.countPosted(value);
|
|
37
|
+
try {
|
|
38
|
+
parentPort.postMessage(value);
|
|
39
|
+
}
|
|
40
|
+
catch { /* the parent may already be gone during shutdown */ }
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* dev-0.6.6 long-run stability: coalesce response/thought deltas **inside the
|
|
44
|
+
* host** before they cross the process boundary.
|
|
45
|
+
*
|
|
46
|
+
* Measured defect: the host posted one IPC message per model delta (18,746
|
|
47
|
+
* messages / 722 MiB for ~31 MB of model text — a 23x amplification) and the
|
|
48
|
+
* heap snapshot showed 10,728 retained per-delta strings. The main process
|
|
49
|
+
* already coalesces for the renderer (`main.ts` WorkEventCoalescer) and the
|
|
50
|
+
* renderer expands `coalescedDeltas` back into individual deltas, so batching at
|
|
51
|
+
* the host boundary changes nothing the user or the transcript sees — it only
|
|
52
|
+
* stops the per-delta pile-up. Lifecycle/tool events still flush immediately and
|
|
53
|
+
* keep their ordering.
|
|
54
|
+
*/
|
|
55
|
+
const hostWorkCoalescer = new workEventCoalescer_1.WorkEventCoalescer(event => post({ event: 'work', data: event }), Math.max(4, Number(process.env.NEWMARK_HOST_COALESCE_MS) || 16));
|
|
56
|
+
function flushHostWorkEvents() {
|
|
57
|
+
try {
|
|
58
|
+
hostWorkCoalescer.flushAll();
|
|
59
|
+
}
|
|
60
|
+
catch { /* shutdown best effort */ }
|
|
30
61
|
}
|
|
31
|
-
|
|
62
|
+
process.on('exit', flushHostWorkEvents);
|
|
63
|
+
process.on('beforeExit', flushHostWorkEvents);
|
|
64
|
+
kernel.subscribe(event => hostWorkCoalescer.push(event));
|
|
32
65
|
function checkedTarget(target) {
|
|
33
66
|
const normalized = (0, conversationTarget_1.normalizeConversationTarget)(target);
|
|
34
67
|
if (normalized.runtimeKey !== expectedRuntimeKey) {
|
|
@@ -37,6 +70,61 @@ function checkedTarget(target) {
|
|
|
37
70
|
activeTarget = normalized;
|
|
38
71
|
return normalized;
|
|
39
72
|
}
|
|
73
|
+
/**
|
|
74
|
+
* dev-0.6.6 long-run memory reclamation: the transcript part of a snapshot is
|
|
75
|
+
* only sent when the caller cannot already prove it holds that exact revision.
|
|
76
|
+
*
|
|
77
|
+
* Measured before this: RPC responses (mostly snapshots) were **86% of all
|
|
78
|
+
* cross-process bytes** in a 12-round load (24 responses = 329 MiB, single
|
|
79
|
+
* response up to 38 MB) because every poll re-serialized the whole conversation.
|
|
80
|
+
*
|
|
81
|
+
* The handshake is caller-driven: a slim payload is only produced when the
|
|
82
|
+
* caller supplies the revision it currently holds. A caller that holds nothing
|
|
83
|
+
* (or painted another conversation) receives the full transcript; the main
|
|
84
|
+
* process only attaches a revision it received from that same renderer through
|
|
85
|
+
* `conversation:ackTranscript`.
|
|
86
|
+
*/
|
|
87
|
+
const transcriptRevisions = new Map();
|
|
88
|
+
function transcriptRevisionOf(snapshot) {
|
|
89
|
+
const messages = Array.isArray(snapshot.chatMessages) ? snapshot.chatMessages : [];
|
|
90
|
+
const runs = Array.isArray(snapshot.workRuns) ? snapshot.workRuns : [];
|
|
91
|
+
const last = messages.length ? messages[messages.length - 1] : null;
|
|
92
|
+
const lastRun = runs.length ? runs[runs.length - 1] : null;
|
|
93
|
+
// Only what the renderer actually paints takes part in the revision: the
|
|
94
|
+
// visible message window and the work-run summary. `history` deliberately
|
|
95
|
+
// does NOT: it grows on every tool round inside a turn, and folding it in made
|
|
96
|
+
// every mid-turn poll look "changed" (measured: no slim snapshots at all).
|
|
97
|
+
// Anything derived from `history` is only recomputed when the window changes,
|
|
98
|
+
// which is exactly when a full payload is sent anyway.
|
|
99
|
+
return [
|
|
100
|
+
messages.length,
|
|
101
|
+
String(last?.messageId || last?.clientMessageId || last?.timestamp || ''),
|
|
102
|
+
String(typeof last?.content === 'string' ? last.content.length : ''),
|
|
103
|
+
String(snapshot.totalMessages ?? ''),
|
|
104
|
+
String(snapshot.windowStart ?? ''),
|
|
105
|
+
runs.length,
|
|
106
|
+
String(lastRun?.status || ''),
|
|
107
|
+
String(lastRun?.endedAt || ''),
|
|
108
|
+
].join('|');
|
|
109
|
+
}
|
|
110
|
+
function applyTranscriptPolicy(snapshot, options) {
|
|
111
|
+
const revision = transcriptRevisionOf(snapshot);
|
|
112
|
+
const key = `${snapshot.target?.workspaceId || ''}::${snapshot.target?.conversationId || ''}`;
|
|
113
|
+
transcriptRevisions.set(key, revision);
|
|
114
|
+
const callerRevision = String(options.transcriptRevision || '');
|
|
115
|
+
const full = options.transcript === 'force' || !callerRevision || callerRevision !== revision;
|
|
116
|
+
if (full)
|
|
117
|
+
return { ...snapshot, transcriptRevision: revision };
|
|
118
|
+
return {
|
|
119
|
+
...snapshot,
|
|
120
|
+
chatMessages: undefined,
|
|
121
|
+
history: undefined,
|
|
122
|
+
workRuns: undefined,
|
|
123
|
+
workEvents: undefined,
|
|
124
|
+
transcriptUnchanged: true,
|
|
125
|
+
transcriptRevision: revision,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
40
128
|
(0, utilityHostToolBridge_1.configureUtilityHostToolBridge)(request => post({ event: 'host_tool_request', data: request }), () => activeTarget ? {
|
|
41
129
|
workspaceId: activeTarget.workspaceId,
|
|
42
130
|
conversationId: activeTarget.conversationId,
|
|
@@ -64,8 +152,10 @@ async function handle(request) {
|
|
|
64
152
|
const result = await kernel.prompt(request.params.message, target, request.params.options, request.params.queueMode);
|
|
65
153
|
return { ...result, backend: 'utility', pid: process.pid };
|
|
66
154
|
}
|
|
67
|
-
if (request.method === 'snapshot')
|
|
68
|
-
|
|
155
|
+
if (request.method === 'snapshot') {
|
|
156
|
+
const options = request.params.options || {};
|
|
157
|
+
return applyTranscriptPolicy(kernel.snapshot(checkedTarget(request.params.target), options), options);
|
|
158
|
+
}
|
|
69
159
|
if (request.method === 'rewind') {
|
|
70
160
|
return kernel.rewind(checkedTarget(request.params.target), request.params.messageIndex);
|
|
71
161
|
}
|
|
@@ -87,9 +177,6 @@ async function handle(request) {
|
|
|
87
177
|
if (request.method === 'context_compress') {
|
|
88
178
|
return kernel.compressContext(checkedTarget(request.params.target), request.params.options);
|
|
89
179
|
}
|
|
90
|
-
if (request.method === 'rate_auto_route') {
|
|
91
|
-
return kernel.rateAutoRoute(checkedTarget(request.params.target), request.params.score, request.params.routeId);
|
|
92
|
-
}
|
|
93
180
|
if (request.method === 'set_work_run_expanded') {
|
|
94
181
|
return kernel.setWorkRunExpanded(checkedTarget(request.params.target), request.params.runId, request.params.expanded);
|
|
95
182
|
}
|
package/dist/core/agent.d.ts
CHANGED
|
@@ -55,11 +55,27 @@ export interface ModelValidationProgress {
|
|
|
55
55
|
check: string;
|
|
56
56
|
}>;
|
|
57
57
|
}
|
|
58
|
-
|
|
58
|
+
/** Editable settings for model-backed Auto decisions. */
|
|
59
|
+
export interface JevDecisionModelPatch {
|
|
60
|
+
enabled?: boolean;
|
|
61
|
+
timeoutMs?: number;
|
|
62
|
+
}
|
|
63
|
+
export interface JevDecisionModelState {
|
|
64
|
+
/** `models.auto_switch`: the user's Auto master switch. */
|
|
65
|
+
autoEnabled: boolean;
|
|
66
|
+
/** True when Auto is off: the decision model cannot be edited and cannot move a model. */
|
|
67
|
+
locked: boolean;
|
|
68
|
+
lockReason?: 'auto_disabled';
|
|
69
|
+
enabled: boolean;
|
|
70
|
+
decisionModel: 'current_eligible_model';
|
|
71
|
+
thinkingMode: 'off';
|
|
72
|
+
outputFormat: 'strict_json_schema';
|
|
73
|
+
timeoutMs: number;
|
|
74
|
+
}
|
|
75
|
+
export interface JevDecisionModelUpdateResult {
|
|
59
76
|
ok: boolean;
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
reason?: 'invalid_score' | 'no_active_auto_route' | 'stale_route' | 'already_rated';
|
|
77
|
+
reason?: 'auto_disabled' | 'invalid_value';
|
|
78
|
+
state: JevDecisionModelState;
|
|
63
79
|
}
|
|
64
80
|
export declare const ROOT_AGENT_ACTOR_ID = "00000000-0000-4000-8000-000000000001";
|
|
65
81
|
export declare function normalizeIntelligenceTier(value: unknown): 'low' | 'medium' | 'high' | 'xhigh' | 'max' | 'ultra';
|
|
@@ -85,6 +101,8 @@ export interface CompressionCacheEntry {
|
|
|
85
101
|
foldedChars: number;
|
|
86
102
|
model: string;
|
|
87
103
|
fallback: boolean;
|
|
104
|
+
/** Branch node that owns this folded history. Sibling pages must never read it. */
|
|
105
|
+
branchNodeId?: string;
|
|
88
106
|
}
|
|
89
107
|
type ConversationModelSelection = {
|
|
90
108
|
kind: 'auto';
|
|
@@ -413,6 +431,8 @@ export declare class Agent {
|
|
|
413
431
|
private modelSwitchCompressionPromise;
|
|
414
432
|
private activePeerAgents;
|
|
415
433
|
private peerProviderCaches;
|
|
434
|
+
/** Reuses the provider connection for current-model JEV calls without sharing conversation build state. */
|
|
435
|
+
private readonly jevProviderCache;
|
|
416
436
|
private awaitingAgentKernelRuntime;
|
|
417
437
|
private pendingAgentKernelQueue;
|
|
418
438
|
private linkedPlanAccess;
|
|
@@ -432,7 +452,7 @@ export declare class Agent {
|
|
|
432
452
|
private finalizingWorkRunId;
|
|
433
453
|
private agentRunService;
|
|
434
454
|
private agentRunByWorkRunId;
|
|
435
|
-
private readonly
|
|
455
|
+
private readonly routeController;
|
|
436
456
|
private resolvedDeployment;
|
|
437
457
|
private fixedDeployment;
|
|
438
458
|
private preferredConversationModelSelection;
|
|
@@ -444,11 +464,21 @@ export declare class Agent {
|
|
|
444
464
|
private lastRouteRetryDelayMs;
|
|
445
465
|
private routeAttemptStartedAt;
|
|
446
466
|
private readonly providerBalanceBlockedUntilByDeployment;
|
|
447
|
-
private readonly explicitlyRatedRoutes;
|
|
448
467
|
private conversationStateCache;
|
|
449
468
|
private conversationStateCacheFingerprint;
|
|
469
|
+
private conversationStateWrittenFingerprint;
|
|
470
|
+
private conversationShardFingerprint;
|
|
471
|
+
private hydratedShardEntries;
|
|
472
|
+
/**
|
|
473
|
+
* Revision of the durable queue snapshot this runtime is working from. The
|
|
474
|
+
* merge only accepts a writer's queue when that writer has seen the persisted
|
|
475
|
+
* revision, so an outdated in-memory snapshot can neither drop queued work
|
|
476
|
+
* nor resurrect an entry that was already consumed or cleared.
|
|
477
|
+
*/
|
|
478
|
+
private continuationRevision;
|
|
450
479
|
private conversationStateFlushTimers;
|
|
451
480
|
private conversationStateDirty;
|
|
481
|
+
private conversationStateLastWriteAt;
|
|
452
482
|
private systemPromptCache;
|
|
453
483
|
private toolDefinitionCache;
|
|
454
484
|
private modelValidationPromise;
|
|
@@ -528,6 +558,16 @@ export declare class Agent {
|
|
|
528
558
|
activeModelName(): string;
|
|
529
559
|
modelSelectionValue(): string;
|
|
530
560
|
currentWorkRunId(): string;
|
|
561
|
+
/**
|
|
562
|
+
* The branch node that owns the currently active Build. Provider session ids
|
|
563
|
+
* and branch-scoped caches must use this identity instead of "the branch that
|
|
564
|
+
* happens to be active", otherwise a concurrently running sibling branch
|
|
565
|
+
* (branch-communication mode) or a page switched mid-Build would read another
|
|
566
|
+
* branch's remote session and folded history.
|
|
567
|
+
*/
|
|
568
|
+
activeWorkRunBranchId(): string;
|
|
569
|
+
/** Full conversation identity of one branch node (shared by every branch kind). */
|
|
570
|
+
branchConversationIdentity(branchNodeId: string): string;
|
|
531
571
|
activeModelConfig(): ReturnType<ConfigManager['allModels']>[number] | undefined;
|
|
532
572
|
requestedModelSelection(): ModelSelection;
|
|
533
573
|
resetAutoRoute(): void;
|
|
@@ -539,12 +579,65 @@ export declare class Agent {
|
|
|
539
579
|
recordRouteSuccess(latencyMs?: number, throughput?: number): void;
|
|
540
580
|
recordRouteToolOutcome(valid: boolean): void;
|
|
541
581
|
updateProviders(value: unknown): void;
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
582
|
+
/**
|
|
583
|
+
* Auto master switch. Every automatic model decision in this runtime is
|
|
584
|
+
* gated on it: when it is off the Agent neither routes nor edits the current
|
|
585
|
+
* model decision settings, and no code path may move the active model on its own.
|
|
586
|
+
*/
|
|
587
|
+
autoDecisionEnabled(): boolean;
|
|
588
|
+
/** Current-model JEV settings exposed to GUI / TUI / CLI editors. */
|
|
589
|
+
jevDecisionModelState(): JevDecisionModelState;
|
|
590
|
+
/**
|
|
591
|
+
* Edit current-model Auto decision settings.
|
|
592
|
+
*
|
|
593
|
+
* Refuses every write while Auto is off (`auto_disabled`): with automatic
|
|
594
|
+
* decision-making disabled, not even the decision-model configuration may
|
|
595
|
+
* change — that is what "Auto off never moves a model" means at the editor
|
|
596
|
+
* boundary. Invalid values are rejected without touching the stored config.
|
|
597
|
+
*/
|
|
598
|
+
updateJevDecisionModel(patch?: JevDecisionModelPatch): JevDecisionModelUpdateResult;
|
|
546
599
|
private workspaceConversationKey;
|
|
547
600
|
private workspaceConversationStorePath;
|
|
601
|
+
/**
|
|
602
|
+
* Heavy conversation payload that lives in a per-conversation shard file
|
|
603
|
+
* instead of the workspace index document. Everything else (title, pinning,
|
|
604
|
+
* order, draft, mode, goal, runtime owner, counters) stays in the index so
|
|
605
|
+
* listing, sorting and cross-process merge never need to parse a transcript.
|
|
606
|
+
*/
|
|
607
|
+
private static readonly CONVERSATION_SHARD_FIELDS;
|
|
608
|
+
private workspaceConversationShardDir;
|
|
609
|
+
private conversationShardFileName;
|
|
610
|
+
private conversationShardPath;
|
|
611
|
+
/**
|
|
612
|
+
* Hydrate one conversation entry from its shard on first access. The heavy
|
|
613
|
+
* fields are non-enumerable so `{ ...entry }` (and therefore the index
|
|
614
|
+
* document written back to disk) never pulls a transcript into memory, while
|
|
615
|
+
* every existing reader that asks for `entry.chatMessages` / `entry.history`
|
|
616
|
+
* keeps working unchanged.
|
|
617
|
+
*/
|
|
618
|
+
private attachConversationShard;
|
|
619
|
+
/**
|
|
620
|
+
* Heavy payload carried in memory by this entry, or `null` when the entry is
|
|
621
|
+
* a shard-backed index record whose heavy fields were never touched. That
|
|
622
|
+
* distinction is what keeps unrelated conversations off the write path.
|
|
623
|
+
*/
|
|
624
|
+
private conversationShardSnapshot;
|
|
625
|
+
/**
|
|
626
|
+
* Force one shard-backed entry into memory. Used only on the rare recovery
|
|
627
|
+
* paths that must compare against a payload written by another runtime.
|
|
628
|
+
*/
|
|
629
|
+
private hydrateConversationEntry;
|
|
630
|
+
/**
|
|
631
|
+
* Durable queue merge.
|
|
632
|
+
*
|
|
633
|
+
* Queue entries are the user's pending work, so a runtime that never saw an
|
|
634
|
+
* entry must not delete it, while an entry this runtime actually consumed
|
|
635
|
+
* must not be resurrected. Identity-based union minus exactly the consumed
|
|
636
|
+
* ids gives both guarantees without needing a global revision clock.
|
|
637
|
+
*/
|
|
638
|
+
private mergeConversationContinuations;
|
|
639
|
+
/** Index-document form of a conversation entry: metadata plus a shard pointer. */
|
|
640
|
+
private conversationIndexEntryForDisk;
|
|
548
641
|
private workspaceConversationStateKey;
|
|
549
642
|
private workspaceConversationStateKeyFor;
|
|
550
643
|
private workspaceConversationPrefix;
|
|
@@ -581,6 +674,16 @@ export declare class Agent {
|
|
|
581
674
|
handleImageDisplayWithDescription(args: string, signal?: AbortSignal): Promise<string>;
|
|
582
675
|
/** Keep media bytes in one content-addressed asset and state.json as refs. */
|
|
583
676
|
private conversationEntryForDisk;
|
|
677
|
+
/**
|
|
678
|
+
* Bound the live Build ledger.
|
|
679
|
+
*
|
|
680
|
+
* `normalizeWorkRuns()` already windows the persisted/served ledger to 120
|
|
681
|
+
* runs, but the live `this.workRuns` array kept every Build block of the
|
|
682
|
+
* conversation (measured: 307 runs / 4.6 MiB after 300 turns). The renderer
|
|
683
|
+
* only ever shows the newest window, so older terminal runs can be dropped
|
|
684
|
+
* from memory while the conversation continues.
|
|
685
|
+
*/
|
|
686
|
+
private pruneLiveWorkRuns;
|
|
584
687
|
private normalizeWorkRuns;
|
|
585
688
|
private recoverPersistedWorkRuns;
|
|
586
689
|
private publishConversationTitle;
|
|
@@ -685,7 +788,20 @@ export declare class Agent {
|
|
|
685
788
|
private normalizeContinuations;
|
|
686
789
|
private normalizeConversationPlan;
|
|
687
790
|
private readStoredConversationState;
|
|
791
|
+
/** Durable replacement-style text write (temp file + fsync + rename). */
|
|
792
|
+
private writeAtomicTextFile;
|
|
688
793
|
private writeStoredConversationState;
|
|
794
|
+
/**
|
|
795
|
+
* Coalesced conversation-state write.
|
|
796
|
+
*
|
|
797
|
+
* Mid-turn persistence used to rewrite the whole workspace document
|
|
798
|
+
* synchronously on every kernel event (measured: 5.33 full rewrites per turn
|
|
799
|
+
* with no tools). The document grows with the conversation, so that cost grew
|
|
800
|
+
* with the turn count. This path keeps durability at turn boundaries (the
|
|
801
|
+
* terminal save stays synchronous and cancels any pending timer) while
|
|
802
|
+
* throttling intermediate saves: the latest snapshot wins, and bursts inside
|
|
803
|
+
* one throttle window collapse into a single write.
|
|
804
|
+
*/
|
|
689
805
|
private scheduleStoredConversationState;
|
|
690
806
|
flushWorkspaceConversationState(): void;
|
|
691
807
|
getStoredFlowSuspension(conversationId?: string, ws?: WorkspaceInfo | null): FlowSuspensionRecord | null;
|
|
@@ -1105,10 +1221,20 @@ export declare class Agent {
|
|
|
1105
1221
|
private autoSwitchSubset;
|
|
1106
1222
|
private autoRouteCandidates;
|
|
1107
1223
|
private persistRouteDecision;
|
|
1108
|
-
private loadLearnedRouteFeedback;
|
|
1109
|
-
private recordRouteFeedbackFor;
|
|
1110
1224
|
allModelNames(): string[];
|
|
1111
1225
|
evaluateAndSwitch(task: string, override?: AgentPromptMessage['routePolicy']): Promise<boolean>;
|
|
1226
|
+
/**
|
|
1227
|
+
* Auto Router v2 decision pipeline:
|
|
1228
|
+
*
|
|
1229
|
+
* RouteEligibilityGuard → JevDecisionEngine → RouteDecisionValidator → pin
|
|
1230
|
+
*
|
|
1231
|
+
* The current conversation model is the only Auto decision source. If it is
|
|
1232
|
+
* disabled, times out, crashes or returns something the guard cannot accept,
|
|
1233
|
+
* Auto stops without selecting another deployment.
|
|
1234
|
+
*/
|
|
1235
|
+
private decideAutoRoute;
|
|
1236
|
+
/** Resolve JEV to the current eligible conversation model, never a second model slot. */
|
|
1237
|
+
private resolveCurrentModelJevEngine;
|
|
1112
1238
|
shouldExposeToolInterface(): boolean;
|
|
1113
1239
|
modelIsUnavailable(modelName: string): boolean;
|
|
1114
1240
|
private failedDeploymentsThisRun;
|
|
@@ -1229,6 +1355,17 @@ export declare class Agent {
|
|
|
1229
1355
|
private formatCompressionSummary;
|
|
1230
1356
|
private persistCompressedHistory;
|
|
1231
1357
|
private compressionArchiveScopeKey;
|
|
1358
|
+
/**
|
|
1359
|
+
* The hot folded-history cache belongs to one branch node. Legacy entries
|
|
1360
|
+
* (created before branch scoping) belong to the root node, which is where
|
|
1361
|
+
* they were produced.
|
|
1362
|
+
*/
|
|
1363
|
+
private compressionCacheForBranch;
|
|
1364
|
+
/**
|
|
1365
|
+
* Persist the union of every branch's folded history: the live in-memory
|
|
1366
|
+
* cache only holds the active branch, and the stored entry holds the rest.
|
|
1367
|
+
*/
|
|
1368
|
+
private mergedCompressionCacheForPersist;
|
|
1232
1369
|
private coldCompressionEntries;
|
|
1233
1370
|
private compressionArchiveEntryCount;
|
|
1234
1371
|
private archiveColdCompressionEntries;
|