@adhdev/daemon-core 0.9.82-rc.137 → 0.9.82-rc.138
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/chat/source-machine.d.ts +166 -0
- package/dist/chat/source-resolver.d.ts +104 -0
- package/dist/cli-adapters/cli-state-engine.d.ts +15 -0
- package/dist/cli-adapters/provider-cli-adapter.d.ts +0 -1
- package/dist/cli-adapters/provider-cli-parse.d.ts +1 -0
- package/dist/cli-adapters/provider-cli-shared.d.ts +1 -0
- package/dist/index.js +922 -328
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +922 -328
- package/dist/index.mjs.map +1 -1
- package/dist/mesh/contracts.d.ts +164 -0
- package/dist/providers/contracts.d.ts +19 -0
- package/dist/providers/read-chat-contract.d.ts +29 -0
- package/dist/providers/transcript-v2.d.ts +176 -0
- package/dist/shared-types.d.ts +7 -0
- package/dist/status/snapshot.d.ts +1 -0
- package/dist/types.d.ts +5 -0
- package/package.json +1 -1
- package/src/chat/source-machine.ts +534 -0
- package/src/chat/source-resolver.ts +0 -0
- package/src/chat/subscription-updates.ts +9 -0
- package/src/cli-adapters/cli-state-engine.ts +103 -6
- package/src/cli-adapters/provider-cli-adapter.ts +51 -5
- package/src/cli-adapters/provider-cli-parse.ts +3 -0
- package/src/cli-adapters/provider-cli-shared.ts +13 -1
- package/src/cli-adapters/terminal-backends/ghostty-vt-backend.ts +17 -1
- package/src/cli-adapters/terminal-backends/xterm-backend.ts +8 -1
- package/src/commands/chat-commands.ts +712 -381
- package/src/commands/router.ts +14 -2
- package/src/config/chat-history.ts +36 -13
- package/src/mesh/contracts.ts +329 -0
- package/src/providers/contracts.ts +19 -0
- package/src/providers/provider-loader.ts +21 -7
- package/src/providers/provider-schema.ts +10 -0
- package/src/providers/read-chat-contract.ts +74 -14
- package/src/providers/transcript-v2.ts +567 -0
- package/src/shared-types.ts +7 -0
- package/src/status/snapshot.ts +35 -11
- package/src/types.ts +5 -0
package/dist/index.js
CHANGED
|
@@ -4350,7 +4350,14 @@ var init_ghostty_vt_backend = __esm({
|
|
|
4350
4350
|
this.terminal.write(data);
|
|
4351
4351
|
}
|
|
4352
4352
|
getText() {
|
|
4353
|
-
|
|
4353
|
+
const raw = this.terminal.formatPlainText({ trim: false }) || "";
|
|
4354
|
+
if (!raw) return "";
|
|
4355
|
+
const lines = raw.split("\n").map((row) => row.replace(/\s+$/, ""));
|
|
4356
|
+
let first = 0;
|
|
4357
|
+
let last = lines.length;
|
|
4358
|
+
while (first < last && !lines[first]) first += 1;
|
|
4359
|
+
while (last > first && !lines[last - 1]) last -= 1;
|
|
4360
|
+
return lines.slice(first, last).join("\n");
|
|
4354
4361
|
}
|
|
4355
4362
|
getCursorPosition() {
|
|
4356
4363
|
return this.terminal.getCursorPosition();
|
|
@@ -4404,7 +4411,8 @@ var init_xterm_backend = __esm({
|
|
|
4404
4411
|
const lines = [];
|
|
4405
4412
|
for (let i = start; i < end; i++) {
|
|
4406
4413
|
const line = buffer.getLine(i);
|
|
4407
|
-
|
|
4414
|
+
const raw = line ? line.translateToString(false) : "";
|
|
4415
|
+
lines.push(raw.replace(/\s+$/, ""));
|
|
4408
4416
|
}
|
|
4409
4417
|
let first = 0;
|
|
4410
4418
|
let last = lines.length;
|
|
@@ -4936,8 +4944,13 @@ var init_provider_cli_shared = __esm({
|
|
|
4936
4944
|
this.ensureRow();
|
|
4937
4945
|
if (final === "A") this.row = Math.max(0, this.row - count);
|
|
4938
4946
|
else if (final === "B") this.row += count;
|
|
4939
|
-
else if (final === "C")
|
|
4940
|
-
|
|
4947
|
+
else if (final === "C") {
|
|
4948
|
+
const line = this.lines[this.row];
|
|
4949
|
+
for (let c = this.col; c < this.col + count; c += 1) {
|
|
4950
|
+
if (line[c] === void 0) line[c] = " ";
|
|
4951
|
+
}
|
|
4952
|
+
this.col += count;
|
|
4953
|
+
} else if (final === "D") this.col = Math.max(0, this.col - count);
|
|
4941
4954
|
else if (final === "G") this.col = Math.max(0, count - 1);
|
|
4942
4955
|
else if (final === "H" || final === "f") {
|
|
4943
4956
|
const parts = String(params || "").split(";");
|
|
@@ -5110,7 +5123,8 @@ function buildCliParseInput(options) {
|
|
|
5110
5123
|
partialResponse,
|
|
5111
5124
|
isWaitingForResponse,
|
|
5112
5125
|
scope,
|
|
5113
|
-
runtimeSettings
|
|
5126
|
+
runtimeSettings,
|
|
5127
|
+
spawnAt
|
|
5114
5128
|
} = options;
|
|
5115
5129
|
const buffer = scope ? sliceFromOffset(accumulatedBuffer, scope.bufferStart) : accumulatedBuffer;
|
|
5116
5130
|
const rawBuffer = scope ? sliceFromOffset(accumulatedRawBuffer, scope.rawBufferStart) : accumulatedRawBuffer;
|
|
@@ -5132,7 +5146,8 @@ function buildCliParseInput(options) {
|
|
|
5132
5146
|
partialResponse,
|
|
5133
5147
|
isWaitingForResponse,
|
|
5134
5148
|
promptText: scope?.prompt || "",
|
|
5135
|
-
settings: { ...runtimeSettings }
|
|
5149
|
+
settings: { ...runtimeSettings },
|
|
5150
|
+
...typeof spawnAt === "number" && spawnAt > 0 ? { spawnAt } : {}
|
|
5136
5151
|
};
|
|
5137
5152
|
}
|
|
5138
5153
|
function summarizeCliTraceText(text, max = 800) {
|
|
@@ -5148,7 +5163,7 @@ var init_provider_cli_parse = __esm({
|
|
|
5148
5163
|
});
|
|
5149
5164
|
|
|
5150
5165
|
// src/cli-adapters/cli-state-engine.ts
|
|
5151
|
-
var SCRIPT_STATUS_DEBOUNCE_MS, MAX_FINISH_RETRIES, FINISH_RETRY_DELAY_MS, MAX_TRACE_ENTRIES, APPROVAL_EXIT_TIMEOUT_MS, CliStateEngine;
|
|
5166
|
+
var SCRIPT_STATUS_DEBOUNCE_MS, MAX_FINISH_RETRIES, FINISH_RETRY_DELAY_MS, MAX_TRACE_ENTRIES, APPROVAL_EXIT_TIMEOUT_MS, IDLE_CONFIRMATION_GRACE_MS, CliStateEngine;
|
|
5152
5167
|
var init_cli_state_engine = __esm({
|
|
5153
5168
|
"src/cli-adapters/cli-state-engine.ts"() {
|
|
5154
5169
|
"use strict";
|
|
@@ -5160,6 +5175,7 @@ var init_cli_state_engine = __esm({
|
|
|
5160
5175
|
FINISH_RETRY_DELAY_MS = 300;
|
|
5161
5176
|
MAX_TRACE_ENTRIES = 250;
|
|
5162
5177
|
APPROVAL_EXIT_TIMEOUT_MS = 6e4;
|
|
5178
|
+
IDLE_CONFIRMATION_GRACE_MS = 2e3;
|
|
5163
5179
|
CliStateEngine = class {
|
|
5164
5180
|
constructor(provider, runner, transport, callbacks, timeouts) {
|
|
5165
5181
|
this.provider = provider;
|
|
@@ -5198,6 +5214,20 @@ var init_cli_state_engine = __esm({
|
|
|
5198
5214
|
pendingScriptStatusTimer = null;
|
|
5199
5215
|
// ── Idle candidate ───────────────────────────────
|
|
5200
5216
|
idleFinishCandidate = null;
|
|
5217
|
+
// ── Idle confirmation grace ──────────────────────
|
|
5218
|
+
/**
|
|
5219
|
+
* `finishResponse` produces the `generating → idle` transition that
|
|
5220
|
+
* coordinators interpret as "task complete". Some providers (antigravity-
|
|
5221
|
+
* cli observed in the wild) briefly paint a screen that looks like an
|
|
5222
|
+
* idle prompt between tool result frames while still actively running,
|
|
5223
|
+
* which fired `response_finished` and broke completion semantics.
|
|
5224
|
+
* We defer the actual idle transition by IDLE_CONFIRMATION_GRACE_MS and
|
|
5225
|
+
* cancel it if the scripted detection re-detects generating during that
|
|
5226
|
+
* window — a true completion stays idle for many seconds, so a 2-second
|
|
5227
|
+
* grace is sufficient to filter the paint blip.
|
|
5228
|
+
*/
|
|
5229
|
+
pendingIdleFinishTimer = null;
|
|
5230
|
+
pendingIdleFinishAt = 0;
|
|
5201
5231
|
// ── Status history (debug) ───────────────────────
|
|
5202
5232
|
statusHistory = [];
|
|
5203
5233
|
traceEntries = [];
|
|
@@ -5372,6 +5402,11 @@ var init_cli_state_engine = __esm({
|
|
|
5372
5402
|
clearTimeout(this.providerErrorRetryTimer);
|
|
5373
5403
|
this.providerErrorRetryTimer = null;
|
|
5374
5404
|
}
|
|
5405
|
+
if (this.pendingIdleFinishTimer) {
|
|
5406
|
+
clearTimeout(this.pendingIdleFinishTimer);
|
|
5407
|
+
this.pendingIdleFinishTimer = null;
|
|
5408
|
+
this.pendingIdleFinishAt = 0;
|
|
5409
|
+
}
|
|
5375
5410
|
this.providerErrorRetryKey = "";
|
|
5376
5411
|
}
|
|
5377
5412
|
resetActiveTurnState() {
|
|
@@ -5515,7 +5550,7 @@ var init_cli_state_engine = __esm({
|
|
|
5515
5550
|
"CLI",
|
|
5516
5551
|
`[${this.provider.type}] settled diagnostics prompt=${JSON.stringify(this.currentTurnScope?.prompt || "").slice(0, 140)} status=${String(status || "")} parsedStatus=${String(parsedStatus || "")} parsedMsgCount=${parsedMessages.length} lastParsedAssistant=${JSON.stringify((lastParsedAssistant?.content || "").slice(0, 120)).slice(0, 160)} responseBuffer=${JSON.stringify((snap.responseBuffer || "").slice(0, 160)).slice(0, 220)}`
|
|
5517
5552
|
);
|
|
5518
|
-
const shouldHoldGenerating = status === "idle" && this.isWaitingForResponse && !modal && recentInteractiveActivity && !(parsedStatus === "idle" && !!lastParsedAssistant);
|
|
5553
|
+
const shouldHoldGenerating = status === "idle" && this.isWaitingForResponse && !!this.currentTurnScope && !modal && recentInteractiveActivity && !(parsedStatus === "idle" && !!lastParsedAssistant);
|
|
5519
5554
|
if (shouldHoldGenerating) {
|
|
5520
5555
|
this.applyHoldGenerating(ctx);
|
|
5521
5556
|
return;
|
|
@@ -5611,19 +5646,30 @@ var init_cli_state_engine = __esm({
|
|
|
5611
5646
|
if (!inCooldown) {
|
|
5612
5647
|
if (!modal) {
|
|
5613
5648
|
LOG.warn("CLI", `[${this.provider.type}] detectStatus=waiting_approval but parseApproval returned null; ignoring`);
|
|
5649
|
+
if (this.currentStatus === "waiting_approval") {
|
|
5650
|
+
this.activeModal = null;
|
|
5651
|
+
this.setStatus("generating", "approval_lost_modal");
|
|
5652
|
+
this.callbacks.onStatusChange();
|
|
5653
|
+
}
|
|
5614
5654
|
return;
|
|
5615
5655
|
}
|
|
5616
5656
|
this.isWaitingForResponse = true;
|
|
5617
5657
|
this.setStatus("waiting_approval", "script_detect");
|
|
5618
|
-
this.activeModal
|
|
5658
|
+
const prev = this.activeModal;
|
|
5659
|
+
const prevBtnCount = Array.isArray(prev?.buttons) ? prev.buttons.length : 0;
|
|
5660
|
+
const nextBtnCount = Array.isArray(modal.buttons) ? modal.buttons.length : 0;
|
|
5661
|
+
if (!prev || prevBtnCount !== nextBtnCount) {
|
|
5662
|
+
this.activeModal = modal;
|
|
5663
|
+
this.callbacks.onStatusChange();
|
|
5664
|
+
}
|
|
5619
5665
|
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
5620
5666
|
this.armApprovalExitTimeout();
|
|
5621
|
-
this.callbacks.onStatusChange();
|
|
5622
5667
|
}
|
|
5623
5668
|
}
|
|
5624
5669
|
applyGenerating(ctx) {
|
|
5625
5670
|
const { modal, parsedMessages, lastParsedAssistant, parsedStatus, prevStatus } = ctx;
|
|
5626
5671
|
this.clearIdleFinishCandidate("generating");
|
|
5672
|
+
this.cancelPendingIdleFinish("generating_signal_returned");
|
|
5627
5673
|
const snap = this.transport.getSnapshot();
|
|
5628
5674
|
const effectiveScreenText = snap.screenText || snap.accumulatedBuffer;
|
|
5629
5675
|
const noActiveTurn = !this.currentTurnScope;
|
|
@@ -5784,10 +5830,27 @@ var init_cli_state_engine = __esm({
|
|
|
5784
5830
|
}
|
|
5785
5831
|
this.resetActiveTurnState();
|
|
5786
5832
|
this.callbacks.onTurnCompleted();
|
|
5787
|
-
this.
|
|
5788
|
-
this.callbacks.onStatusChange();
|
|
5833
|
+
this.scheduleIdleFinish("response_finished");
|
|
5789
5834
|
this.transport.flushOutboundQueue();
|
|
5790
5835
|
}
|
|
5836
|
+
scheduleIdleFinish(reason) {
|
|
5837
|
+
if (this.pendingIdleFinishTimer) clearTimeout(this.pendingIdleFinishTimer);
|
|
5838
|
+
this.pendingIdleFinishAt = Date.now() + IDLE_CONFIRMATION_GRACE_MS;
|
|
5839
|
+
this.pendingIdleFinishTimer = setTimeout(() => {
|
|
5840
|
+
this.pendingIdleFinishTimer = null;
|
|
5841
|
+
this.pendingIdleFinishAt = 0;
|
|
5842
|
+
if (this.isWaitingForResponse) return;
|
|
5843
|
+
this.setStatus("idle", reason);
|
|
5844
|
+
this.callbacks.onStatusChange();
|
|
5845
|
+
}, IDLE_CONFIRMATION_GRACE_MS);
|
|
5846
|
+
}
|
|
5847
|
+
cancelPendingIdleFinish(reason) {
|
|
5848
|
+
if (!this.pendingIdleFinishTimer) return;
|
|
5849
|
+
clearTimeout(this.pendingIdleFinishTimer);
|
|
5850
|
+
this.pendingIdleFinishTimer = null;
|
|
5851
|
+
this.pendingIdleFinishAt = 0;
|
|
5852
|
+
this.recordTrace("idle_finish_cancelled", { trigger: reason });
|
|
5853
|
+
}
|
|
5791
5854
|
// ─── Helpers ────────────────────────────────────────────────────────────
|
|
5792
5855
|
armApprovalExitTimeout() {
|
|
5793
5856
|
if (this.approvalExitTimeout) clearTimeout(this.approvalExitTimeout);
|
|
@@ -6224,9 +6287,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
6224
6287
|
submitRetryTimer = null;
|
|
6225
6288
|
// Resize redraw suppression
|
|
6226
6289
|
resizeSuppressUntil = 0;
|
|
6227
|
-
// Native transcript anchor
|
|
6228
|
-
//
|
|
6229
|
-
|
|
6290
|
+
// (A2.2) Native transcript anchor moved to CHAT_SOURCE_REGISTRY.
|
|
6291
|
+
// ChatSourceMachine holds the lock by state, not by a mutable field on
|
|
6292
|
+
// the adapter. Removed entirely; no callers remain after the readChat
|
|
6293
|
+
// ladder was replaced.
|
|
6230
6294
|
// ─── Script runner (parsing isolated here, adapter stays as transport) ───
|
|
6231
6295
|
runner;
|
|
6232
6296
|
/** @deprecated use runner.cliScripts for direct script access */
|
|
@@ -6562,6 +6626,8 @@ ${lastSnapshot}`;
|
|
|
6562
6626
|
this.engine.lastApprovalResolvedAt = Date.now();
|
|
6563
6627
|
}
|
|
6564
6628
|
this.engine.activeModal = null;
|
|
6629
|
+
this.engine.isWaitingForResponse = false;
|
|
6630
|
+
this.engine.currentTurnScope = null;
|
|
6565
6631
|
this.engine.setStatus("idle", `startup_ready:${trigger}`);
|
|
6566
6632
|
}
|
|
6567
6633
|
LOG.info(
|
|
@@ -6654,7 +6720,8 @@ ${lastSnapshot}`;
|
|
|
6654
6720
|
partialResponse: this.responseBuffer,
|
|
6655
6721
|
isWaitingForResponse: this.engine.isWaitingForResponse,
|
|
6656
6722
|
scope: this.engine.currentTurnScope,
|
|
6657
|
-
runtimeSettings: this.runtimeSettings
|
|
6723
|
+
runtimeSettings: this.runtimeSettings,
|
|
6724
|
+
spawnAt: this.spawnAt
|
|
6658
6725
|
});
|
|
6659
6726
|
const session = this.runner.parseSession({
|
|
6660
6727
|
...input,
|
|
@@ -6691,7 +6758,7 @@ ${lastSnapshot}`;
|
|
|
6691
6758
|
}
|
|
6692
6759
|
applyParsedSessionMetadata(parsed) {
|
|
6693
6760
|
const providerSessionId = typeof parsed?.providerSessionId === "string" && parsed.providerSessionId.trim() ? parsed.providerSessionId.trim() : "";
|
|
6694
|
-
if (providerSessionId) {
|
|
6761
|
+
if (providerSessionId && providerSessionId !== this.providerSessionId) {
|
|
6695
6762
|
this.providerSessionId = providerSessionId;
|
|
6696
6763
|
this.updateRuntimeMeta({ providerSessionId });
|
|
6697
6764
|
}
|
|
@@ -6709,7 +6776,25 @@ ${lastSnapshot}`;
|
|
|
6709
6776
|
const startupDetectedStatus = allowParse && this.startupParseGate && !startupModal ? this.runDetectStatus(this.recentOutputBuffer || this.terminalScreen.getText()) : null;
|
|
6710
6777
|
let effectiveStatus = this.projectEffectiveStatus(startupModal);
|
|
6711
6778
|
let effectiveModal = startupModal || this.engine.activeModal;
|
|
6712
|
-
if (
|
|
6779
|
+
if (allowParse && !effectiveModal && this.engine.isWaitingForResponse) {
|
|
6780
|
+
const liveDetect = this.runDetectStatus(this.recentOutputBuffer || this.terminalScreen.getText());
|
|
6781
|
+
if (liveDetect === "waiting_approval") {
|
|
6782
|
+
const liveModal = this.runParseApproval(this.terminalScreen.getText()) || this.runParseApproval(this.recentOutputBuffer);
|
|
6783
|
+
if (liveModal) {
|
|
6784
|
+
effectiveModal = liveModal;
|
|
6785
|
+
if (!this.engine.activeModal) this.engine.activeModal = liveModal;
|
|
6786
|
+
} else {
|
|
6787
|
+
LOG.warn("CLI", `[${this.cliType}] getStatus live re-extract: detect=waiting_approval but parseApproval still null (recentLen=${this.recentOutputBuffer.length} screenLen=${this.terminalScreen.getText().length})`);
|
|
6788
|
+
}
|
|
6789
|
+
} else if (liveDetect && liveDetect !== "generating" && liveDetect !== "idle") {
|
|
6790
|
+
LOG.warn("CLI", `[${this.cliType}] getStatus live re-extract: detect=${liveDetect} (not waiting_approval)`);
|
|
6791
|
+
} else if (this.engine.currentStatus === "waiting_approval" && liveDetect !== "waiting_approval") {
|
|
6792
|
+
LOG.warn("CLI", `[${this.cliType}] getStatus live re-extract: engine.status=waiting_approval but live detect=${liveDetect}`);
|
|
6793
|
+
}
|
|
6794
|
+
} else if (!effectiveModal && this.engine.currentStatus === "waiting_approval") {
|
|
6795
|
+
LOG.warn("CLI", `[${this.cliType}] getStatus skipped live re-extract: allowParse=${allowParse} isWaitingForResponse=${this.engine.isWaitingForResponse}`);
|
|
6796
|
+
}
|
|
6797
|
+
if (startupDetectedStatus === "waiting_approval" && effectiveModal) {
|
|
6713
6798
|
effectiveStatus = "waiting_approval";
|
|
6714
6799
|
} else if (startupDetectedStatus === "idle" && !startupModal && !effectiveModal) {
|
|
6715
6800
|
effectiveStatus = "idle";
|
|
@@ -6811,7 +6896,8 @@ ${lastSnapshot}`;
|
|
|
6811
6896
|
partialResponse: this.responseBuffer,
|
|
6812
6897
|
isWaitingForResponse: this.engine.isWaitingForResponse,
|
|
6813
6898
|
scope: this.engine.currentTurnScope,
|
|
6814
|
-
runtimeSettings: this.runtimeSettings
|
|
6899
|
+
runtimeSettings: this.runtimeSettings,
|
|
6900
|
+
spawnAt: this.spawnAt
|
|
6815
6901
|
});
|
|
6816
6902
|
return await Promise.resolve(this.runner.invokeByName(scriptName, {
|
|
6817
6903
|
...input,
|
|
@@ -14848,19 +14934,37 @@ function getProviderNativeHistoryScript(scripts, canonicalHistory, key) {
|
|
|
14848
14934
|
function normalizeProviderNativeHistoryRecords(agentType, historySessionId, records) {
|
|
14849
14935
|
if (!Array.isArray(records)) return [];
|
|
14850
14936
|
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
14851
|
-
return records.map((record) =>
|
|
14852
|
-
|
|
14853
|
-
|
|
14854
|
-
|
|
14855
|
-
|
|
14856
|
-
|
|
14857
|
-
|
|
14858
|
-
|
|
14859
|
-
|
|
14860
|
-
|
|
14861
|
-
|
|
14862
|
-
|
|
14863
|
-
|
|
14937
|
+
return records.map((record) => {
|
|
14938
|
+
const base = {
|
|
14939
|
+
ts: typeof record?.ts === "string" ? record.ts : new Date(Number(record?.receivedAt) || Date.now()).toISOString(),
|
|
14940
|
+
receivedAt: Number(record?.receivedAt) || Date.parse(record?.ts || "") || Date.now(),
|
|
14941
|
+
role: record?.role,
|
|
14942
|
+
content: String(record?.content || ""),
|
|
14943
|
+
kind: record?.kind || (record?.role === "system" ? "session_start" : "standard"),
|
|
14944
|
+
senderName: record?.senderName,
|
|
14945
|
+
agent: agentType,
|
|
14946
|
+
instanceId: record?.instanceId,
|
|
14947
|
+
historySessionId: normalizeSavedHistorySessionId(record?.historySessionId || normalizedSessionId),
|
|
14948
|
+
sessionTitle: record?.sessionTitle,
|
|
14949
|
+
workspace: record?.workspace
|
|
14950
|
+
};
|
|
14951
|
+
if (typeof record?.providerUnitKey === "string" && record.providerUnitKey) {
|
|
14952
|
+
base.providerUnitKey = record.providerUnitKey;
|
|
14953
|
+
}
|
|
14954
|
+
if (typeof record?.bubbleId === "string" && record.bubbleId) {
|
|
14955
|
+
base.bubbleId = record.bubbleId;
|
|
14956
|
+
}
|
|
14957
|
+
if (typeof record?.sequence === "number" && Number.isFinite(record.sequence)) {
|
|
14958
|
+
base.sequence = record.sequence;
|
|
14959
|
+
}
|
|
14960
|
+
if (typeof record?._turnKey === "string" && record._turnKey) {
|
|
14961
|
+
base._turnKey = record._turnKey;
|
|
14962
|
+
}
|
|
14963
|
+
if (typeof record?.bubbleState === "string" && record.bubbleState) {
|
|
14964
|
+
base.bubbleState = record.bubbleState;
|
|
14965
|
+
}
|
|
14966
|
+
return sanitizeHistoryMessage(agentType, base);
|
|
14967
|
+
}).filter(Boolean);
|
|
14864
14968
|
}
|
|
14865
14969
|
function callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, historySessionId, workspace, excludeInProgressTurn) {
|
|
14866
14970
|
const fn = getProviderNativeHistoryScript(scripts, canonicalHistory, "readSession");
|
|
@@ -15525,6 +15629,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
15525
15629
|
// src/providers/ide-provider-instance.ts
|
|
15526
15630
|
init_logger();
|
|
15527
15631
|
|
|
15632
|
+
// src/providers/transcript-v2.ts
|
|
15633
|
+
var CHAT_CONTRACT_VERSION_V1 = "1.0";
|
|
15634
|
+
|
|
15528
15635
|
// src/providers/read-chat-contract.ts
|
|
15529
15636
|
var VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "starting", "streaming", "long_generating"];
|
|
15530
15637
|
var VALID_ROLES = ["user", "assistant", "system", "human"];
|
|
@@ -15581,6 +15688,7 @@ function validateMessage(message, source, index) {
|
|
|
15581
15688
|
if (isFiniteNumber(message.index)) normalized.index = message.index;
|
|
15582
15689
|
if (isFiniteNumber(message.timestamp)) normalized.timestamp = message.timestamp;
|
|
15583
15690
|
if (isFiniteNumber(message.receivedAt)) normalized.receivedAt = message.receivedAt;
|
|
15691
|
+
if (isFiniteNumber(message.sequence)) normalized.sequence = message.sequence;
|
|
15584
15692
|
if (typeof message._turnKey === "string") normalized._turnKey = message._turnKey;
|
|
15585
15693
|
if (Array.isArray(message.toolCalls)) normalized.toolCalls = message.toolCalls;
|
|
15586
15694
|
if (isPlainObject3(message.meta)) normalized.meta = message.meta;
|
|
@@ -17512,12 +17620,365 @@ function buildSessionModalDeliverySignature(payload) {
|
|
|
17512
17620
|
]);
|
|
17513
17621
|
}
|
|
17514
17622
|
|
|
17623
|
+
// src/chat/source-machine.ts
|
|
17624
|
+
var INITIAL_CHAT_SOURCE_STATE = Object.freeze({
|
|
17625
|
+
name: "Booting",
|
|
17626
|
+
nativeSequencePeak: void 0,
|
|
17627
|
+
committedUnitKeys: Object.freeze(/* @__PURE__ */ new Set()),
|
|
17628
|
+
recoveringMisses: 0
|
|
17629
|
+
});
|
|
17630
|
+
var RECOVERING_MISS_PROMOTION_THRESHOLD = 3;
|
|
17631
|
+
function transitionChatSourceState(prev, observation, at, lockedSince) {
|
|
17632
|
+
const fromState = prev.name;
|
|
17633
|
+
if (observation.kind === "native_unavailable") {
|
|
17634
|
+
return handleNativeUnavailable(prev, observation.reason, at, lockedSince);
|
|
17635
|
+
}
|
|
17636
|
+
return handleNativePresent(prev, observation, at, lockedSince, fromState);
|
|
17637
|
+
}
|
|
17638
|
+
function handleNativeUnavailable(prev, reason, at, lockedSince) {
|
|
17639
|
+
const cause = reasonToUnavailableCause(reason);
|
|
17640
|
+
const fromState = prev.name;
|
|
17641
|
+
if (prev.name === "Booting") {
|
|
17642
|
+
const next2 = {
|
|
17643
|
+
name: "PtyOnly",
|
|
17644
|
+
nativeSequencePeak: void 0,
|
|
17645
|
+
committedUnitKeys: prev.committedUnitKeys,
|
|
17646
|
+
recoveringMisses: 0
|
|
17647
|
+
};
|
|
17648
|
+
return {
|
|
17649
|
+
next: next2,
|
|
17650
|
+
selected: "pty-parser",
|
|
17651
|
+
transition: { fromState, toState: "PtyOnly", event: "NativeUnavailable", cause, at },
|
|
17652
|
+
lockState: { locked: false }
|
|
17653
|
+
};
|
|
17654
|
+
}
|
|
17655
|
+
if (prev.name === "PtyOnly") {
|
|
17656
|
+
return {
|
|
17657
|
+
next: prev,
|
|
17658
|
+
selected: "pty-parser",
|
|
17659
|
+
transition: { fromState, toState: "PtyOnly", event: "NoOp", cause, at },
|
|
17660
|
+
lockState: { locked: false }
|
|
17661
|
+
};
|
|
17662
|
+
}
|
|
17663
|
+
if (prev.name === "NativeLocked") {
|
|
17664
|
+
const next2 = {
|
|
17665
|
+
name: "Recovering",
|
|
17666
|
+
nativeSequencePeak: prev.nativeSequencePeak,
|
|
17667
|
+
committedUnitKeys: prev.committedUnitKeys,
|
|
17668
|
+
recoveringMisses: 1
|
|
17669
|
+
};
|
|
17670
|
+
return {
|
|
17671
|
+
next: next2,
|
|
17672
|
+
selected: "pty-parser",
|
|
17673
|
+
transition: { fromState, toState: "Recovering", event: "NativeUnavailable", cause, at },
|
|
17674
|
+
lockState: { locked: false }
|
|
17675
|
+
};
|
|
17676
|
+
}
|
|
17677
|
+
const misses = prev.recoveringMisses + 1;
|
|
17678
|
+
if (misses >= RECOVERING_MISS_PROMOTION_THRESHOLD) {
|
|
17679
|
+
const next2 = {
|
|
17680
|
+
name: "PtyOnly",
|
|
17681
|
+
nativeSequencePeak: prev.nativeSequencePeak,
|
|
17682
|
+
committedUnitKeys: prev.committedUnitKeys,
|
|
17683
|
+
recoveringMisses: 0
|
|
17684
|
+
};
|
|
17685
|
+
return {
|
|
17686
|
+
next: next2,
|
|
17687
|
+
selected: "pty-parser",
|
|
17688
|
+
transition: { fromState, toState: "PtyOnly", event: "NativeUnavailable", cause, at },
|
|
17689
|
+
lockState: { locked: false }
|
|
17690
|
+
};
|
|
17691
|
+
}
|
|
17692
|
+
const next = {
|
|
17693
|
+
name: "Recovering",
|
|
17694
|
+
nativeSequencePeak: prev.nativeSequencePeak,
|
|
17695
|
+
committedUnitKeys: prev.committedUnitKeys,
|
|
17696
|
+
recoveringMisses: misses
|
|
17697
|
+
};
|
|
17698
|
+
return {
|
|
17699
|
+
next,
|
|
17700
|
+
selected: "pty-parser",
|
|
17701
|
+
transition: { fromState, toState: "Recovering", event: "NoOp", cause, at },
|
|
17702
|
+
lockState: { locked: false }
|
|
17703
|
+
};
|
|
17704
|
+
}
|
|
17705
|
+
function handleNativePresent(prev, observation, at, lockedSince, fromState) {
|
|
17706
|
+
if (!observation.safeMapping) {
|
|
17707
|
+
return regressTo(prev, fromState, "native_regressed_unsafe_mapping", at);
|
|
17708
|
+
}
|
|
17709
|
+
if (observation.coverage === "partial" && observation.messages.length === 0) {
|
|
17710
|
+
return regressTo(prev, fromState, "native_regressed_coverage_partial", at);
|
|
17711
|
+
}
|
|
17712
|
+
if (observation.messages.length === 0) {
|
|
17713
|
+
return handleNativeUnavailable(prev, "empty", at, lockedSince);
|
|
17714
|
+
}
|
|
17715
|
+
const incomingUnitKeys = collectUnitKeys(observation.messages);
|
|
17716
|
+
const incomingPeak = maxSequence(observation.messages);
|
|
17717
|
+
if (prev.name === "Booting") {
|
|
17718
|
+
if (observation.coverage === "partial") {
|
|
17719
|
+
const next2 = {
|
|
17720
|
+
name: "Recovering",
|
|
17721
|
+
nativeSequencePeak: incomingPeak,
|
|
17722
|
+
committedUnitKeys: incomingUnitKeys,
|
|
17723
|
+
recoveringMisses: 0
|
|
17724
|
+
};
|
|
17725
|
+
return {
|
|
17726
|
+
next: next2,
|
|
17727
|
+
selected: "pty-parser",
|
|
17728
|
+
transition: { fromState, toState: "Recovering", event: "NativeProgressed", cause: "native_progressed", at },
|
|
17729
|
+
lockState: { locked: false }
|
|
17730
|
+
};
|
|
17731
|
+
}
|
|
17732
|
+
const next = {
|
|
17733
|
+
name: "NativeLocked",
|
|
17734
|
+
nativeSequencePeak: incomingPeak,
|
|
17735
|
+
committedUnitKeys: incomingUnitKeys,
|
|
17736
|
+
recoveringMisses: 0
|
|
17737
|
+
};
|
|
17738
|
+
return {
|
|
17739
|
+
next,
|
|
17740
|
+
selected: "native-history",
|
|
17741
|
+
transition: { fromState, toState: "NativeLocked", event: "NativeProgressed", cause: "native_progressed", at },
|
|
17742
|
+
lockState: { locked: true, lockedSince: at }
|
|
17743
|
+
};
|
|
17744
|
+
}
|
|
17745
|
+
if (prev.name === "NativeLocked") {
|
|
17746
|
+
if (!isSupersetOf(incomingUnitKeys, prev.committedUnitKeys)) {
|
|
17747
|
+
return regressTo(prev, fromState, "native_regressed_shrunk", at);
|
|
17748
|
+
}
|
|
17749
|
+
if (prev.nativeSequencePeak !== void 0 && incomingPeak < prev.nativeSequencePeak) {
|
|
17750
|
+
return regressTo(prev, fromState, "native_regressed_shrunk", at);
|
|
17751
|
+
}
|
|
17752
|
+
const next = {
|
|
17753
|
+
name: "NativeLocked",
|
|
17754
|
+
nativeSequencePeak: Math.max(prev.nativeSequencePeak ?? incomingPeak, incomingPeak),
|
|
17755
|
+
committedUnitKeys: incomingUnitKeys,
|
|
17756
|
+
recoveringMisses: 0
|
|
17757
|
+
};
|
|
17758
|
+
return {
|
|
17759
|
+
next,
|
|
17760
|
+
selected: "native-history",
|
|
17761
|
+
transition: { fromState, toState: "NativeLocked", event: "NoOp", cause: "native_progressed", at },
|
|
17762
|
+
lockState: { locked: true, lockedSince: lockedSince ?? at }
|
|
17763
|
+
};
|
|
17764
|
+
}
|
|
17765
|
+
if (prev.name === "Recovering") {
|
|
17766
|
+
const meetsWatermark = prev.nativeSequencePeak === void 0 || incomingPeak >= prev.nativeSequencePeak;
|
|
17767
|
+
if (meetsWatermark && isSupersetOf(incomingUnitKeys, prev.committedUnitKeys) && observation.coverage !== "partial") {
|
|
17768
|
+
const next = {
|
|
17769
|
+
name: "NativeLocked",
|
|
17770
|
+
nativeSequencePeak: Math.max(prev.nativeSequencePeak ?? incomingPeak, incomingPeak),
|
|
17771
|
+
committedUnitKeys: incomingUnitKeys,
|
|
17772
|
+
recoveringMisses: 0
|
|
17773
|
+
};
|
|
17774
|
+
return {
|
|
17775
|
+
next,
|
|
17776
|
+
selected: "native-history",
|
|
17777
|
+
transition: { fromState, toState: "NativeLocked", event: "NativeProgressed", cause: "native_progressed", at },
|
|
17778
|
+
lockState: { locked: true, lockedSince: at }
|
|
17779
|
+
};
|
|
17780
|
+
}
|
|
17781
|
+
return handleNativeUnavailable(prev, "empty", at, lockedSince);
|
|
17782
|
+
}
|
|
17783
|
+
if (prev.nativeSequencePeak === void 0 || incomingPeak > prev.nativeSequencePeak) {
|
|
17784
|
+
if (observation.coverage !== "partial" && incomingUnitKeys.size > 0) {
|
|
17785
|
+
const next = {
|
|
17786
|
+
name: "NativeLocked",
|
|
17787
|
+
nativeSequencePeak: Math.max(prev.nativeSequencePeak ?? incomingPeak, incomingPeak),
|
|
17788
|
+
committedUnitKeys: incomingUnitKeys,
|
|
17789
|
+
recoveringMisses: 0
|
|
17790
|
+
};
|
|
17791
|
+
return {
|
|
17792
|
+
next,
|
|
17793
|
+
selected: "native-history",
|
|
17794
|
+
transition: { fromState, toState: "NativeLocked", event: "NativeProgressed", cause: "native_progressed", at },
|
|
17795
|
+
lockState: { locked: true, lockedSince: at }
|
|
17796
|
+
};
|
|
17797
|
+
}
|
|
17798
|
+
} else if (incomingPeak >= prev.nativeSequencePeak) {
|
|
17799
|
+
if (isSupersetOf(incomingUnitKeys, prev.committedUnitKeys) && observation.coverage !== "partial") {
|
|
17800
|
+
const next = {
|
|
17801
|
+
name: "NativeLocked",
|
|
17802
|
+
nativeSequencePeak: Math.max(prev.nativeSequencePeak ?? incomingPeak, incomingPeak),
|
|
17803
|
+
committedUnitKeys: incomingUnitKeys,
|
|
17804
|
+
recoveringMisses: 0
|
|
17805
|
+
};
|
|
17806
|
+
return {
|
|
17807
|
+
next,
|
|
17808
|
+
selected: "native-history",
|
|
17809
|
+
transition: { fromState, toState: "NativeLocked", event: "NativeProgressed", cause: "native_progressed", at },
|
|
17810
|
+
lockState: { locked: true, lockedSince: at }
|
|
17811
|
+
};
|
|
17812
|
+
}
|
|
17813
|
+
}
|
|
17814
|
+
return {
|
|
17815
|
+
next: prev,
|
|
17816
|
+
selected: "pty-parser",
|
|
17817
|
+
transition: { fromState, toState: "PtyOnly", event: "NoOp", cause: "native_progressed", at },
|
|
17818
|
+
lockState: { locked: false }
|
|
17819
|
+
};
|
|
17820
|
+
}
|
|
17821
|
+
function regressTo(prev, fromState, cause, at) {
|
|
17822
|
+
const next = {
|
|
17823
|
+
name: "PtyOnly",
|
|
17824
|
+
nativeSequencePeak: prev.nativeSequencePeak,
|
|
17825
|
+
committedUnitKeys: prev.committedUnitKeys,
|
|
17826
|
+
recoveringMisses: 0
|
|
17827
|
+
};
|
|
17828
|
+
return {
|
|
17829
|
+
next,
|
|
17830
|
+
selected: "pty-parser",
|
|
17831
|
+
transition: { fromState, toState: "PtyOnly", event: "NativeRegressed", cause, at },
|
|
17832
|
+
lockState: { locked: false }
|
|
17833
|
+
};
|
|
17834
|
+
}
|
|
17835
|
+
function reasonToUnavailableCause(reason) {
|
|
17836
|
+
switch (reason) {
|
|
17837
|
+
case "provider_not_supported":
|
|
17838
|
+
return "native_unavailable_provider_unsupported";
|
|
17839
|
+
case "read_error":
|
|
17840
|
+
return "native_unavailable_read_error";
|
|
17841
|
+
case "empty":
|
|
17842
|
+
return "native_unavailable_empty";
|
|
17843
|
+
case "not_native_source":
|
|
17844
|
+
return "native_unavailable_not_native_source";
|
|
17845
|
+
case "coverage_unavailable":
|
|
17846
|
+
return "native_regressed_coverage_unavailable";
|
|
17847
|
+
}
|
|
17848
|
+
}
|
|
17849
|
+
function collectUnitKeys(messages) {
|
|
17850
|
+
const set = /* @__PURE__ */ new Set();
|
|
17851
|
+
for (const m of messages) set.add(m.providerUnitKey);
|
|
17852
|
+
return set;
|
|
17853
|
+
}
|
|
17854
|
+
function maxSequence(messages) {
|
|
17855
|
+
let max = -Infinity;
|
|
17856
|
+
for (const m of messages) {
|
|
17857
|
+
if (m.sequence > max) max = m.sequence;
|
|
17858
|
+
}
|
|
17859
|
+
return max === -Infinity ? 0 : max;
|
|
17860
|
+
}
|
|
17861
|
+
function isSupersetOf(candidate, required) {
|
|
17862
|
+
if (required.size === 0) return true;
|
|
17863
|
+
for (const key of required) {
|
|
17864
|
+
if (!candidate.has(key)) return false;
|
|
17865
|
+
}
|
|
17866
|
+
return true;
|
|
17867
|
+
}
|
|
17868
|
+
|
|
17869
|
+
// src/chat/source-resolver.ts
|
|
17870
|
+
var TRANSITION_HISTORY_LIMIT = 25;
|
|
17871
|
+
function chatSourceSessionKey(providerType, sessionId) {
|
|
17872
|
+
return `${providerType}\0${sessionId}`;
|
|
17873
|
+
}
|
|
17874
|
+
var ChatSourceRegistry = class {
|
|
17875
|
+
records = /* @__PURE__ */ new Map();
|
|
17876
|
+
/** Snapshot of current state for diagnostics. Does not mutate. */
|
|
17877
|
+
getState(key) {
|
|
17878
|
+
return this.records.get(key)?.state ?? INITIAL_CHAT_SOURCE_STATE;
|
|
17879
|
+
}
|
|
17880
|
+
/** Recent transitions, newest last. Empty array when nothing has happened. */
|
|
17881
|
+
getTransitions(key) {
|
|
17882
|
+
return this.records.get(key)?.transitions ?? [];
|
|
17883
|
+
}
|
|
17884
|
+
/** Drop a session. Caller should invoke this when the session is destroyed
|
|
17885
|
+
* to avoid unbounded growth across long-lived daemons. */
|
|
17886
|
+
clear(key) {
|
|
17887
|
+
this.records.delete(key);
|
|
17888
|
+
}
|
|
17889
|
+
/** Drop all sessions. Test helper. */
|
|
17890
|
+
clearAll() {
|
|
17891
|
+
this.records.clear();
|
|
17892
|
+
}
|
|
17893
|
+
/**
|
|
17894
|
+
* Apply one observation, returning the decision and side-effecting the
|
|
17895
|
+
* stored state. The returned `nextState` is the same object now stored
|
|
17896
|
+
* under `key`; callers may treat the decision as authoritative without
|
|
17897
|
+
* re-reading.
|
|
17898
|
+
*/
|
|
17899
|
+
observe(key, observation, at = Date.now()) {
|
|
17900
|
+
const prev = this.records.get(key);
|
|
17901
|
+
const prevState = prev?.state ?? INITIAL_CHAT_SOURCE_STATE;
|
|
17902
|
+
const prevLockedSince = prev?.lockedSince;
|
|
17903
|
+
const result = transitionChatSourceState(prevState, observation, at, prevLockedSince);
|
|
17904
|
+
const transitions = prev?.transitions ?? [];
|
|
17905
|
+
const nextTransitions = appendTransition(transitions, result.transition);
|
|
17906
|
+
const lockedSince = result.lockState.lockedSince;
|
|
17907
|
+
this.records.set(key, {
|
|
17908
|
+
state: result.next,
|
|
17909
|
+
lockedSince,
|
|
17910
|
+
transitions: nextTransitions
|
|
17911
|
+
});
|
|
17912
|
+
return {
|
|
17913
|
+
selected: result.selected,
|
|
17914
|
+
nextState: result.next,
|
|
17915
|
+
transition: result.transition,
|
|
17916
|
+
lockState: result.lockState
|
|
17917
|
+
};
|
|
17918
|
+
}
|
|
17919
|
+
};
|
|
17920
|
+
function appendTransition(existing, next) {
|
|
17921
|
+
const last = existing[existing.length - 1];
|
|
17922
|
+
if (last && last.fromState === next.fromState && last.toState === next.toState && last.event === next.event && last.cause === next.cause) {
|
|
17923
|
+
return existing;
|
|
17924
|
+
}
|
|
17925
|
+
const trimmed = existing.length >= TRANSITION_HISTORY_LIMIT ? existing.slice(existing.length - TRANSITION_HISTORY_LIMIT + 1) : [...existing];
|
|
17926
|
+
trimmed.push(next);
|
|
17927
|
+
return trimmed;
|
|
17928
|
+
}
|
|
17929
|
+
function buildV1NativePresentObservation(args) {
|
|
17930
|
+
const identities = [];
|
|
17931
|
+
let synthesisedSequence = 0;
|
|
17932
|
+
for (const message of args.messages) {
|
|
17933
|
+
const providerUnitKey = pickFirstString(
|
|
17934
|
+
message.providerUnitKey,
|
|
17935
|
+
message.bubbleId,
|
|
17936
|
+
message.id
|
|
17937
|
+
) ?? synthesiseV1UnitKey(args.providerType, args.sessionId, synthesisedSequence, message);
|
|
17938
|
+
const sequence = pickFiniteNumber(message.receivedAt, message.timestamp, message.index) ?? synthesisedSequence;
|
|
17939
|
+
identities.push({ providerUnitKey, sequence });
|
|
17940
|
+
synthesisedSequence += 1;
|
|
17941
|
+
}
|
|
17942
|
+
return {
|
|
17943
|
+
kind: "native_present",
|
|
17944
|
+
contractVersion: CHAT_CONTRACT_VERSION_V1,
|
|
17945
|
+
messages: identities,
|
|
17946
|
+
coverage: args.coverage,
|
|
17947
|
+
safeMapping: args.safeMapping
|
|
17948
|
+
};
|
|
17949
|
+
}
|
|
17950
|
+
function pickFirstString(...candidates) {
|
|
17951
|
+
for (const c of candidates) {
|
|
17952
|
+
if (typeof c === "string" && c.length > 0) return c;
|
|
17953
|
+
}
|
|
17954
|
+
return void 0;
|
|
17955
|
+
}
|
|
17956
|
+
function pickFiniteNumber(...candidates) {
|
|
17957
|
+
for (const c of candidates) {
|
|
17958
|
+
if (typeof c === "number" && Number.isFinite(c)) return c;
|
|
17959
|
+
}
|
|
17960
|
+
return void 0;
|
|
17961
|
+
}
|
|
17962
|
+
function synthesiseV1UnitKey(providerType, sessionId, positionalSeq, message) {
|
|
17963
|
+
const role = typeof message.role === "string" ? message.role : "";
|
|
17964
|
+
const ts2 = pickFiniteNumber(message.receivedAt, message.timestamp);
|
|
17965
|
+
return `v1:${providerType}:${sessionId}:${ts2 ?? ""}:${positionalSeq}:${role}`;
|
|
17966
|
+
}
|
|
17967
|
+
var CHAT_SOURCE_REGISTRY = new ChatSourceRegistry();
|
|
17968
|
+
|
|
17515
17969
|
// src/commands/chat-commands.ts
|
|
17516
17970
|
var RECENT_SEND_WINDOW_MS = 1200;
|
|
17517
17971
|
var READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS = 25e3;
|
|
17518
17972
|
var HERMES_CLI_STARTING_SEND_SETTLE_MS = 2e3;
|
|
17519
|
-
var CLI_NATIVE_HISTORY_FRESH_MS = 5 * 6e4;
|
|
17520
17973
|
var CLI_NATIVE_TRANSCRIPT_PROVIDERS = /* @__PURE__ */ new Set(["codex-cli", "claude-cli", "hermes-cli", "antigravity-cli"]);
|
|
17974
|
+
var warnedLegacyNativeAllowlistHits = /* @__PURE__ */ new Set();
|
|
17975
|
+
function warnLegacyNativeAllowlistHit(providerType) {
|
|
17976
|
+
if (warnedLegacyNativeAllowlistHits.has(providerType)) return;
|
|
17977
|
+
warnedLegacyNativeAllowlistHits.add(providerType);
|
|
17978
|
+
console.warn(
|
|
17979
|
+
`[chat-commands] supportsCliNativeTranscript fell back to the hardcoded CLI_NATIVE_TRANSCRIPT_PROVIDERS set for "${providerType}". The provider module was unavailable or did not declare canonicalHistory. Set canonicalHistory.contractVersion in the provider.json to remove this dependency.`
|
|
17980
|
+
);
|
|
17981
|
+
}
|
|
17521
17982
|
var recentSendByTarget = /* @__PURE__ */ new Map();
|
|
17522
17983
|
function getCurrentProviderType(h, fallback = "") {
|
|
17523
17984
|
return h.currentSession?.providerType || h.currentProviderType || fallback;
|
|
@@ -17692,7 +18153,11 @@ function readHistorySessionIdFromMessages(messages) {
|
|
|
17692
18153
|
function shouldPreserveNativeIdentity(providerType, sessionId, message) {
|
|
17693
18154
|
const providerUnitKey = typeof message.providerUnitKey === "string" ? message.providerUnitKey.trim() : "";
|
|
17694
18155
|
const turnKey = typeof message._turnKey === "string" ? message._turnKey.trim() : "";
|
|
17695
|
-
if (!providerUnitKey
|
|
18156
|
+
if (!providerUnitKey) return false;
|
|
18157
|
+
if (providerUnitKey.startsWith("v2:") || providerUnitKey.startsWith("v2-pty:")) {
|
|
18158
|
+
return true;
|
|
18159
|
+
}
|
|
18160
|
+
if (!turnKey) return false;
|
|
17696
18161
|
if (providerType === "hermes-cli" && sessionId) {
|
|
17697
18162
|
return providerUnitKey.startsWith(`${providerType}:native:${sessionId}:`) && turnKey.startsWith(`${providerType}:native-turn:${sessionId}:`);
|
|
17698
18163
|
}
|
|
@@ -17721,12 +18186,16 @@ function normalizeNativeHistoryMessages(providerType, messages, nativeSessionId)
|
|
|
17721
18186
|
const meta = message.meta && typeof message.meta === "object" ? message.meta : void 0;
|
|
17722
18187
|
const isSystemSessionStart = role === "system" || kind === "system" || kind === "session_start";
|
|
17723
18188
|
const isActivity = role === "assistant" && (kind === "tool" || kind === "terminal" || kind === "thought");
|
|
18189
|
+
const existingSequence = typeof message.sequence === "number" && Number.isFinite(message.sequence) ? message.sequence : null;
|
|
18190
|
+
const tsCandidate = Number(message.receivedAt || message.timestamp || 0);
|
|
18191
|
+
const sequence = existingSequence !== null ? existingSequence : tsCandidate > 0 ? tsCandidate : index;
|
|
17724
18192
|
return {
|
|
17725
18193
|
...message,
|
|
17726
18194
|
role: role === "human" ? "user" : role || "assistant",
|
|
17727
18195
|
kind: isSystemSessionStart ? "system" : kind,
|
|
17728
18196
|
providerUnitKey,
|
|
17729
18197
|
bubbleId: typeof message.bubbleId === "string" && message.bubbleId.trim() && preserveNativeIdentity ? message.bubbleId.trim() : `bubble:${providerUnitKey}`,
|
|
18198
|
+
sequence,
|
|
17730
18199
|
_turnKey: preserveNativeIdentity ? existingTurnKey : `${providerType}:native-turn:${nativeIdentitySessionId || "workspace"}:${turnIndex}`,
|
|
17731
18200
|
bubbleState: message.bubbleState || "final",
|
|
17732
18201
|
...isSystemSessionStart ? {
|
|
@@ -17785,17 +18254,185 @@ function buildCliMessageSourceProvenance(args) {
|
|
|
17785
18254
|
}
|
|
17786
18255
|
};
|
|
17787
18256
|
}
|
|
17788
|
-
function
|
|
17789
|
-
if (
|
|
17790
|
-
|
|
17791
|
-
|
|
17792
|
-
|
|
17793
|
-
|
|
17794
|
-
|
|
17795
|
-
|
|
17796
|
-
|
|
17797
|
-
|
|
17798
|
-
|
|
18257
|
+
function causeToLegacyFallbackReason(cause, selected, extraDetail) {
|
|
18258
|
+
if (selected === "native-history") return void 0;
|
|
18259
|
+
switch (cause) {
|
|
18260
|
+
case "initial":
|
|
18261
|
+
return "native_history_not_checked";
|
|
18262
|
+
case "native_progressed":
|
|
18263
|
+
return "native_history_not_selected";
|
|
18264
|
+
case "native_regressed_shrunk":
|
|
18265
|
+
return "native_history_empty";
|
|
18266
|
+
case "native_regressed_unsafe_mapping":
|
|
18267
|
+
return "native_history_not_safely_mapped";
|
|
18268
|
+
case "native_regressed_coverage_partial":
|
|
18269
|
+
return "native_history_partial";
|
|
18270
|
+
case "native_regressed_coverage_unavailable":
|
|
18271
|
+
return "native_history_unavailable";
|
|
18272
|
+
case "native_unavailable_read_error":
|
|
18273
|
+
return extraDetail?.unavailableReason ? `native_history_unavailable:${extraDetail.unavailableReason}` : "native_history_unavailable";
|
|
18274
|
+
case "native_unavailable_provider_unsupported":
|
|
18275
|
+
return "provider_native_transcript_not_supported";
|
|
18276
|
+
case "native_unavailable_empty":
|
|
18277
|
+
return "native_history_empty";
|
|
18278
|
+
case "native_unavailable_not_native_source":
|
|
18279
|
+
return extraDetail?.nativeSource ? `native_history_source_${extraDetail.nativeSource}` : "native_history_unavailable";
|
|
18280
|
+
}
|
|
18281
|
+
}
|
|
18282
|
+
function decideCliReadChatSource(args) {
|
|
18283
|
+
const supportsNative = supportsCliNativeTranscript(args.providerType, args.provider);
|
|
18284
|
+
const observation = buildObservationForCli(args, supportsNative);
|
|
18285
|
+
const sessionKey = chatSourceSessionKey(args.providerType, args.sessionId);
|
|
18286
|
+
const decision = CHAT_SOURCE_REGISTRY.observe(sessionKey, observation);
|
|
18287
|
+
const nativeMessages = observation.kind === "native_present" ? extractNativeMessagesFromResult(args.providerType, args.nativeHistoryResult) : [];
|
|
18288
|
+
const nativeSource = typeof args.nativeHistoryResult?.source === "string" ? args.nativeHistoryResult.source : void 0;
|
|
18289
|
+
const sourcePath = typeof args.nativeHistoryResult?.sourcePath === "string" ? args.nativeHistoryResult.sourcePath : void 0;
|
|
18290
|
+
const sourceMtimeMs = typeof args.nativeHistoryResult?.sourceMtimeMs === "number" ? args.nativeHistoryResult.sourceMtimeMs : void 0;
|
|
18291
|
+
const coverageHint = typeof args.nativeHistoryResult?.nativeHistoryCoverage === "string" ? args.nativeHistoryResult.nativeHistoryCoverage : void 0;
|
|
18292
|
+
const partialReason = typeof args.nativeHistoryResult?.partialReason === "string" ? args.nativeHistoryResult.partialReason : void 0;
|
|
18293
|
+
const unavailableReason = typeof args.nativeHistoryResult?.unavailableReason === "string" ? args.nativeHistoryResult.unavailableReason : args.nativeHistoryError ? `error:${args.nativeHistoryError?.message || String(args.nativeHistoryError)}` : void 0;
|
|
18294
|
+
const nativeHandle = typeof args.nativeHistoryResult?.providerSessionId === "string" ? args.nativeHistoryResult.providerSessionId : void 0;
|
|
18295
|
+
const transcriptWorkspace = typeof args.nativeHistoryResult?.workspace === "string" ? args.nativeHistoryResult.workspace : nativeMessages.map((m) => typeof m?.workspace === "string" ? m.workspace.trim() : "").find(Boolean);
|
|
18296
|
+
const fallbackReason = causeToLegacyFallbackReason(decision.transition.cause, decision.selected, {
|
|
18297
|
+
unavailableReason,
|
|
18298
|
+
nativeSource: nativeSource && nativeSource !== "provider-native" ? nativeSource : void 0
|
|
18299
|
+
});
|
|
18300
|
+
const ptyStatusApprovalOnly = decision.selected === "native-history" ? true : args.ptyStatusApprovalOnly;
|
|
18301
|
+
const messageSource = buildCliMessageSourceProvenance({
|
|
18302
|
+
selected: decision.selected,
|
|
18303
|
+
provider: args.providerType,
|
|
18304
|
+
nativeHandle,
|
|
18305
|
+
sessionWorkspace: args.sessionWorkspace,
|
|
18306
|
+
intendedWorkspace: args.intendedWorkspace,
|
|
18307
|
+
transcriptWorkspace,
|
|
18308
|
+
fallbackReason,
|
|
18309
|
+
nativeSource,
|
|
18310
|
+
sourcePath,
|
|
18311
|
+
sourceMtimeMs,
|
|
18312
|
+
nativeHistoryCoverage: coverageHint,
|
|
18313
|
+
partialReason,
|
|
18314
|
+
unavailableReason,
|
|
18315
|
+
nativeMessages,
|
|
18316
|
+
ptyMessages: args.ptyMessages,
|
|
18317
|
+
returnedMessages: decision.selected === "native-history" ? nativeMessages : args.ptyMessages,
|
|
18318
|
+
safeMapping: args.safeMapping,
|
|
18319
|
+
// freshEnough is a v1 concept the machine does not model directly.
|
|
18320
|
+
// We surface lockState.locked here so v1 consumers reading
|
|
18321
|
+
// staleness.freshEnough still get a meaningful boolean.
|
|
18322
|
+
freshEnough: decision.lockState.locked,
|
|
18323
|
+
ptyStatusApprovalOnly
|
|
18324
|
+
});
|
|
18325
|
+
return {
|
|
18326
|
+
decision,
|
|
18327
|
+
messageSource,
|
|
18328
|
+
nativeMessages,
|
|
18329
|
+
nativeSelected: decision.selected === "native-history"
|
|
18330
|
+
};
|
|
18331
|
+
}
|
|
18332
|
+
function buildObservationForCli(args, supportsNative) {
|
|
18333
|
+
if (!supportsNative) {
|
|
18334
|
+
return { kind: "native_unavailable", reason: "provider_not_supported" };
|
|
18335
|
+
}
|
|
18336
|
+
if (args.nativeHistoryError) {
|
|
18337
|
+
return { kind: "native_unavailable", reason: "read_error" };
|
|
18338
|
+
}
|
|
18339
|
+
const result = args.nativeHistoryResult;
|
|
18340
|
+
if (!result || typeof result !== "object") {
|
|
18341
|
+
return { kind: "native_unavailable", reason: "read_error" };
|
|
18342
|
+
}
|
|
18343
|
+
const source = typeof result.source === "string" ? result.source : "";
|
|
18344
|
+
if (source && source !== "provider-native") {
|
|
18345
|
+
return { kind: "native_unavailable", reason: source === "native-unavailable" ? "empty" : "not_native_source" };
|
|
18346
|
+
}
|
|
18347
|
+
const messages = Array.isArray(result.messages) ? result.messages : [];
|
|
18348
|
+
if (messages.length === 0) {
|
|
18349
|
+
return { kind: "native_unavailable", reason: "empty" };
|
|
18350
|
+
}
|
|
18351
|
+
const coverage = typeof result.nativeHistoryCoverage === "string" ? result.nativeHistoryCoverage : "tail";
|
|
18352
|
+
if (coverage === "unavailable") {
|
|
18353
|
+
return { kind: "native_unavailable", reason: "coverage_unavailable" };
|
|
18354
|
+
}
|
|
18355
|
+
return buildV1NativePresentObservation({
|
|
18356
|
+
providerType: args.providerType,
|
|
18357
|
+
sessionId: args.sessionId,
|
|
18358
|
+
messages,
|
|
18359
|
+
coverage: coverage === "full" || coverage === "tail" || coverage === "current-turn" || coverage === "partial" ? coverage : "tail",
|
|
18360
|
+
safeMapping: args.safeMapping
|
|
18361
|
+
});
|
|
18362
|
+
}
|
|
18363
|
+
function extractNativeMessagesFromResult(providerType, result) {
|
|
18364
|
+
if (!result || !Array.isArray(result.messages)) return [];
|
|
18365
|
+
return normalizeNativeHistoryMessages(
|
|
18366
|
+
providerType,
|
|
18367
|
+
result.messages,
|
|
18368
|
+
typeof result.providerSessionId === "string" ? result.providerSessionId : void 0
|
|
18369
|
+
);
|
|
18370
|
+
}
|
|
18371
|
+
function applyUnsafeNativeDaemonFallback(args) {
|
|
18372
|
+
if (args.adapter.cliType !== "codex-cli") {
|
|
18373
|
+
return;
|
|
18374
|
+
}
|
|
18375
|
+
const ms = args.messageSourceRef.get();
|
|
18376
|
+
const fallbackReason = typeof ms.fallbackReason === "string" ? ms.fallbackReason : "";
|
|
18377
|
+
if (!isUnsafeNativeTranscriptFallback(fallbackReason)) {
|
|
18378
|
+
return;
|
|
18379
|
+
}
|
|
18380
|
+
const safeCurrentRuntimePtyMessages = isCurrentRuntimePtySafelyAttributed({
|
|
18381
|
+
adapter: args.adapter,
|
|
18382
|
+
helpers: args.helpers,
|
|
18383
|
+
readChatArgs: args.readChatArgs,
|
|
18384
|
+
sessionWorkspace: args.sessionWorkspace,
|
|
18385
|
+
intendedWorkspace: args.intendedWorkspace,
|
|
18386
|
+
ptyMessages: args.ptyMessages
|
|
18387
|
+
});
|
|
18388
|
+
if (safeCurrentRuntimePtyMessages) {
|
|
18389
|
+
args.apply({
|
|
18390
|
+
messages: args.ptyMessages,
|
|
18391
|
+
transcriptAuthority: "daemon",
|
|
18392
|
+
coverage: args.coverage || "current-turn",
|
|
18393
|
+
status: args.returnedStatus
|
|
18394
|
+
});
|
|
18395
|
+
const next2 = { ...ms, selectedDaemonSource: "current-runtime-pty", transcriptAuthority: "daemon", runtimeMappingSafe: true };
|
|
18396
|
+
args.messageSourceRef.set(next2);
|
|
18397
|
+
return;
|
|
18398
|
+
}
|
|
18399
|
+
const safeRuntimeAckMessages = selectRuntimeInputAckMessages(args.ptyMessages);
|
|
18400
|
+
if (safeRuntimeAckMessages.length > 0) {
|
|
18401
|
+
args.apply({
|
|
18402
|
+
messages: safeRuntimeAckMessages,
|
|
18403
|
+
transcriptAuthority: "daemon",
|
|
18404
|
+
coverage: "tail",
|
|
18405
|
+
status: coerceUnsafeNativeFallbackStatus(args.returnedStatus, args.activeModal)
|
|
18406
|
+
});
|
|
18407
|
+
const next2 = { ...ms, ptyStatusApprovalOnly: true };
|
|
18408
|
+
args.messageSourceRef.set(next2);
|
|
18409
|
+
return;
|
|
18410
|
+
}
|
|
18411
|
+
const exactRuntimeMirrorMessages = readExactRuntimeMirrorMessages({
|
|
18412
|
+
providerType: args.providerType,
|
|
18413
|
+
targetSessionId: typeof args.readChatArgs?.targetSessionId === "string" ? args.readChatArgs.targetSessionId : void 0,
|
|
18414
|
+
currentSessionId: typeof args.helpers.currentSession?.sessionId === "string" ? args.helpers.currentSession.sessionId : void 0,
|
|
18415
|
+
tailLimit: args.nativeHistoryLimit,
|
|
18416
|
+
historyBehavior: args.provider?.historyBehavior
|
|
18417
|
+
});
|
|
18418
|
+
if (exactRuntimeMirrorMessages.length > 0) {
|
|
18419
|
+
args.apply({
|
|
18420
|
+
messages: exactRuntimeMirrorMessages,
|
|
18421
|
+
transcriptAuthority: "daemon",
|
|
18422
|
+
coverage: "tail",
|
|
18423
|
+
status: coerceUnsafeNativeFallbackStatus(args.returnedStatus, args.activeModal)
|
|
18424
|
+
});
|
|
18425
|
+
const next2 = { ...ms, selectedDaemonSource: "exact-runtime-mirror", transcriptAuthority: "daemon", ptyStatusApprovalOnly: true };
|
|
18426
|
+
args.messageSourceRef.set(next2);
|
|
18427
|
+
return;
|
|
18428
|
+
}
|
|
18429
|
+
args.apply({
|
|
18430
|
+
messages: args.ptyMessages,
|
|
18431
|
+
coverage: args.coverage,
|
|
18432
|
+
status: coerceUnsafeNativeFallbackStatus(args.returnedStatus, args.activeModal)
|
|
18433
|
+
});
|
|
18434
|
+
const next = { ...ms, ptyStatusApprovalOnly: true };
|
|
18435
|
+
args.messageSourceRef.set(next);
|
|
17799
18436
|
}
|
|
17800
18437
|
function isUnsafeNativeTranscriptFallback(reason) {
|
|
17801
18438
|
const value = String(reason || "").trim();
|
|
@@ -17867,8 +18504,14 @@ function isCurrentRuntimePtySafelyAttributed(args) {
|
|
|
17867
18504
|
return true;
|
|
17868
18505
|
}
|
|
17869
18506
|
function supportsCliNativeTranscript(providerType, provider) {
|
|
17870
|
-
if (
|
|
17871
|
-
|
|
18507
|
+
if (provider?.category === "cli" && isNativeSourceCanonicalHistory(provider?.canonicalHistory)) {
|
|
18508
|
+
return true;
|
|
18509
|
+
}
|
|
18510
|
+
if (CLI_NATIVE_TRANSCRIPT_PROVIDERS.has(providerType)) {
|
|
18511
|
+
warnLegacyNativeAllowlistHit(providerType);
|
|
18512
|
+
return true;
|
|
18513
|
+
}
|
|
18514
|
+
return false;
|
|
17872
18515
|
}
|
|
17873
18516
|
function getComparableVisibleText(message) {
|
|
17874
18517
|
if (!message) return "";
|
|
@@ -17967,14 +18610,6 @@ function readLiveCodexWorkspaceNativeHistory(agentStr, args) {
|
|
|
17967
18610
|
});
|
|
17968
18611
|
return { ...history, lookup: "workspace" };
|
|
17969
18612
|
}
|
|
17970
|
-
function isNativeHistoryFreshEnough(args) {
|
|
17971
|
-
const nativeNewest = getMessageNewestReceivedAt(args.nativeMessages);
|
|
17972
|
-
const ptyNewest = getMessageNewestReceivedAt(args.ptyMessages);
|
|
17973
|
-
if (nativeNewest > 0 && nativeNewest >= ptyNewest) return true;
|
|
17974
|
-
const sourceMtimeMs = Number(args.sourceMtimeMs || 0);
|
|
17975
|
-
if (sourceMtimeMs > 0 && Date.now() - sourceMtimeMs <= CLI_NATIVE_HISTORY_FRESH_MS) return true;
|
|
17976
|
-
return ptyNewest === 0 && nativeNewest > 0;
|
|
17977
|
-
}
|
|
17978
18613
|
function shouldPreserveReadChatPayloadField(key) {
|
|
17979
18614
|
return key === "messageSource" || key === "transcriptProvenance";
|
|
17980
18615
|
}
|
|
@@ -18039,6 +18674,8 @@ function normalizeReadChatCommandStatus(status, activeModal) {
|
|
|
18039
18674
|
case "disconnected":
|
|
18040
18675
|
case "not_monitored":
|
|
18041
18676
|
return "error";
|
|
18677
|
+
case "waiting_approval":
|
|
18678
|
+
return hasNonEmptyModalButtons(activeModal) ? "waiting_approval" : "generating";
|
|
18042
18679
|
default:
|
|
18043
18680
|
return raw;
|
|
18044
18681
|
}
|
|
@@ -18087,6 +18724,36 @@ function finalizeStreamingMessagesWhenIdle(messages, status) {
|
|
|
18087
18724
|
};
|
|
18088
18725
|
});
|
|
18089
18726
|
}
|
|
18727
|
+
function collapseAdjacentDuplicateChatMessages(messages) {
|
|
18728
|
+
if (!Array.isArray(messages) || messages.length <= 1) return messages;
|
|
18729
|
+
const result = [];
|
|
18730
|
+
let prevRoleKind = "";
|
|
18731
|
+
let prevStripped = "";
|
|
18732
|
+
for (const message of messages) {
|
|
18733
|
+
const role = typeof message.role === "string" ? message.role : "";
|
|
18734
|
+
const kind = typeof message.kind === "string" ? message.kind : "standard";
|
|
18735
|
+
const content = typeof message.content === "string" ? message.content : Array.isArray(message.content) ? message.content.map((p) => typeof p?.text === "string" ? p.text : "").join("") : "";
|
|
18736
|
+
const strippedContent = content.replace(/\s+/g, "");
|
|
18737
|
+
if (!strippedContent || role === "system") {
|
|
18738
|
+
result.push(message);
|
|
18739
|
+
prevRoleKind = "";
|
|
18740
|
+
prevStripped = "";
|
|
18741
|
+
continue;
|
|
18742
|
+
}
|
|
18743
|
+
const roleKind = `${role}:${kind}`;
|
|
18744
|
+
const sameStripped = strippedContent === prevStripped && roleKind === prevRoleKind;
|
|
18745
|
+
if (result.length > 0 && sameStripped) {
|
|
18746
|
+
result[result.length - 1] = message;
|
|
18747
|
+
prevRoleKind = roleKind;
|
|
18748
|
+
prevStripped = strippedContent;
|
|
18749
|
+
continue;
|
|
18750
|
+
}
|
|
18751
|
+
result.push(message);
|
|
18752
|
+
prevRoleKind = roleKind;
|
|
18753
|
+
prevStripped = strippedContent;
|
|
18754
|
+
}
|
|
18755
|
+
return result;
|
|
18756
|
+
}
|
|
18090
18757
|
function buildReadChatCommandResult(payload, args) {
|
|
18091
18758
|
let validatedPayload;
|
|
18092
18759
|
const debugReadChat = payload?.debugReadChat && typeof payload.debugReadChat === "object" ? payload.debugReadChat : void 0;
|
|
@@ -18609,7 +19276,9 @@ async function handleReadChat(h, args) {
|
|
|
18609
19276
|
const activeModal = parsedRecord.activeModal ?? parsedRecord.modal ?? null;
|
|
18610
19277
|
const returnedStatus = normalizeCliReadChatStatus(parsedRecord.status, activeModal, adapter, adapterStatus, parsedRecord.messages);
|
|
18611
19278
|
const runtimeMessageMerger = getTargetInstance(h, args);
|
|
18612
|
-
const parsedMessages =
|
|
19279
|
+
const parsedMessages = collapseAdjacentDuplicateChatMessages(
|
|
19280
|
+
finalizeStreamingMessagesWhenIdle(parsedRecord.messages, returnedStatus)
|
|
19281
|
+
);
|
|
18613
19282
|
const returnedMessages = runtimeMessageMerger?.category === "cli" && runtimeMessageMerger.type === adapter.cliType && typeof runtimeMessageMerger.mergeRuntimeChatMessages === "function" ? runtimeMessageMerger.mergeRuntimeChatMessages(parsedMessages) : parsedMessages;
|
|
18614
19283
|
const providerType = provider?.type || adapter.cliType;
|
|
18615
19284
|
let selectedMessages = returnedMessages;
|
|
@@ -18620,30 +19289,22 @@ async function handleReadChat(h, args) {
|
|
|
18620
19289
|
let selectedStatus = returnedStatus;
|
|
18621
19290
|
const sessionWorkspace = typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : typeof adapter.workingDir === "string" ? adapter.workingDir : void 0;
|
|
18622
19291
|
const intendedWorkspace = typeof args?.workspace === "string" ? args.workspace : void 0;
|
|
18623
|
-
|
|
18624
|
-
|
|
18625
|
-
|
|
18626
|
-
|
|
18627
|
-
|
|
18628
|
-
|
|
18629
|
-
|
|
18630
|
-
|
|
18631
|
-
|
|
18632
|
-
|
|
18633
|
-
|
|
18634
|
-
|
|
18635
|
-
|
|
18636
|
-
|
|
18637
|
-
|
|
18638
|
-
|
|
18639
|
-
200
|
|
18640
|
-
);
|
|
18641
|
-
const nativeHistorySessionId = resolveCliNativeHistorySessionId(args, historySessionId, providerSessionId);
|
|
18642
|
-
const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
|
|
18643
|
-
const exactNativeHistoryScope = Boolean(
|
|
18644
|
-
typeof args?.historySessionId === "string" && args.historySessionId.trim() || typeof args?.providerSessionId === "string" && args.providerSessionId.trim() || providerSessionId || nativeHistorySessionId && nativeHistorySessionId !== targetSessionId || h.currentSession?.sessionId === args?.targetSessionId && typeof h.currentSession?.providerSessionId === "string" && h.currentSession.providerSessionId.trim()
|
|
18645
|
-
);
|
|
18646
|
-
let nativeHistory = null;
|
|
19292
|
+
const supportsNative = supportsCliNativeTranscript(providerType, provider) && isNativeSourceCanonicalHistory(provider?.canonicalHistory);
|
|
19293
|
+
const agentStr = provider?.type || args?.agentType || getCurrentProviderType(h, adapter.cliType);
|
|
19294
|
+
const workspace = sessionWorkspace;
|
|
19295
|
+
const nativeHistoryLimit = Math.max(
|
|
19296
|
+
normalizeReadChatTailLimit(args) || 0,
|
|
19297
|
+
returnedMessages.length,
|
|
19298
|
+
200
|
|
19299
|
+
);
|
|
19300
|
+
const nativeHistorySessionId = supportsNative ? resolveCliNativeHistorySessionId(args, historySessionId, providerSessionId) : void 0;
|
|
19301
|
+
const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
|
|
19302
|
+
const exactNativeHistoryScope = Boolean(
|
|
19303
|
+
typeof args?.historySessionId === "string" && args.historySessionId.trim() || typeof args?.providerSessionId === "string" && args.providerSessionId.trim() || providerSessionId || nativeHistorySessionId && nativeHistorySessionId !== targetSessionId || h.currentSession?.sessionId === args?.targetSessionId && typeof h.currentSession?.providerSessionId === "string" && h.currentSession.providerSessionId.trim()
|
|
19304
|
+
);
|
|
19305
|
+
let nativeHistory = null;
|
|
19306
|
+
let nativeHistoryError;
|
|
19307
|
+
if (supportsNative) {
|
|
18647
19308
|
try {
|
|
18648
19309
|
nativeHistory = readCliProviderNativeHistory(agentStr, {
|
|
18649
19310
|
canonicalHistory: provider?.canonicalHistory,
|
|
@@ -18657,210 +19318,148 @@ async function handleReadChat(h, args) {
|
|
|
18657
19318
|
excludeInProgressTurn: returnedStatus === "waiting_approval"
|
|
18658
19319
|
});
|
|
18659
19320
|
} catch (error) {
|
|
18660
|
-
|
|
18661
|
-
messageSource = buildCliMessageSourceProvenance({
|
|
18662
|
-
selected: "pty-parser",
|
|
18663
|
-
provider: adapter.cliType,
|
|
18664
|
-
fallbackReason,
|
|
18665
|
-
sessionWorkspace,
|
|
18666
|
-
intendedWorkspace,
|
|
18667
|
-
ptyMessages: returnedMessages,
|
|
18668
|
-
returnedMessages,
|
|
18669
|
-
ptyStatusApprovalOnly: false
|
|
18670
|
-
});
|
|
19321
|
+
nativeHistoryError = error;
|
|
18671
19322
|
nativeHistory = null;
|
|
18672
19323
|
}
|
|
18673
|
-
|
|
18674
|
-
|
|
18675
|
-
|
|
18676
|
-
|
|
18677
|
-
|
|
18678
|
-
|
|
18679
|
-
|
|
18680
|
-
|
|
18681
|
-
|
|
18682
|
-
|
|
18683
|
-
|
|
18684
|
-
|
|
18685
|
-
|
|
18686
|
-
|
|
19324
|
+
}
|
|
19325
|
+
const nativeMessages = nativeHistory && Array.isArray(nativeHistory.messages) ? normalizeNativeHistoryMessages(agentStr, nativeHistory.messages, nativeHistory.providerSessionId) : [];
|
|
19326
|
+
const historyProviderSessionId = typeof nativeHistory?.providerSessionId === "string" ? nativeHistory.providerSessionId : readHistorySessionIdFromMessages(nativeMessages) || nativeHistorySessionId || historySessionId;
|
|
19327
|
+
const lookup = nativeHistory?.lookup === "workspace" ? "workspace" : "session";
|
|
19328
|
+
const nativeHistorySessionForMapping = adapter.cliType === "antigravity-cli" && historyProviderSessionId && nativeHistorySessionId && historyProviderSessionId !== nativeHistorySessionId ? void 0 : nativeHistorySessionId;
|
|
19329
|
+
const safeMapping = supportsNative && nativeHistory ? hasSafeNativeHistoryMapping({
|
|
19330
|
+
historySessionId: lookup === "workspace" ? void 0 : nativeHistorySessionForMapping,
|
|
19331
|
+
providerSessionId: lookup === "workspace" ? void 0 : historyProviderSessionId || providerSessionId,
|
|
19332
|
+
workspace,
|
|
19333
|
+
nativeMessages,
|
|
19334
|
+
ptyMessages: returnedMessages,
|
|
19335
|
+
requireWorkspaceContentOverlap: lookup === "workspace" && !exactNativeHistoryScope
|
|
19336
|
+
}) : false;
|
|
19337
|
+
const machineSessionKey = String(
|
|
19338
|
+
args?.targetSessionId || providerSessionId || historySessionId || h.currentSession?.sessionId || ""
|
|
19339
|
+
);
|
|
19340
|
+
const primary = decideCliReadChatSource({
|
|
19341
|
+
providerType,
|
|
19342
|
+
provider,
|
|
19343
|
+
sessionId: machineSessionKey,
|
|
19344
|
+
nativeHistoryResult: nativeHistory,
|
|
19345
|
+
nativeHistoryError,
|
|
19346
|
+
safeMapping,
|
|
19347
|
+
sessionWorkspace,
|
|
19348
|
+
intendedWorkspace,
|
|
19349
|
+
ptyMessages: returnedMessages,
|
|
19350
|
+
// Start with PTY visible; decideCliReadChatSource flips this
|
|
19351
|
+
// to true when the machine actually selects native-history.
|
|
19352
|
+
ptyStatusApprovalOnly: false
|
|
19353
|
+
});
|
|
19354
|
+
let messageSource = primary.messageSource;
|
|
19355
|
+
if (primary.nativeSelected) {
|
|
19356
|
+
selectedMessages = finalizeStreamingMessagesWhenIdle(primary.nativeMessages, returnedStatus);
|
|
19357
|
+
selectedProviderSessionId = historyProviderSessionId || providerSessionId;
|
|
19358
|
+
selectedTranscriptAuthority = "provider";
|
|
19359
|
+
selectedCoverage = nativeHistory?.hasMore ? "tail" : "full";
|
|
19360
|
+
} else if (supportsNative) {
|
|
19361
|
+
const liveCurrentRuntimePtySafe = isCurrentRuntimePtySafelyAttributed({
|
|
19362
|
+
adapter,
|
|
19363
|
+
helpers: h,
|
|
19364
|
+
readChatArgs: args,
|
|
19365
|
+
sessionWorkspace,
|
|
19366
|
+
intendedWorkspace,
|
|
19367
|
+
ptyMessages: returnedMessages
|
|
19368
|
+
});
|
|
19369
|
+
const mayProbeLiveCodexWorkspaceNative = adapter.cliType === "codex-cli" && liveCurrentRuntimePtySafe && !(typeof args?.providerSessionId === "string" && args.providerSessionId.trim()) && !(providerSessionId && providerSessionId.trim()) && (!historyProviderSessionId || historyProviderSessionId === nativeHistorySessionId || historyProviderSessionId === historySessionId);
|
|
19370
|
+
const liveWorkspaceNativeHistory = mayProbeLiveCodexWorkspaceNative ? readLiveCodexWorkspaceNativeHistory(agentStr, {
|
|
19371
|
+
canonicalHistory: provider?.canonicalHistory,
|
|
19372
|
+
workspace,
|
|
19373
|
+
offset: 0,
|
|
19374
|
+
limit: nativeHistoryLimit,
|
|
19375
|
+
excludeRecentCount: 0,
|
|
19376
|
+
historyBehavior: provider?.historyBehavior,
|
|
19377
|
+
scripts: provider?.scripts
|
|
19378
|
+
}) : null;
|
|
19379
|
+
const liveWorkspaceNativeMessages = Array.isArray(liveWorkspaceNativeHistory?.messages) ? normalizeNativeHistoryMessages(agentStr, liveWorkspaceNativeHistory.messages, liveWorkspaceNativeHistory?.providerSessionId) : [];
|
|
19380
|
+
const liveWorkspaceNativeProviderSessionId = typeof liveWorkspaceNativeHistory?.providerSessionId === "string" ? liveWorkspaceNativeHistory.providerSessionId : readHistorySessionIdFromMessages(liveWorkspaceNativeMessages);
|
|
19381
|
+
const liveWorkspaceNativeSafeMapping = liveWorkspaceNativeMessages.length > 0 && hasSafeNativeHistoryMapping({
|
|
19382
|
+
workspace,
|
|
19383
|
+
nativeMessages: liveWorkspaceNativeMessages,
|
|
19384
|
+
ptyMessages: returnedMessages,
|
|
19385
|
+
requireWorkspaceContentOverlap: true
|
|
19386
|
+
});
|
|
19387
|
+
if (liveWorkspaceNativeHistory) {
|
|
19388
|
+
const liveDecision = decideCliReadChatSource({
|
|
19389
|
+
providerType,
|
|
19390
|
+
provider,
|
|
19391
|
+
// Distinct session key so a transient codex live-probe does not
|
|
19392
|
+
// clobber the primary session's lock. The machine treats this
|
|
19393
|
+
// as its own session; the primary session's state is untouched.
|
|
19394
|
+
sessionId: `${machineSessionKey}::live-workspace`,
|
|
19395
|
+
nativeHistoryResult: liveWorkspaceNativeHistory,
|
|
19396
|
+
safeMapping: liveWorkspaceNativeSafeMapping,
|
|
19397
|
+
sessionWorkspace,
|
|
19398
|
+
intendedWorkspace,
|
|
18687
19399
|
ptyMessages: returnedMessages,
|
|
18688
|
-
|
|
18689
|
-
});
|
|
18690
|
-
const freshEnough = isNativeHistoryFreshEnough({
|
|
18691
|
-
sourceMtimeMs: nativeHistory.sourceMtimeMs,
|
|
18692
|
-
nativeMessages,
|
|
18693
|
-
ptyMessages: returnedMessages
|
|
19400
|
+
ptyStatusApprovalOnly: true
|
|
18694
19401
|
});
|
|
18695
|
-
|
|
18696
|
-
|
|
18697
|
-
|
|
18698
|
-
const nativeIsAnchored = nativeAnchoredAt > 0 && Date.now() - nativeAnchoredAt < NATIVE_ANCHOR_TTL_MS;
|
|
18699
|
-
const allowStaleNativeChatMessages = (adapter.cliType === "antigravity-cli" || nativeIsAnchored) && nativeUsableForChatMessages;
|
|
18700
|
-
if (nativeUsableForChatMessages && (freshEnough || allowStaleNativeChatMessages)) {
|
|
18701
|
-
adapter.nativeHistoryAnchoredAt = Date.now();
|
|
18702
|
-
selectedMessages = finalizeStreamingMessagesWhenIdle(nativeMessages, returnedStatus);
|
|
18703
|
-
selectedProviderSessionId = historyProviderSessionId || providerSessionId;
|
|
19402
|
+
if (liveDecision.nativeSelected) {
|
|
19403
|
+
selectedMessages = finalizeStreamingMessagesWhenIdle(liveDecision.nativeMessages, returnedStatus);
|
|
19404
|
+
selectedProviderSessionId = liveWorkspaceNativeProviderSessionId || providerSessionId;
|
|
18704
19405
|
selectedTranscriptAuthority = "provider";
|
|
18705
|
-
selectedCoverage =
|
|
18706
|
-
messageSource =
|
|
18707
|
-
|
|
18708
|
-
|
|
18709
|
-
nativeHandle: selectedProviderSessionId || nativeHistorySessionId || historySessionId,
|
|
18710
|
-
sessionWorkspace,
|
|
18711
|
-
intendedWorkspace,
|
|
18712
|
-
transcriptWorkspace,
|
|
18713
|
-
nativeSource: nativeHistory.source,
|
|
18714
|
-
sourcePath: nativeHistory.sourcePath,
|
|
18715
|
-
sourceMtimeMs: nativeHistory.sourceMtimeMs,
|
|
18716
|
-
nativeHistoryCoverage,
|
|
18717
|
-
partialReason,
|
|
18718
|
-
unavailableReason,
|
|
18719
|
-
nativeMessages,
|
|
18720
|
-
ptyMessages: returnedMessages,
|
|
18721
|
-
returnedMessages: selectedMessages,
|
|
18722
|
-
safeMapping,
|
|
18723
|
-
freshEnough,
|
|
18724
|
-
ptyStatusApprovalOnly: true
|
|
18725
|
-
});
|
|
19406
|
+
selectedCoverage = liveWorkspaceNativeHistory.hasMore ? "tail" : "full";
|
|
19407
|
+
messageSource = liveDecision.messageSource;
|
|
19408
|
+
messageSource.selectedDaemonSource = "live-workspace-native-history";
|
|
19409
|
+
messageSource.runtimeMappingSafe = true;
|
|
18726
19410
|
} else {
|
|
18727
|
-
|
|
18728
|
-
|
|
18729
|
-
}
|
|
18730
|
-
const liveCurrentRuntimePtySafe = isCurrentRuntimePtySafelyAttributed({
|
|
19411
|
+
applyUnsafeNativeDaemonFallback({
|
|
19412
|
+
providerType,
|
|
18731
19413
|
adapter,
|
|
18732
19414
|
helpers: h,
|
|
18733
19415
|
readChatArgs: args,
|
|
18734
19416
|
sessionWorkspace,
|
|
18735
19417
|
intendedWorkspace,
|
|
18736
|
-
ptyMessages: returnedMessages
|
|
18737
|
-
});
|
|
18738
|
-
const mayProbeLiveCodexWorkspaceNative = adapter.cliType === "codex-cli" && liveCurrentRuntimePtySafe && !(typeof args?.providerSessionId === "string" && args.providerSessionId.trim()) && !(providerSessionId && providerSessionId.trim()) && (!historyProviderSessionId || historyProviderSessionId === nativeHistorySessionId || historyProviderSessionId === historySessionId);
|
|
18739
|
-
const liveWorkspaceNativeHistory = mayProbeLiveCodexWorkspaceNative ? readLiveCodexWorkspaceNativeHistory(agentStr, {
|
|
18740
|
-
canonicalHistory: provider?.canonicalHistory,
|
|
18741
|
-
workspace,
|
|
18742
|
-
offset: 0,
|
|
18743
|
-
limit: nativeHistoryLimit,
|
|
18744
|
-
excludeRecentCount: 0,
|
|
18745
|
-
historyBehavior: provider?.historyBehavior,
|
|
18746
|
-
scripts: provider?.scripts
|
|
18747
|
-
}) : null;
|
|
18748
|
-
const liveWorkspaceNativeMessages = Array.isArray(liveWorkspaceNativeHistory?.messages) ? normalizeNativeHistoryMessages(agentStr, liveWorkspaceNativeHistory.messages, liveWorkspaceNativeHistory?.providerSessionId) : [];
|
|
18749
|
-
const liveWorkspaceNativeProviderSessionId = typeof liveWorkspaceNativeHistory?.providerSessionId === "string" ? liveWorkspaceNativeHistory.providerSessionId : readHistorySessionIdFromMessages(liveWorkspaceNativeMessages);
|
|
18750
|
-
const liveWorkspaceTranscriptWorkspace = typeof liveWorkspaceNativeHistory?.workspace === "string" ? liveWorkspaceNativeHistory.workspace : liveWorkspaceNativeMessages.map((message) => typeof message?.workspace === "string" ? message.workspace.trim() : "").find(Boolean);
|
|
18751
|
-
const liveWorkspaceNativeSafeMapping = liveWorkspaceNativeMessages.length > 0 && hasSafeNativeHistoryMapping({
|
|
18752
|
-
workspace,
|
|
18753
|
-
nativeMessages: liveWorkspaceNativeMessages,
|
|
18754
19418
|
ptyMessages: returnedMessages,
|
|
18755
|
-
|
|
18756
|
-
|
|
18757
|
-
|
|
18758
|
-
|
|
18759
|
-
|
|
18760
|
-
|
|
19419
|
+
nativeHistoryLimit,
|
|
19420
|
+
provider,
|
|
19421
|
+
messageSourceRef: { set(value) {
|
|
19422
|
+
messageSource = value;
|
|
19423
|
+
}, get() {
|
|
19424
|
+
return messageSource;
|
|
19425
|
+
} },
|
|
19426
|
+
apply(selection) {
|
|
19427
|
+
selectedMessages = selection.messages;
|
|
19428
|
+
selectedTranscriptAuthority = selection.transcriptAuthority;
|
|
19429
|
+
selectedCoverage = selection.coverage ?? coverage;
|
|
19430
|
+
selectedStatus = selection.status ?? returnedStatus;
|
|
19431
|
+
},
|
|
19432
|
+
activeModal,
|
|
19433
|
+
returnedStatus,
|
|
19434
|
+
coverage
|
|
18761
19435
|
});
|
|
18762
|
-
const liveWorkspaceNativeUsable = liveWorkspaceNativeHistory?.source === "provider-native" && liveWorkspaceNativeMessages.length > 0 && liveWorkspaceNativeHistory?.nativeHistoryCoverage !== "partial" && liveWorkspaceNativeHistory?.nativeHistoryCoverage !== "unavailable" && liveWorkspaceNativeSafeMapping && liveWorkspaceNativeFreshEnough;
|
|
18763
|
-
if (liveWorkspaceNativeUsable) {
|
|
18764
|
-
selectedMessages = finalizeStreamingMessagesWhenIdle(liveWorkspaceNativeMessages, returnedStatus);
|
|
18765
|
-
selectedProviderSessionId = liveWorkspaceNativeProviderSessionId || providerSessionId;
|
|
18766
|
-
selectedTranscriptAuthority = "provider";
|
|
18767
|
-
selectedCoverage = liveWorkspaceNativeHistory.hasMore ? "tail" : "full";
|
|
18768
|
-
messageSource = buildCliMessageSourceProvenance({
|
|
18769
|
-
selected: "native-history",
|
|
18770
|
-
provider: adapter.cliType,
|
|
18771
|
-
nativeHandle: selectedProviderSessionId || nativeHistorySessionId || historySessionId,
|
|
18772
|
-
sessionWorkspace,
|
|
18773
|
-
intendedWorkspace,
|
|
18774
|
-
transcriptWorkspace: liveWorkspaceTranscriptWorkspace,
|
|
18775
|
-
nativeSource: liveWorkspaceNativeHistory.source,
|
|
18776
|
-
sourcePath: liveWorkspaceNativeHistory.sourcePath,
|
|
18777
|
-
sourceMtimeMs: liveWorkspaceNativeHistory.sourceMtimeMs,
|
|
18778
|
-
nativeHistoryCoverage: liveWorkspaceNativeHistory.nativeHistoryCoverage,
|
|
18779
|
-
partialReason: liveWorkspaceNativeHistory.partialReason,
|
|
18780
|
-
unavailableReason: liveWorkspaceNativeHistory.unavailableReason,
|
|
18781
|
-
nativeMessages: liveWorkspaceNativeMessages,
|
|
18782
|
-
ptyMessages: returnedMessages,
|
|
18783
|
-
returnedMessages: selectedMessages,
|
|
18784
|
-
safeMapping: true,
|
|
18785
|
-
freshEnough: true,
|
|
18786
|
-
ptyStatusApprovalOnly: true
|
|
18787
|
-
});
|
|
18788
|
-
messageSource.selectedDaemonSource = "live-workspace-native-history";
|
|
18789
|
-
messageSource.runtimeMappingSafe = true;
|
|
18790
|
-
} else {
|
|
18791
|
-
const fallbackReason = buildNativeHistoryFallbackReason({
|
|
18792
|
-
providerType,
|
|
18793
|
-
provider,
|
|
18794
|
-
nativeSource: nativeHistory.source,
|
|
18795
|
-
nativeHistoryCoverage,
|
|
18796
|
-
unavailableReason,
|
|
18797
|
-
nativeMessageCount: nativeMessages.length,
|
|
18798
|
-
safeMapping,
|
|
18799
|
-
freshEnough
|
|
18800
|
-
});
|
|
18801
|
-
const unsafeNativeFallback = adapter.cliType === "codex-cli" && isUnsafeNativeTranscriptFallback(fallbackReason);
|
|
18802
|
-
const safeCurrentRuntimePtyMessages = unsafeNativeFallback && isCurrentRuntimePtySafelyAttributed({
|
|
18803
|
-
adapter,
|
|
18804
|
-
helpers: h,
|
|
18805
|
-
readChatArgs: args,
|
|
18806
|
-
sessionWorkspace,
|
|
18807
|
-
intendedWorkspace,
|
|
18808
|
-
ptyMessages: returnedMessages
|
|
18809
|
-
});
|
|
18810
|
-
const safeRuntimeAckMessages = unsafeNativeFallback && !safeCurrentRuntimePtyMessages ? selectRuntimeInputAckMessages(returnedMessages) : [];
|
|
18811
|
-
const exactRuntimeMirrorMessages = unsafeNativeFallback && !safeCurrentRuntimePtyMessages && safeRuntimeAckMessages.length === 0 ? readExactRuntimeMirrorMessages({
|
|
18812
|
-
providerType,
|
|
18813
|
-
targetSessionId: typeof args?.targetSessionId === "string" ? args.targetSessionId : void 0,
|
|
18814
|
-
currentSessionId: typeof h.currentSession?.sessionId === "string" ? h.currentSession.sessionId : void 0,
|
|
18815
|
-
tailLimit: nativeHistoryLimit,
|
|
18816
|
-
historyBehavior: provider?.historyBehavior
|
|
18817
|
-
}) : [];
|
|
18818
|
-
const safeDaemonMessages = safeRuntimeAckMessages.length > 0 ? safeRuntimeAckMessages : exactRuntimeMirrorMessages;
|
|
18819
|
-
if (unsafeNativeFallback) {
|
|
18820
|
-
if (safeCurrentRuntimePtyMessages) {
|
|
18821
|
-
selectedMessages = returnedMessages;
|
|
18822
|
-
selectedTranscriptAuthority = "daemon";
|
|
18823
|
-
selectedCoverage = coverage || "current-turn";
|
|
18824
|
-
selectedStatus = returnedStatus;
|
|
18825
|
-
} else {
|
|
18826
|
-
selectedMessages = safeDaemonMessages;
|
|
18827
|
-
selectedTranscriptAuthority = safeDaemonMessages.length > 0 ? "daemon" : void 0;
|
|
18828
|
-
selectedCoverage = safeDaemonMessages.length > 0 ? "tail" : void 0;
|
|
18829
|
-
selectedStatus = coerceUnsafeNativeFallbackStatus(returnedStatus, activeModal);
|
|
18830
|
-
}
|
|
18831
|
-
}
|
|
18832
|
-
messageSource = buildCliMessageSourceProvenance({
|
|
18833
|
-
selected: "pty-parser",
|
|
18834
|
-
provider: adapter.cliType,
|
|
18835
|
-
nativeHandle: historyProviderSessionId || nativeHistorySessionId || historySessionId,
|
|
18836
|
-
sessionWorkspace,
|
|
18837
|
-
intendedWorkspace,
|
|
18838
|
-
transcriptWorkspace,
|
|
18839
|
-
fallbackReason,
|
|
18840
|
-
nativeSource: nativeHistory.source,
|
|
18841
|
-
sourcePath: nativeHistory.sourcePath,
|
|
18842
|
-
sourceMtimeMs: nativeHistory.sourceMtimeMs,
|
|
18843
|
-
nativeHistoryCoverage,
|
|
18844
|
-
partialReason,
|
|
18845
|
-
unavailableReason,
|
|
18846
|
-
nativeMessages,
|
|
18847
|
-
ptyMessages: returnedMessages,
|
|
18848
|
-
returnedMessages: unsafeNativeFallback && !safeCurrentRuntimePtyMessages ? safeDaemonMessages : returnedMessages,
|
|
18849
|
-
safeMapping,
|
|
18850
|
-
freshEnough,
|
|
18851
|
-
ptyStatusApprovalOnly: unsafeNativeFallback && !safeCurrentRuntimePtyMessages
|
|
18852
|
-
});
|
|
18853
|
-
if (safeCurrentRuntimePtyMessages) {
|
|
18854
|
-
messageSource.selectedDaemonSource = "current-runtime-pty";
|
|
18855
|
-
messageSource.transcriptAuthority = "daemon";
|
|
18856
|
-
messageSource.runtimeMappingSafe = true;
|
|
18857
|
-
}
|
|
18858
|
-
if (unsafeNativeFallback && exactRuntimeMirrorMessages.length > 0) {
|
|
18859
|
-
messageSource.selectedDaemonSource = "exact-runtime-mirror";
|
|
18860
|
-
messageSource.transcriptAuthority = "daemon";
|
|
18861
|
-
}
|
|
18862
|
-
}
|
|
18863
19436
|
}
|
|
19437
|
+
} else {
|
|
19438
|
+
applyUnsafeNativeDaemonFallback({
|
|
19439
|
+
providerType,
|
|
19440
|
+
adapter,
|
|
19441
|
+
helpers: h,
|
|
19442
|
+
readChatArgs: args,
|
|
19443
|
+
sessionWorkspace,
|
|
19444
|
+
intendedWorkspace,
|
|
19445
|
+
ptyMessages: returnedMessages,
|
|
19446
|
+
nativeHistoryLimit,
|
|
19447
|
+
provider,
|
|
19448
|
+
messageSourceRef: { set(value) {
|
|
19449
|
+
messageSource = value;
|
|
19450
|
+
}, get() {
|
|
19451
|
+
return messageSource;
|
|
19452
|
+
} },
|
|
19453
|
+
apply(selection) {
|
|
19454
|
+
selectedMessages = selection.messages;
|
|
19455
|
+
selectedTranscriptAuthority = selection.transcriptAuthority;
|
|
19456
|
+
selectedCoverage = selection.coverage ?? coverage;
|
|
19457
|
+
selectedStatus = selection.status ?? returnedStatus;
|
|
19458
|
+
},
|
|
19459
|
+
activeModal,
|
|
19460
|
+
returnedStatus,
|
|
19461
|
+
coverage
|
|
19462
|
+
});
|
|
18864
19463
|
}
|
|
18865
19464
|
}
|
|
18866
19465
|
LOG.debug("Command", `[read_chat] cli-like parsed provider=${adapter.cliType} target=${String(args?.targetSessionId || "")} adapterStatus=${String(adapterStatus.status || "")} parsedStatus=${String(parsedRecord.status || "")} parsedMsgCount=${parsedRecord.messages.length} returnedMsgCount=${returnedMessages.length}`);
|
|
@@ -18893,10 +19492,8 @@ async function handleReadChat(h, args) {
|
|
|
18893
19492
|
const agentStr = provider?.type || args?.agentType || getCurrentProviderType(h);
|
|
18894
19493
|
const workspace = typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : void 0;
|
|
18895
19494
|
const intendedWorkspace = typeof args?.workspace === "string" ? args.workspace : void 0;
|
|
18896
|
-
const
|
|
18897
|
-
|
|
18898
|
-
);
|
|
18899
|
-
const history = supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.canonicalHistory) ? readCliProviderNativeHistory(agentStr, {
|
|
19495
|
+
const supportsNative = supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.canonicalHistory);
|
|
19496
|
+
const history = supportsNative ? readCliProviderNativeHistory(agentStr, {
|
|
18900
19497
|
canonicalHistory: provider?.canonicalHistory,
|
|
18901
19498
|
historySessionId,
|
|
18902
19499
|
workspace,
|
|
@@ -18915,65 +19512,44 @@ async function handleReadChat(h, args) {
|
|
|
18915
19512
|
historyBehavior: provider?.historyBehavior,
|
|
18916
19513
|
scripts: provider?.scripts
|
|
18917
19514
|
});
|
|
18918
|
-
const lookup = history
|
|
19515
|
+
const lookup = history?.lookup === "workspace" ? "workspace" : "session";
|
|
18919
19516
|
const historyMessages = Array.isArray(history?.messages) ? normalizeNativeHistoryMessages(agentStr, history.messages, history?.providerSessionId) : [];
|
|
18920
19517
|
const historyProviderSessionId = typeof history?.providerSessionId === "string" ? history.providerSessionId : readHistorySessionIdFromMessages(historyMessages) || historySessionId;
|
|
18921
|
-
const
|
|
18922
|
-
const partialReason = typeof history?.partialReason === "string" ? history.partialReason : void 0;
|
|
18923
|
-
const unavailableReason = typeof history?.unavailableReason === "string" ? history.unavailableReason : void 0;
|
|
18924
|
-
const transcriptWorkspace = typeof history?.workspace === "string" ? history.workspace : historyMessages.map((message) => typeof message?.workspace === "string" ? message.workspace.trim() : "").find(Boolean);
|
|
18925
|
-
const safeMapping = supportsCliNativeTranscript(agentStr, provider) ? hasSafeNativeHistoryMapping({
|
|
19518
|
+
const safeMapping = supportsNative ? hasSafeNativeHistoryMapping({
|
|
18926
19519
|
historySessionId: lookup === "workspace" ? void 0 : historySessionId,
|
|
18927
19520
|
providerSessionId: lookup === "workspace" ? void 0 : historyProviderSessionId,
|
|
18928
19521
|
workspace,
|
|
18929
19522
|
nativeMessages: historyMessages
|
|
18930
19523
|
}) : false;
|
|
18931
|
-
const
|
|
18932
|
-
|
|
18933
|
-
|
|
18934
|
-
|
|
18935
|
-
|
|
19524
|
+
const machineSessionKey = String(
|
|
19525
|
+
args?.targetSessionId || historyProviderSessionId || historySessionId || h.currentSession?.sessionId || ""
|
|
19526
|
+
);
|
|
19527
|
+
const decision = decideCliReadChatSource({
|
|
19528
|
+
providerType: agentStr,
|
|
19529
|
+
provider,
|
|
19530
|
+
sessionId: machineSessionKey,
|
|
19531
|
+
nativeHistoryResult: history,
|
|
19532
|
+
safeMapping,
|
|
18936
19533
|
sessionWorkspace: workspace,
|
|
18937
19534
|
intendedWorkspace,
|
|
18938
|
-
|
|
18939
|
-
fallbackReason: nativeSelected ? void 0 : buildNativeHistoryFallbackReason({
|
|
18940
|
-
providerType: agentStr,
|
|
18941
|
-
provider,
|
|
18942
|
-
nativeSource: history.source,
|
|
18943
|
-
nativeHistoryCoverage,
|
|
18944
|
-
unavailableReason,
|
|
18945
|
-
nativeMessageCount: historyMessages.length,
|
|
18946
|
-
safeMapping,
|
|
18947
|
-
freshEnough: true
|
|
18948
|
-
}),
|
|
18949
|
-
nativeSource: history.source,
|
|
18950
|
-
sourcePath: history.sourcePath,
|
|
18951
|
-
sourceMtimeMs: history.sourceMtimeMs,
|
|
18952
|
-
nativeHistoryCoverage,
|
|
18953
|
-
partialReason,
|
|
18954
|
-
unavailableReason,
|
|
18955
|
-
nativeMessages: historyMessages,
|
|
18956
|
-
returnedMessages: historyMessages,
|
|
18957
|
-
safeMapping,
|
|
18958
|
-
freshEnough: true,
|
|
19535
|
+
ptyMessages: [],
|
|
18959
19536
|
ptyStatusApprovalOnly: false
|
|
18960
19537
|
});
|
|
18961
|
-
|
|
18962
|
-
if (requiresNativeSource && !nativeSelected) {
|
|
19538
|
+
if (supportsNative && !decision.nativeSelected) {
|
|
18963
19539
|
return {
|
|
18964
19540
|
success: false,
|
|
18965
19541
|
code: "native_history_not_safely_available",
|
|
18966
19542
|
error: "Provider-native history was not safely available for the requested CLI session.",
|
|
18967
19543
|
providerSessionId: historyProviderSessionId,
|
|
18968
|
-
messageSource,
|
|
18969
|
-
transcriptProvenance: messageSource
|
|
19544
|
+
messageSource: decision.messageSource,
|
|
19545
|
+
transcriptProvenance: decision.messageSource
|
|
18970
19546
|
};
|
|
18971
19547
|
}
|
|
18972
19548
|
return buildReadChatCommandResult({
|
|
18973
19549
|
messages: historyMessages,
|
|
18974
19550
|
status: "idle",
|
|
18975
|
-
messageSource,
|
|
18976
|
-
transcriptProvenance: messageSource,
|
|
19551
|
+
messageSource: decision.messageSource,
|
|
19552
|
+
transcriptProvenance: decision.messageSource,
|
|
18977
19553
|
...typeof history?.title === "string" ? { title: history.title } : {},
|
|
18978
19554
|
...historyProviderSessionId ? { providerSessionId: historyProviderSessionId } : {},
|
|
18979
19555
|
...provider?.historyBehavior?.transcriptAuthority === "provider" || provider?.historyBehavior?.transcriptAuthority === "daemon" ? { transcriptAuthority: (provider?.historyBehavior).transcriptAuthority } : {},
|
|
@@ -25196,6 +25772,10 @@ function validateCanonicalHistory(raw, errors) {
|
|
|
25196
25772
|
if (mode !== void 0 && !["native-source", "materialized-mirror", "disabled"].includes(String(mode))) {
|
|
25197
25773
|
errors.push("canonicalHistory.mode must be one of: native-source, materialized-mirror, disabled");
|
|
25198
25774
|
}
|
|
25775
|
+
const chatContractVersion = canonicalHistory.contractVersion;
|
|
25776
|
+
if (chatContractVersion !== void 0 && chatContractVersion !== "1.0" && chatContractVersion !== "2.0") {
|
|
25777
|
+
errors.push(`canonicalHistory.contractVersion must be '1.0' or '2.0' when provided (got ${JSON.stringify(chatContractVersion)})`);
|
|
25778
|
+
}
|
|
25199
25779
|
const scripts = canonicalHistory.scripts;
|
|
25200
25780
|
if (scripts === void 0) return;
|
|
25201
25781
|
if (!scripts || typeof scripts !== "object" || Array.isArray(scripts)) {
|
|
@@ -26434,7 +27014,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
26434
27014
|
return args ? args.map((arg) => /\s/.test(arg) ? JSON.stringify(arg) : arg).join(" ") : "";
|
|
26435
27015
|
}
|
|
26436
27016
|
const schemaDef = this.getSettingsSchema(providerType)[key];
|
|
26437
|
-
const defaultVal = schemaDef ?
|
|
27017
|
+
const defaultVal = schemaDef ? schemaDef.default : void 0;
|
|
26438
27018
|
const config = this.readConfig();
|
|
26439
27019
|
const userVal = config?.providerSettings?.[providerType]?.[key];
|
|
26440
27020
|
return userVal !== void 0 ? userVal : defaultVal;
|
|
@@ -26536,7 +27116,6 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
26536
27116
|
if (result.autoApprove?.type === "boolean") {
|
|
26537
27117
|
result.autoApprove = {
|
|
26538
27118
|
...result.autoApprove,
|
|
26539
|
-
default: true,
|
|
26540
27119
|
public: true,
|
|
26541
27120
|
label: result.autoApprove.label || "Auto Approve",
|
|
26542
27121
|
description: result.autoApprove.description || "Automatically approve actionable prompts without sending approval alerts."
|
|
@@ -26558,7 +27137,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
26558
27137
|
if (!provider.settings?.autoApprove) {
|
|
26559
27138
|
result.autoApprove = {
|
|
26560
27139
|
type: "boolean",
|
|
26561
|
-
default
|
|
27140
|
+
// (fix) Safe default is *off*. Auto-approving every modal without the
|
|
27141
|
+
// user opting in produced silent-bash-execution surprises and the
|
|
27142
|
+
// "Auto-approved: ..." system-message flood seen on AGY/Codex.
|
|
27143
|
+
default: false,
|
|
26562
27144
|
public: true,
|
|
26563
27145
|
label: "Auto Approve",
|
|
26564
27146
|
description: "Automatically approve actionable prompts without sending approval alerts."
|
|
@@ -27855,15 +28437,22 @@ function getSessionMessageUpdatedAt(session) {
|
|
|
27855
28437
|
return getMessageEventTime(lastMessage);
|
|
27856
28438
|
}
|
|
27857
28439
|
function getSessionCompletionMarker(session) {
|
|
27858
|
-
const
|
|
27859
|
-
if (!
|
|
27860
|
-
|
|
27861
|
-
|
|
27862
|
-
|
|
27863
|
-
|
|
27864
|
-
|
|
27865
|
-
|
|
27866
|
-
|
|
28440
|
+
const messages = session.activeChat?.messages;
|
|
28441
|
+
if (!Array.isArray(messages) || messages.length === 0) return "";
|
|
28442
|
+
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
28443
|
+
const m = messages[i];
|
|
28444
|
+
const role = typeof m?.role === "string" ? m.role : "";
|
|
28445
|
+
const kind = typeof m?.kind === "string" ? m.kind : "";
|
|
28446
|
+
if (role === "user" || role === "human") return "";
|
|
28447
|
+
if (role === "system") continue;
|
|
28448
|
+
if (kind === "tool") continue;
|
|
28449
|
+
if (typeof m._turnKey === "string" && m._turnKey) return `turn:${m._turnKey}`;
|
|
28450
|
+
if (typeof m.id === "string" && m.id) return `id:${m.id}`;
|
|
28451
|
+
if (typeof m.index === "number" && Number.isFinite(m.index)) return `idx:${m.index}`;
|
|
28452
|
+
const timestamp = getMessageEventTime(m);
|
|
28453
|
+
return timestamp > 0 ? `ts:${timestamp}` : "";
|
|
28454
|
+
}
|
|
28455
|
+
return "";
|
|
27867
28456
|
}
|
|
27868
28457
|
function getSessionLastUsedAt(session) {
|
|
27869
28458
|
return getSessionMessageUpdatedAt(session) || session.lastUpdated || Date.now();
|
|
@@ -27878,7 +28467,8 @@ function getUnreadState(hasContentChange, status, lastUsedAt, lastSeenAt, lastRo
|
|
|
27878
28467
|
if (status === "generating" || status === "starting") {
|
|
27879
28468
|
return { unread: false, inboxBucket: "working" };
|
|
27880
28469
|
}
|
|
27881
|
-
const
|
|
28470
|
+
const ignorableTrailingRoles = lastRole === "user" || lastRole === "human" || lastRole === "system" || lastRole === "tool";
|
|
28471
|
+
const unread = completionMarker ? seenCompletionMarker ? completionMarker !== seenCompletionMarker : hasContentChange && lastUsedAt > lastSeenAt && !ignorableTrailingRoles : hasContentChange && lastUsedAt > lastSeenAt && !ignorableTrailingRoles;
|
|
27882
28472
|
return { unread, inboxBucket: unread ? "task_complete" : "idle" };
|
|
27883
28473
|
}
|
|
27884
28474
|
function projectLiveSessionFromFull(session) {
|
|
@@ -31242,7 +31832,8 @@ var DaemonCommandRouter = class {
|
|
|
31242
31832
|
}
|
|
31243
31833
|
case "get_pending_mesh_events": {
|
|
31244
31834
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
31245
|
-
const
|
|
31835
|
+
const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : void 0;
|
|
31836
|
+
const events = drainPendingMeshCoordinatorEvents(meshId || void 0, coordinatorDaemonId);
|
|
31246
31837
|
return { success: true, events };
|
|
31247
31838
|
}
|
|
31248
31839
|
case "launch_cli":
|
|
@@ -33218,7 +33809,8 @@ ${block2}`);
|
|
|
33218
33809
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
33219
33810
|
nodeStatuses.push(status);
|
|
33220
33811
|
}
|
|
33221
|
-
const
|
|
33812
|
+
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : void 0;
|
|
33813
|
+
const pendingCoordinatorEvents = drainPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
33222
33814
|
const previewFreshness = (() => {
|
|
33223
33815
|
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs11.existsSync(candidate));
|
|
33224
33816
|
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
@@ -33696,6 +34288,7 @@ function prepareSessionChatTailUpdate(input) {
|
|
|
33696
34288
|
const title = typeof result.title === "string" ? result.title : void 0;
|
|
33697
34289
|
const activeModal = normalizeChatTailActiveModal(result.activeModal);
|
|
33698
34290
|
const status = typeof result.status === "string" ? result.status : "idle";
|
|
34291
|
+
const messageSource = result.messageSource && typeof result.messageSource === "object" ? result.messageSource : void 0;
|
|
33699
34292
|
const deliverySignature = buildChatTailDeliverySignature({
|
|
33700
34293
|
sessionId: input.sessionId,
|
|
33701
34294
|
...input.historySessionId ? { historySessionId: input.historySessionId } : {},
|
|
@@ -33728,7 +34321,8 @@ function prepareSessionChatTailUpdate(input) {
|
|
|
33728
34321
|
messages,
|
|
33729
34322
|
status,
|
|
33730
34323
|
...title ? { title } : {},
|
|
33731
|
-
...activeModal ? { activeModal } : {}
|
|
34324
|
+
...activeModal ? { activeModal } : {},
|
|
34325
|
+
...messageSource ? { messageSource } : {}
|
|
33732
34326
|
}
|
|
33733
34327
|
};
|
|
33734
34328
|
}
|