@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.mjs
CHANGED
|
@@ -4343,7 +4343,14 @@ var init_ghostty_vt_backend = __esm({
|
|
|
4343
4343
|
this.terminal.write(data);
|
|
4344
4344
|
}
|
|
4345
4345
|
getText() {
|
|
4346
|
-
|
|
4346
|
+
const raw = this.terminal.formatPlainText({ trim: false }) || "";
|
|
4347
|
+
if (!raw) return "";
|
|
4348
|
+
const lines = raw.split("\n").map((row) => row.replace(/\s+$/, ""));
|
|
4349
|
+
let first = 0;
|
|
4350
|
+
let last = lines.length;
|
|
4351
|
+
while (first < last && !lines[first]) first += 1;
|
|
4352
|
+
while (last > first && !lines[last - 1]) last -= 1;
|
|
4353
|
+
return lines.slice(first, last).join("\n");
|
|
4347
4354
|
}
|
|
4348
4355
|
getCursorPosition() {
|
|
4349
4356
|
return this.terminal.getCursorPosition();
|
|
@@ -4397,7 +4404,8 @@ var init_xterm_backend = __esm({
|
|
|
4397
4404
|
const lines = [];
|
|
4398
4405
|
for (let i = start; i < end; i++) {
|
|
4399
4406
|
const line = buffer.getLine(i);
|
|
4400
|
-
|
|
4407
|
+
const raw = line ? line.translateToString(false) : "";
|
|
4408
|
+
lines.push(raw.replace(/\s+$/, ""));
|
|
4401
4409
|
}
|
|
4402
4410
|
let first = 0;
|
|
4403
4411
|
let last = lines.length;
|
|
@@ -4932,8 +4940,13 @@ var init_provider_cli_shared = __esm({
|
|
|
4932
4940
|
this.ensureRow();
|
|
4933
4941
|
if (final === "A") this.row = Math.max(0, this.row - count);
|
|
4934
4942
|
else if (final === "B") this.row += count;
|
|
4935
|
-
else if (final === "C")
|
|
4936
|
-
|
|
4943
|
+
else if (final === "C") {
|
|
4944
|
+
const line = this.lines[this.row];
|
|
4945
|
+
for (let c = this.col; c < this.col + count; c += 1) {
|
|
4946
|
+
if (line[c] === void 0) line[c] = " ";
|
|
4947
|
+
}
|
|
4948
|
+
this.col += count;
|
|
4949
|
+
} else if (final === "D") this.col = Math.max(0, this.col - count);
|
|
4937
4950
|
else if (final === "G") this.col = Math.max(0, count - 1);
|
|
4938
4951
|
else if (final === "H" || final === "f") {
|
|
4939
4952
|
const parts = String(params || "").split(";");
|
|
@@ -5106,7 +5119,8 @@ function buildCliParseInput(options) {
|
|
|
5106
5119
|
partialResponse,
|
|
5107
5120
|
isWaitingForResponse,
|
|
5108
5121
|
scope,
|
|
5109
|
-
runtimeSettings
|
|
5122
|
+
runtimeSettings,
|
|
5123
|
+
spawnAt
|
|
5110
5124
|
} = options;
|
|
5111
5125
|
const buffer = scope ? sliceFromOffset(accumulatedBuffer, scope.bufferStart) : accumulatedBuffer;
|
|
5112
5126
|
const rawBuffer = scope ? sliceFromOffset(accumulatedRawBuffer, scope.rawBufferStart) : accumulatedRawBuffer;
|
|
@@ -5128,7 +5142,8 @@ function buildCliParseInput(options) {
|
|
|
5128
5142
|
partialResponse,
|
|
5129
5143
|
isWaitingForResponse,
|
|
5130
5144
|
promptText: scope?.prompt || "",
|
|
5131
|
-
settings: { ...runtimeSettings }
|
|
5145
|
+
settings: { ...runtimeSettings },
|
|
5146
|
+
...typeof spawnAt === "number" && spawnAt > 0 ? { spawnAt } : {}
|
|
5132
5147
|
};
|
|
5133
5148
|
}
|
|
5134
5149
|
function summarizeCliTraceText(text, max = 800) {
|
|
@@ -5144,7 +5159,7 @@ var init_provider_cli_parse = __esm({
|
|
|
5144
5159
|
});
|
|
5145
5160
|
|
|
5146
5161
|
// src/cli-adapters/cli-state-engine.ts
|
|
5147
|
-
var SCRIPT_STATUS_DEBOUNCE_MS, MAX_FINISH_RETRIES, FINISH_RETRY_DELAY_MS, MAX_TRACE_ENTRIES, APPROVAL_EXIT_TIMEOUT_MS, CliStateEngine;
|
|
5162
|
+
var SCRIPT_STATUS_DEBOUNCE_MS, MAX_FINISH_RETRIES, FINISH_RETRY_DELAY_MS, MAX_TRACE_ENTRIES, APPROVAL_EXIT_TIMEOUT_MS, IDLE_CONFIRMATION_GRACE_MS, CliStateEngine;
|
|
5148
5163
|
var init_cli_state_engine = __esm({
|
|
5149
5164
|
"src/cli-adapters/cli-state-engine.ts"() {
|
|
5150
5165
|
"use strict";
|
|
@@ -5156,6 +5171,7 @@ var init_cli_state_engine = __esm({
|
|
|
5156
5171
|
FINISH_RETRY_DELAY_MS = 300;
|
|
5157
5172
|
MAX_TRACE_ENTRIES = 250;
|
|
5158
5173
|
APPROVAL_EXIT_TIMEOUT_MS = 6e4;
|
|
5174
|
+
IDLE_CONFIRMATION_GRACE_MS = 2e3;
|
|
5159
5175
|
CliStateEngine = class {
|
|
5160
5176
|
constructor(provider, runner, transport, callbacks, timeouts) {
|
|
5161
5177
|
this.provider = provider;
|
|
@@ -5194,6 +5210,20 @@ var init_cli_state_engine = __esm({
|
|
|
5194
5210
|
pendingScriptStatusTimer = null;
|
|
5195
5211
|
// ── Idle candidate ───────────────────────────────
|
|
5196
5212
|
idleFinishCandidate = null;
|
|
5213
|
+
// ── Idle confirmation grace ──────────────────────
|
|
5214
|
+
/**
|
|
5215
|
+
* `finishResponse` produces the `generating → idle` transition that
|
|
5216
|
+
* coordinators interpret as "task complete". Some providers (antigravity-
|
|
5217
|
+
* cli observed in the wild) briefly paint a screen that looks like an
|
|
5218
|
+
* idle prompt between tool result frames while still actively running,
|
|
5219
|
+
* which fired `response_finished` and broke completion semantics.
|
|
5220
|
+
* We defer the actual idle transition by IDLE_CONFIRMATION_GRACE_MS and
|
|
5221
|
+
* cancel it if the scripted detection re-detects generating during that
|
|
5222
|
+
* window — a true completion stays idle for many seconds, so a 2-second
|
|
5223
|
+
* grace is sufficient to filter the paint blip.
|
|
5224
|
+
*/
|
|
5225
|
+
pendingIdleFinishTimer = null;
|
|
5226
|
+
pendingIdleFinishAt = 0;
|
|
5197
5227
|
// ── Status history (debug) ───────────────────────
|
|
5198
5228
|
statusHistory = [];
|
|
5199
5229
|
traceEntries = [];
|
|
@@ -5368,6 +5398,11 @@ var init_cli_state_engine = __esm({
|
|
|
5368
5398
|
clearTimeout(this.providerErrorRetryTimer);
|
|
5369
5399
|
this.providerErrorRetryTimer = null;
|
|
5370
5400
|
}
|
|
5401
|
+
if (this.pendingIdleFinishTimer) {
|
|
5402
|
+
clearTimeout(this.pendingIdleFinishTimer);
|
|
5403
|
+
this.pendingIdleFinishTimer = null;
|
|
5404
|
+
this.pendingIdleFinishAt = 0;
|
|
5405
|
+
}
|
|
5371
5406
|
this.providerErrorRetryKey = "";
|
|
5372
5407
|
}
|
|
5373
5408
|
resetActiveTurnState() {
|
|
@@ -5511,7 +5546,7 @@ var init_cli_state_engine = __esm({
|
|
|
5511
5546
|
"CLI",
|
|
5512
5547
|
`[${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)}`
|
|
5513
5548
|
);
|
|
5514
|
-
const shouldHoldGenerating = status === "idle" && this.isWaitingForResponse && !modal && recentInteractiveActivity && !(parsedStatus === "idle" && !!lastParsedAssistant);
|
|
5549
|
+
const shouldHoldGenerating = status === "idle" && this.isWaitingForResponse && !!this.currentTurnScope && !modal && recentInteractiveActivity && !(parsedStatus === "idle" && !!lastParsedAssistant);
|
|
5515
5550
|
if (shouldHoldGenerating) {
|
|
5516
5551
|
this.applyHoldGenerating(ctx);
|
|
5517
5552
|
return;
|
|
@@ -5607,19 +5642,30 @@ var init_cli_state_engine = __esm({
|
|
|
5607
5642
|
if (!inCooldown) {
|
|
5608
5643
|
if (!modal) {
|
|
5609
5644
|
LOG.warn("CLI", `[${this.provider.type}] detectStatus=waiting_approval but parseApproval returned null; ignoring`);
|
|
5645
|
+
if (this.currentStatus === "waiting_approval") {
|
|
5646
|
+
this.activeModal = null;
|
|
5647
|
+
this.setStatus("generating", "approval_lost_modal");
|
|
5648
|
+
this.callbacks.onStatusChange();
|
|
5649
|
+
}
|
|
5610
5650
|
return;
|
|
5611
5651
|
}
|
|
5612
5652
|
this.isWaitingForResponse = true;
|
|
5613
5653
|
this.setStatus("waiting_approval", "script_detect");
|
|
5614
|
-
this.activeModal
|
|
5654
|
+
const prev = this.activeModal;
|
|
5655
|
+
const prevBtnCount = Array.isArray(prev?.buttons) ? prev.buttons.length : 0;
|
|
5656
|
+
const nextBtnCount = Array.isArray(modal.buttons) ? modal.buttons.length : 0;
|
|
5657
|
+
if (!prev || prevBtnCount !== nextBtnCount) {
|
|
5658
|
+
this.activeModal = modal;
|
|
5659
|
+
this.callbacks.onStatusChange();
|
|
5660
|
+
}
|
|
5615
5661
|
if (this.idleTimeout) clearTimeout(this.idleTimeout);
|
|
5616
5662
|
this.armApprovalExitTimeout();
|
|
5617
|
-
this.callbacks.onStatusChange();
|
|
5618
5663
|
}
|
|
5619
5664
|
}
|
|
5620
5665
|
applyGenerating(ctx) {
|
|
5621
5666
|
const { modal, parsedMessages, lastParsedAssistant, parsedStatus, prevStatus } = ctx;
|
|
5622
5667
|
this.clearIdleFinishCandidate("generating");
|
|
5668
|
+
this.cancelPendingIdleFinish("generating_signal_returned");
|
|
5623
5669
|
const snap = this.transport.getSnapshot();
|
|
5624
5670
|
const effectiveScreenText = snap.screenText || snap.accumulatedBuffer;
|
|
5625
5671
|
const noActiveTurn = !this.currentTurnScope;
|
|
@@ -5780,10 +5826,27 @@ var init_cli_state_engine = __esm({
|
|
|
5780
5826
|
}
|
|
5781
5827
|
this.resetActiveTurnState();
|
|
5782
5828
|
this.callbacks.onTurnCompleted();
|
|
5783
|
-
this.
|
|
5784
|
-
this.callbacks.onStatusChange();
|
|
5829
|
+
this.scheduleIdleFinish("response_finished");
|
|
5785
5830
|
this.transport.flushOutboundQueue();
|
|
5786
5831
|
}
|
|
5832
|
+
scheduleIdleFinish(reason) {
|
|
5833
|
+
if (this.pendingIdleFinishTimer) clearTimeout(this.pendingIdleFinishTimer);
|
|
5834
|
+
this.pendingIdleFinishAt = Date.now() + IDLE_CONFIRMATION_GRACE_MS;
|
|
5835
|
+
this.pendingIdleFinishTimer = setTimeout(() => {
|
|
5836
|
+
this.pendingIdleFinishTimer = null;
|
|
5837
|
+
this.pendingIdleFinishAt = 0;
|
|
5838
|
+
if (this.isWaitingForResponse) return;
|
|
5839
|
+
this.setStatus("idle", reason);
|
|
5840
|
+
this.callbacks.onStatusChange();
|
|
5841
|
+
}, IDLE_CONFIRMATION_GRACE_MS);
|
|
5842
|
+
}
|
|
5843
|
+
cancelPendingIdleFinish(reason) {
|
|
5844
|
+
if (!this.pendingIdleFinishTimer) return;
|
|
5845
|
+
clearTimeout(this.pendingIdleFinishTimer);
|
|
5846
|
+
this.pendingIdleFinishTimer = null;
|
|
5847
|
+
this.pendingIdleFinishAt = 0;
|
|
5848
|
+
this.recordTrace("idle_finish_cancelled", { trigger: reason });
|
|
5849
|
+
}
|
|
5787
5850
|
// ─── Helpers ────────────────────────────────────────────────────────────
|
|
5788
5851
|
armApprovalExitTimeout() {
|
|
5789
5852
|
if (this.approvalExitTimeout) clearTimeout(this.approvalExitTimeout);
|
|
@@ -6219,9 +6282,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
6219
6282
|
submitRetryTimer = null;
|
|
6220
6283
|
// Resize redraw suppression
|
|
6221
6284
|
resizeSuppressUntil = 0;
|
|
6222
|
-
// Native transcript anchor
|
|
6223
|
-
//
|
|
6224
|
-
|
|
6285
|
+
// (A2.2) Native transcript anchor moved to CHAT_SOURCE_REGISTRY.
|
|
6286
|
+
// ChatSourceMachine holds the lock by state, not by a mutable field on
|
|
6287
|
+
// the adapter. Removed entirely; no callers remain after the readChat
|
|
6288
|
+
// ladder was replaced.
|
|
6225
6289
|
// ─── Script runner (parsing isolated here, adapter stays as transport) ───
|
|
6226
6290
|
runner;
|
|
6227
6291
|
/** @deprecated use runner.cliScripts for direct script access */
|
|
@@ -6557,6 +6621,8 @@ ${lastSnapshot}`;
|
|
|
6557
6621
|
this.engine.lastApprovalResolvedAt = Date.now();
|
|
6558
6622
|
}
|
|
6559
6623
|
this.engine.activeModal = null;
|
|
6624
|
+
this.engine.isWaitingForResponse = false;
|
|
6625
|
+
this.engine.currentTurnScope = null;
|
|
6560
6626
|
this.engine.setStatus("idle", `startup_ready:${trigger}`);
|
|
6561
6627
|
}
|
|
6562
6628
|
LOG.info(
|
|
@@ -6649,7 +6715,8 @@ ${lastSnapshot}`;
|
|
|
6649
6715
|
partialResponse: this.responseBuffer,
|
|
6650
6716
|
isWaitingForResponse: this.engine.isWaitingForResponse,
|
|
6651
6717
|
scope: this.engine.currentTurnScope,
|
|
6652
|
-
runtimeSettings: this.runtimeSettings
|
|
6718
|
+
runtimeSettings: this.runtimeSettings,
|
|
6719
|
+
spawnAt: this.spawnAt
|
|
6653
6720
|
});
|
|
6654
6721
|
const session = this.runner.parseSession({
|
|
6655
6722
|
...input,
|
|
@@ -6686,7 +6753,7 @@ ${lastSnapshot}`;
|
|
|
6686
6753
|
}
|
|
6687
6754
|
applyParsedSessionMetadata(parsed) {
|
|
6688
6755
|
const providerSessionId = typeof parsed?.providerSessionId === "string" && parsed.providerSessionId.trim() ? parsed.providerSessionId.trim() : "";
|
|
6689
|
-
if (providerSessionId) {
|
|
6756
|
+
if (providerSessionId && providerSessionId !== this.providerSessionId) {
|
|
6690
6757
|
this.providerSessionId = providerSessionId;
|
|
6691
6758
|
this.updateRuntimeMeta({ providerSessionId });
|
|
6692
6759
|
}
|
|
@@ -6704,7 +6771,25 @@ ${lastSnapshot}`;
|
|
|
6704
6771
|
const startupDetectedStatus = allowParse && this.startupParseGate && !startupModal ? this.runDetectStatus(this.recentOutputBuffer || this.terminalScreen.getText()) : null;
|
|
6705
6772
|
let effectiveStatus = this.projectEffectiveStatus(startupModal);
|
|
6706
6773
|
let effectiveModal = startupModal || this.engine.activeModal;
|
|
6707
|
-
if (
|
|
6774
|
+
if (allowParse && !effectiveModal && this.engine.isWaitingForResponse) {
|
|
6775
|
+
const liveDetect = this.runDetectStatus(this.recentOutputBuffer || this.terminalScreen.getText());
|
|
6776
|
+
if (liveDetect === "waiting_approval") {
|
|
6777
|
+
const liveModal = this.runParseApproval(this.terminalScreen.getText()) || this.runParseApproval(this.recentOutputBuffer);
|
|
6778
|
+
if (liveModal) {
|
|
6779
|
+
effectiveModal = liveModal;
|
|
6780
|
+
if (!this.engine.activeModal) this.engine.activeModal = liveModal;
|
|
6781
|
+
} else {
|
|
6782
|
+
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})`);
|
|
6783
|
+
}
|
|
6784
|
+
} else if (liveDetect && liveDetect !== "generating" && liveDetect !== "idle") {
|
|
6785
|
+
LOG.warn("CLI", `[${this.cliType}] getStatus live re-extract: detect=${liveDetect} (not waiting_approval)`);
|
|
6786
|
+
} else if (this.engine.currentStatus === "waiting_approval" && liveDetect !== "waiting_approval") {
|
|
6787
|
+
LOG.warn("CLI", `[${this.cliType}] getStatus live re-extract: engine.status=waiting_approval but live detect=${liveDetect}`);
|
|
6788
|
+
}
|
|
6789
|
+
} else if (!effectiveModal && this.engine.currentStatus === "waiting_approval") {
|
|
6790
|
+
LOG.warn("CLI", `[${this.cliType}] getStatus skipped live re-extract: allowParse=${allowParse} isWaitingForResponse=${this.engine.isWaitingForResponse}`);
|
|
6791
|
+
}
|
|
6792
|
+
if (startupDetectedStatus === "waiting_approval" && effectiveModal) {
|
|
6708
6793
|
effectiveStatus = "waiting_approval";
|
|
6709
6794
|
} else if (startupDetectedStatus === "idle" && !startupModal && !effectiveModal) {
|
|
6710
6795
|
effectiveStatus = "idle";
|
|
@@ -6806,7 +6891,8 @@ ${lastSnapshot}`;
|
|
|
6806
6891
|
partialResponse: this.responseBuffer,
|
|
6807
6892
|
isWaitingForResponse: this.engine.isWaitingForResponse,
|
|
6808
6893
|
scope: this.engine.currentTurnScope,
|
|
6809
|
-
runtimeSettings: this.runtimeSettings
|
|
6894
|
+
runtimeSettings: this.runtimeSettings,
|
|
6895
|
+
spawnAt: this.spawnAt
|
|
6810
6896
|
});
|
|
6811
6897
|
return await Promise.resolve(this.runner.invokeByName(scriptName, {
|
|
6812
6898
|
...input,
|
|
@@ -14577,19 +14663,37 @@ function getProviderNativeHistoryScript(scripts, canonicalHistory, key) {
|
|
|
14577
14663
|
function normalizeProviderNativeHistoryRecords(agentType, historySessionId, records) {
|
|
14578
14664
|
if (!Array.isArray(records)) return [];
|
|
14579
14665
|
const normalizedSessionId = normalizeSavedHistorySessionId(historySessionId);
|
|
14580
|
-
return records.map((record) =>
|
|
14581
|
-
|
|
14582
|
-
|
|
14583
|
-
|
|
14584
|
-
|
|
14585
|
-
|
|
14586
|
-
|
|
14587
|
-
|
|
14588
|
-
|
|
14589
|
-
|
|
14590
|
-
|
|
14591
|
-
|
|
14592
|
-
|
|
14666
|
+
return records.map((record) => {
|
|
14667
|
+
const base = {
|
|
14668
|
+
ts: typeof record?.ts === "string" ? record.ts : new Date(Number(record?.receivedAt) || Date.now()).toISOString(),
|
|
14669
|
+
receivedAt: Number(record?.receivedAt) || Date.parse(record?.ts || "") || Date.now(),
|
|
14670
|
+
role: record?.role,
|
|
14671
|
+
content: String(record?.content || ""),
|
|
14672
|
+
kind: record?.kind || (record?.role === "system" ? "session_start" : "standard"),
|
|
14673
|
+
senderName: record?.senderName,
|
|
14674
|
+
agent: agentType,
|
|
14675
|
+
instanceId: record?.instanceId,
|
|
14676
|
+
historySessionId: normalizeSavedHistorySessionId(record?.historySessionId || normalizedSessionId),
|
|
14677
|
+
sessionTitle: record?.sessionTitle,
|
|
14678
|
+
workspace: record?.workspace
|
|
14679
|
+
};
|
|
14680
|
+
if (typeof record?.providerUnitKey === "string" && record.providerUnitKey) {
|
|
14681
|
+
base.providerUnitKey = record.providerUnitKey;
|
|
14682
|
+
}
|
|
14683
|
+
if (typeof record?.bubbleId === "string" && record.bubbleId) {
|
|
14684
|
+
base.bubbleId = record.bubbleId;
|
|
14685
|
+
}
|
|
14686
|
+
if (typeof record?.sequence === "number" && Number.isFinite(record.sequence)) {
|
|
14687
|
+
base.sequence = record.sequence;
|
|
14688
|
+
}
|
|
14689
|
+
if (typeof record?._turnKey === "string" && record._turnKey) {
|
|
14690
|
+
base._turnKey = record._turnKey;
|
|
14691
|
+
}
|
|
14692
|
+
if (typeof record?.bubbleState === "string" && record.bubbleState) {
|
|
14693
|
+
base.bubbleState = record.bubbleState;
|
|
14694
|
+
}
|
|
14695
|
+
return sanitizeHistoryMessage(agentType, base);
|
|
14696
|
+
}).filter(Boolean);
|
|
14593
14697
|
}
|
|
14594
14698
|
function callProviderNativeHistoryRead(agentType, canonicalHistory, scripts, historySessionId, workspace, excludeInProgressTurn) {
|
|
14595
14699
|
const fn = getProviderNativeHistoryScript(scripts, canonicalHistory, "readSession");
|
|
@@ -15254,6 +15358,9 @@ ${effect.notification.body || ""}`.trim();
|
|
|
15254
15358
|
// src/providers/ide-provider-instance.ts
|
|
15255
15359
|
init_logger();
|
|
15256
15360
|
|
|
15361
|
+
// src/providers/transcript-v2.ts
|
|
15362
|
+
var CHAT_CONTRACT_VERSION_V1 = "1.0";
|
|
15363
|
+
|
|
15257
15364
|
// src/providers/read-chat-contract.ts
|
|
15258
15365
|
var VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "starting", "streaming", "long_generating"];
|
|
15259
15366
|
var VALID_ROLES = ["user", "assistant", "system", "human"];
|
|
@@ -15310,6 +15417,7 @@ function validateMessage(message, source, index) {
|
|
|
15310
15417
|
if (isFiniteNumber(message.index)) normalized.index = message.index;
|
|
15311
15418
|
if (isFiniteNumber(message.timestamp)) normalized.timestamp = message.timestamp;
|
|
15312
15419
|
if (isFiniteNumber(message.receivedAt)) normalized.receivedAt = message.receivedAt;
|
|
15420
|
+
if (isFiniteNumber(message.sequence)) normalized.sequence = message.sequence;
|
|
15313
15421
|
if (typeof message._turnKey === "string") normalized._turnKey = message._turnKey;
|
|
15314
15422
|
if (Array.isArray(message.toolCalls)) normalized.toolCalls = message.toolCalls;
|
|
15315
15423
|
if (isPlainObject3(message.meta)) normalized.meta = message.meta;
|
|
@@ -17241,12 +17349,365 @@ function buildSessionModalDeliverySignature(payload) {
|
|
|
17241
17349
|
]);
|
|
17242
17350
|
}
|
|
17243
17351
|
|
|
17352
|
+
// src/chat/source-machine.ts
|
|
17353
|
+
var INITIAL_CHAT_SOURCE_STATE = Object.freeze({
|
|
17354
|
+
name: "Booting",
|
|
17355
|
+
nativeSequencePeak: void 0,
|
|
17356
|
+
committedUnitKeys: Object.freeze(/* @__PURE__ */ new Set()),
|
|
17357
|
+
recoveringMisses: 0
|
|
17358
|
+
});
|
|
17359
|
+
var RECOVERING_MISS_PROMOTION_THRESHOLD = 3;
|
|
17360
|
+
function transitionChatSourceState(prev, observation, at, lockedSince) {
|
|
17361
|
+
const fromState = prev.name;
|
|
17362
|
+
if (observation.kind === "native_unavailable") {
|
|
17363
|
+
return handleNativeUnavailable(prev, observation.reason, at, lockedSince);
|
|
17364
|
+
}
|
|
17365
|
+
return handleNativePresent(prev, observation, at, lockedSince, fromState);
|
|
17366
|
+
}
|
|
17367
|
+
function handleNativeUnavailable(prev, reason, at, lockedSince) {
|
|
17368
|
+
const cause = reasonToUnavailableCause(reason);
|
|
17369
|
+
const fromState = prev.name;
|
|
17370
|
+
if (prev.name === "Booting") {
|
|
17371
|
+
const next2 = {
|
|
17372
|
+
name: "PtyOnly",
|
|
17373
|
+
nativeSequencePeak: void 0,
|
|
17374
|
+
committedUnitKeys: prev.committedUnitKeys,
|
|
17375
|
+
recoveringMisses: 0
|
|
17376
|
+
};
|
|
17377
|
+
return {
|
|
17378
|
+
next: next2,
|
|
17379
|
+
selected: "pty-parser",
|
|
17380
|
+
transition: { fromState, toState: "PtyOnly", event: "NativeUnavailable", cause, at },
|
|
17381
|
+
lockState: { locked: false }
|
|
17382
|
+
};
|
|
17383
|
+
}
|
|
17384
|
+
if (prev.name === "PtyOnly") {
|
|
17385
|
+
return {
|
|
17386
|
+
next: prev,
|
|
17387
|
+
selected: "pty-parser",
|
|
17388
|
+
transition: { fromState, toState: "PtyOnly", event: "NoOp", cause, at },
|
|
17389
|
+
lockState: { locked: false }
|
|
17390
|
+
};
|
|
17391
|
+
}
|
|
17392
|
+
if (prev.name === "NativeLocked") {
|
|
17393
|
+
const next2 = {
|
|
17394
|
+
name: "Recovering",
|
|
17395
|
+
nativeSequencePeak: prev.nativeSequencePeak,
|
|
17396
|
+
committedUnitKeys: prev.committedUnitKeys,
|
|
17397
|
+
recoveringMisses: 1
|
|
17398
|
+
};
|
|
17399
|
+
return {
|
|
17400
|
+
next: next2,
|
|
17401
|
+
selected: "pty-parser",
|
|
17402
|
+
transition: { fromState, toState: "Recovering", event: "NativeUnavailable", cause, at },
|
|
17403
|
+
lockState: { locked: false }
|
|
17404
|
+
};
|
|
17405
|
+
}
|
|
17406
|
+
const misses = prev.recoveringMisses + 1;
|
|
17407
|
+
if (misses >= RECOVERING_MISS_PROMOTION_THRESHOLD) {
|
|
17408
|
+
const next2 = {
|
|
17409
|
+
name: "PtyOnly",
|
|
17410
|
+
nativeSequencePeak: prev.nativeSequencePeak,
|
|
17411
|
+
committedUnitKeys: prev.committedUnitKeys,
|
|
17412
|
+
recoveringMisses: 0
|
|
17413
|
+
};
|
|
17414
|
+
return {
|
|
17415
|
+
next: next2,
|
|
17416
|
+
selected: "pty-parser",
|
|
17417
|
+
transition: { fromState, toState: "PtyOnly", event: "NativeUnavailable", cause, at },
|
|
17418
|
+
lockState: { locked: false }
|
|
17419
|
+
};
|
|
17420
|
+
}
|
|
17421
|
+
const next = {
|
|
17422
|
+
name: "Recovering",
|
|
17423
|
+
nativeSequencePeak: prev.nativeSequencePeak,
|
|
17424
|
+
committedUnitKeys: prev.committedUnitKeys,
|
|
17425
|
+
recoveringMisses: misses
|
|
17426
|
+
};
|
|
17427
|
+
return {
|
|
17428
|
+
next,
|
|
17429
|
+
selected: "pty-parser",
|
|
17430
|
+
transition: { fromState, toState: "Recovering", event: "NoOp", cause, at },
|
|
17431
|
+
lockState: { locked: false }
|
|
17432
|
+
};
|
|
17433
|
+
}
|
|
17434
|
+
function handleNativePresent(prev, observation, at, lockedSince, fromState) {
|
|
17435
|
+
if (!observation.safeMapping) {
|
|
17436
|
+
return regressTo(prev, fromState, "native_regressed_unsafe_mapping", at);
|
|
17437
|
+
}
|
|
17438
|
+
if (observation.coverage === "partial" && observation.messages.length === 0) {
|
|
17439
|
+
return regressTo(prev, fromState, "native_regressed_coverage_partial", at);
|
|
17440
|
+
}
|
|
17441
|
+
if (observation.messages.length === 0) {
|
|
17442
|
+
return handleNativeUnavailable(prev, "empty", at, lockedSince);
|
|
17443
|
+
}
|
|
17444
|
+
const incomingUnitKeys = collectUnitKeys(observation.messages);
|
|
17445
|
+
const incomingPeak = maxSequence(observation.messages);
|
|
17446
|
+
if (prev.name === "Booting") {
|
|
17447
|
+
if (observation.coverage === "partial") {
|
|
17448
|
+
const next2 = {
|
|
17449
|
+
name: "Recovering",
|
|
17450
|
+
nativeSequencePeak: incomingPeak,
|
|
17451
|
+
committedUnitKeys: incomingUnitKeys,
|
|
17452
|
+
recoveringMisses: 0
|
|
17453
|
+
};
|
|
17454
|
+
return {
|
|
17455
|
+
next: next2,
|
|
17456
|
+
selected: "pty-parser",
|
|
17457
|
+
transition: { fromState, toState: "Recovering", event: "NativeProgressed", cause: "native_progressed", at },
|
|
17458
|
+
lockState: { locked: false }
|
|
17459
|
+
};
|
|
17460
|
+
}
|
|
17461
|
+
const next = {
|
|
17462
|
+
name: "NativeLocked",
|
|
17463
|
+
nativeSequencePeak: incomingPeak,
|
|
17464
|
+
committedUnitKeys: incomingUnitKeys,
|
|
17465
|
+
recoveringMisses: 0
|
|
17466
|
+
};
|
|
17467
|
+
return {
|
|
17468
|
+
next,
|
|
17469
|
+
selected: "native-history",
|
|
17470
|
+
transition: { fromState, toState: "NativeLocked", event: "NativeProgressed", cause: "native_progressed", at },
|
|
17471
|
+
lockState: { locked: true, lockedSince: at }
|
|
17472
|
+
};
|
|
17473
|
+
}
|
|
17474
|
+
if (prev.name === "NativeLocked") {
|
|
17475
|
+
if (!isSupersetOf(incomingUnitKeys, prev.committedUnitKeys)) {
|
|
17476
|
+
return regressTo(prev, fromState, "native_regressed_shrunk", at);
|
|
17477
|
+
}
|
|
17478
|
+
if (prev.nativeSequencePeak !== void 0 && incomingPeak < prev.nativeSequencePeak) {
|
|
17479
|
+
return regressTo(prev, fromState, "native_regressed_shrunk", at);
|
|
17480
|
+
}
|
|
17481
|
+
const next = {
|
|
17482
|
+
name: "NativeLocked",
|
|
17483
|
+
nativeSequencePeak: Math.max(prev.nativeSequencePeak ?? incomingPeak, incomingPeak),
|
|
17484
|
+
committedUnitKeys: incomingUnitKeys,
|
|
17485
|
+
recoveringMisses: 0
|
|
17486
|
+
};
|
|
17487
|
+
return {
|
|
17488
|
+
next,
|
|
17489
|
+
selected: "native-history",
|
|
17490
|
+
transition: { fromState, toState: "NativeLocked", event: "NoOp", cause: "native_progressed", at },
|
|
17491
|
+
lockState: { locked: true, lockedSince: lockedSince ?? at }
|
|
17492
|
+
};
|
|
17493
|
+
}
|
|
17494
|
+
if (prev.name === "Recovering") {
|
|
17495
|
+
const meetsWatermark = prev.nativeSequencePeak === void 0 || incomingPeak >= prev.nativeSequencePeak;
|
|
17496
|
+
if (meetsWatermark && isSupersetOf(incomingUnitKeys, prev.committedUnitKeys) && observation.coverage !== "partial") {
|
|
17497
|
+
const next = {
|
|
17498
|
+
name: "NativeLocked",
|
|
17499
|
+
nativeSequencePeak: Math.max(prev.nativeSequencePeak ?? incomingPeak, incomingPeak),
|
|
17500
|
+
committedUnitKeys: incomingUnitKeys,
|
|
17501
|
+
recoveringMisses: 0
|
|
17502
|
+
};
|
|
17503
|
+
return {
|
|
17504
|
+
next,
|
|
17505
|
+
selected: "native-history",
|
|
17506
|
+
transition: { fromState, toState: "NativeLocked", event: "NativeProgressed", cause: "native_progressed", at },
|
|
17507
|
+
lockState: { locked: true, lockedSince: at }
|
|
17508
|
+
};
|
|
17509
|
+
}
|
|
17510
|
+
return handleNativeUnavailable(prev, "empty", at, lockedSince);
|
|
17511
|
+
}
|
|
17512
|
+
if (prev.nativeSequencePeak === void 0 || incomingPeak > prev.nativeSequencePeak) {
|
|
17513
|
+
if (observation.coverage !== "partial" && incomingUnitKeys.size > 0) {
|
|
17514
|
+
const next = {
|
|
17515
|
+
name: "NativeLocked",
|
|
17516
|
+
nativeSequencePeak: Math.max(prev.nativeSequencePeak ?? incomingPeak, incomingPeak),
|
|
17517
|
+
committedUnitKeys: incomingUnitKeys,
|
|
17518
|
+
recoveringMisses: 0
|
|
17519
|
+
};
|
|
17520
|
+
return {
|
|
17521
|
+
next,
|
|
17522
|
+
selected: "native-history",
|
|
17523
|
+
transition: { fromState, toState: "NativeLocked", event: "NativeProgressed", cause: "native_progressed", at },
|
|
17524
|
+
lockState: { locked: true, lockedSince: at }
|
|
17525
|
+
};
|
|
17526
|
+
}
|
|
17527
|
+
} else if (incomingPeak >= prev.nativeSequencePeak) {
|
|
17528
|
+
if (isSupersetOf(incomingUnitKeys, prev.committedUnitKeys) && observation.coverage !== "partial") {
|
|
17529
|
+
const next = {
|
|
17530
|
+
name: "NativeLocked",
|
|
17531
|
+
nativeSequencePeak: Math.max(prev.nativeSequencePeak ?? incomingPeak, incomingPeak),
|
|
17532
|
+
committedUnitKeys: incomingUnitKeys,
|
|
17533
|
+
recoveringMisses: 0
|
|
17534
|
+
};
|
|
17535
|
+
return {
|
|
17536
|
+
next,
|
|
17537
|
+
selected: "native-history",
|
|
17538
|
+
transition: { fromState, toState: "NativeLocked", event: "NativeProgressed", cause: "native_progressed", at },
|
|
17539
|
+
lockState: { locked: true, lockedSince: at }
|
|
17540
|
+
};
|
|
17541
|
+
}
|
|
17542
|
+
}
|
|
17543
|
+
return {
|
|
17544
|
+
next: prev,
|
|
17545
|
+
selected: "pty-parser",
|
|
17546
|
+
transition: { fromState, toState: "PtyOnly", event: "NoOp", cause: "native_progressed", at },
|
|
17547
|
+
lockState: { locked: false }
|
|
17548
|
+
};
|
|
17549
|
+
}
|
|
17550
|
+
function regressTo(prev, fromState, cause, at) {
|
|
17551
|
+
const next = {
|
|
17552
|
+
name: "PtyOnly",
|
|
17553
|
+
nativeSequencePeak: prev.nativeSequencePeak,
|
|
17554
|
+
committedUnitKeys: prev.committedUnitKeys,
|
|
17555
|
+
recoveringMisses: 0
|
|
17556
|
+
};
|
|
17557
|
+
return {
|
|
17558
|
+
next,
|
|
17559
|
+
selected: "pty-parser",
|
|
17560
|
+
transition: { fromState, toState: "PtyOnly", event: "NativeRegressed", cause, at },
|
|
17561
|
+
lockState: { locked: false }
|
|
17562
|
+
};
|
|
17563
|
+
}
|
|
17564
|
+
function reasonToUnavailableCause(reason) {
|
|
17565
|
+
switch (reason) {
|
|
17566
|
+
case "provider_not_supported":
|
|
17567
|
+
return "native_unavailable_provider_unsupported";
|
|
17568
|
+
case "read_error":
|
|
17569
|
+
return "native_unavailable_read_error";
|
|
17570
|
+
case "empty":
|
|
17571
|
+
return "native_unavailable_empty";
|
|
17572
|
+
case "not_native_source":
|
|
17573
|
+
return "native_unavailable_not_native_source";
|
|
17574
|
+
case "coverage_unavailable":
|
|
17575
|
+
return "native_regressed_coverage_unavailable";
|
|
17576
|
+
}
|
|
17577
|
+
}
|
|
17578
|
+
function collectUnitKeys(messages) {
|
|
17579
|
+
const set = /* @__PURE__ */ new Set();
|
|
17580
|
+
for (const m of messages) set.add(m.providerUnitKey);
|
|
17581
|
+
return set;
|
|
17582
|
+
}
|
|
17583
|
+
function maxSequence(messages) {
|
|
17584
|
+
let max = -Infinity;
|
|
17585
|
+
for (const m of messages) {
|
|
17586
|
+
if (m.sequence > max) max = m.sequence;
|
|
17587
|
+
}
|
|
17588
|
+
return max === -Infinity ? 0 : max;
|
|
17589
|
+
}
|
|
17590
|
+
function isSupersetOf(candidate, required) {
|
|
17591
|
+
if (required.size === 0) return true;
|
|
17592
|
+
for (const key of required) {
|
|
17593
|
+
if (!candidate.has(key)) return false;
|
|
17594
|
+
}
|
|
17595
|
+
return true;
|
|
17596
|
+
}
|
|
17597
|
+
|
|
17598
|
+
// src/chat/source-resolver.ts
|
|
17599
|
+
var TRANSITION_HISTORY_LIMIT = 25;
|
|
17600
|
+
function chatSourceSessionKey(providerType, sessionId) {
|
|
17601
|
+
return `${providerType}\0${sessionId}`;
|
|
17602
|
+
}
|
|
17603
|
+
var ChatSourceRegistry = class {
|
|
17604
|
+
records = /* @__PURE__ */ new Map();
|
|
17605
|
+
/** Snapshot of current state for diagnostics. Does not mutate. */
|
|
17606
|
+
getState(key) {
|
|
17607
|
+
return this.records.get(key)?.state ?? INITIAL_CHAT_SOURCE_STATE;
|
|
17608
|
+
}
|
|
17609
|
+
/** Recent transitions, newest last. Empty array when nothing has happened. */
|
|
17610
|
+
getTransitions(key) {
|
|
17611
|
+
return this.records.get(key)?.transitions ?? [];
|
|
17612
|
+
}
|
|
17613
|
+
/** Drop a session. Caller should invoke this when the session is destroyed
|
|
17614
|
+
* to avoid unbounded growth across long-lived daemons. */
|
|
17615
|
+
clear(key) {
|
|
17616
|
+
this.records.delete(key);
|
|
17617
|
+
}
|
|
17618
|
+
/** Drop all sessions. Test helper. */
|
|
17619
|
+
clearAll() {
|
|
17620
|
+
this.records.clear();
|
|
17621
|
+
}
|
|
17622
|
+
/**
|
|
17623
|
+
* Apply one observation, returning the decision and side-effecting the
|
|
17624
|
+
* stored state. The returned `nextState` is the same object now stored
|
|
17625
|
+
* under `key`; callers may treat the decision as authoritative without
|
|
17626
|
+
* re-reading.
|
|
17627
|
+
*/
|
|
17628
|
+
observe(key, observation, at = Date.now()) {
|
|
17629
|
+
const prev = this.records.get(key);
|
|
17630
|
+
const prevState = prev?.state ?? INITIAL_CHAT_SOURCE_STATE;
|
|
17631
|
+
const prevLockedSince = prev?.lockedSince;
|
|
17632
|
+
const result = transitionChatSourceState(prevState, observation, at, prevLockedSince);
|
|
17633
|
+
const transitions = prev?.transitions ?? [];
|
|
17634
|
+
const nextTransitions = appendTransition(transitions, result.transition);
|
|
17635
|
+
const lockedSince = result.lockState.lockedSince;
|
|
17636
|
+
this.records.set(key, {
|
|
17637
|
+
state: result.next,
|
|
17638
|
+
lockedSince,
|
|
17639
|
+
transitions: nextTransitions
|
|
17640
|
+
});
|
|
17641
|
+
return {
|
|
17642
|
+
selected: result.selected,
|
|
17643
|
+
nextState: result.next,
|
|
17644
|
+
transition: result.transition,
|
|
17645
|
+
lockState: result.lockState
|
|
17646
|
+
};
|
|
17647
|
+
}
|
|
17648
|
+
};
|
|
17649
|
+
function appendTransition(existing, next) {
|
|
17650
|
+
const last = existing[existing.length - 1];
|
|
17651
|
+
if (last && last.fromState === next.fromState && last.toState === next.toState && last.event === next.event && last.cause === next.cause) {
|
|
17652
|
+
return existing;
|
|
17653
|
+
}
|
|
17654
|
+
const trimmed = existing.length >= TRANSITION_HISTORY_LIMIT ? existing.slice(existing.length - TRANSITION_HISTORY_LIMIT + 1) : [...existing];
|
|
17655
|
+
trimmed.push(next);
|
|
17656
|
+
return trimmed;
|
|
17657
|
+
}
|
|
17658
|
+
function buildV1NativePresentObservation(args) {
|
|
17659
|
+
const identities = [];
|
|
17660
|
+
let synthesisedSequence = 0;
|
|
17661
|
+
for (const message of args.messages) {
|
|
17662
|
+
const providerUnitKey = pickFirstString(
|
|
17663
|
+
message.providerUnitKey,
|
|
17664
|
+
message.bubbleId,
|
|
17665
|
+
message.id
|
|
17666
|
+
) ?? synthesiseV1UnitKey(args.providerType, args.sessionId, synthesisedSequence, message);
|
|
17667
|
+
const sequence = pickFiniteNumber(message.receivedAt, message.timestamp, message.index) ?? synthesisedSequence;
|
|
17668
|
+
identities.push({ providerUnitKey, sequence });
|
|
17669
|
+
synthesisedSequence += 1;
|
|
17670
|
+
}
|
|
17671
|
+
return {
|
|
17672
|
+
kind: "native_present",
|
|
17673
|
+
contractVersion: CHAT_CONTRACT_VERSION_V1,
|
|
17674
|
+
messages: identities,
|
|
17675
|
+
coverage: args.coverage,
|
|
17676
|
+
safeMapping: args.safeMapping
|
|
17677
|
+
};
|
|
17678
|
+
}
|
|
17679
|
+
function pickFirstString(...candidates) {
|
|
17680
|
+
for (const c of candidates) {
|
|
17681
|
+
if (typeof c === "string" && c.length > 0) return c;
|
|
17682
|
+
}
|
|
17683
|
+
return void 0;
|
|
17684
|
+
}
|
|
17685
|
+
function pickFiniteNumber(...candidates) {
|
|
17686
|
+
for (const c of candidates) {
|
|
17687
|
+
if (typeof c === "number" && Number.isFinite(c)) return c;
|
|
17688
|
+
}
|
|
17689
|
+
return void 0;
|
|
17690
|
+
}
|
|
17691
|
+
function synthesiseV1UnitKey(providerType, sessionId, positionalSeq, message) {
|
|
17692
|
+
const role = typeof message.role === "string" ? message.role : "";
|
|
17693
|
+
const ts2 = pickFiniteNumber(message.receivedAt, message.timestamp);
|
|
17694
|
+
return `v1:${providerType}:${sessionId}:${ts2 ?? ""}:${positionalSeq}:${role}`;
|
|
17695
|
+
}
|
|
17696
|
+
var CHAT_SOURCE_REGISTRY = new ChatSourceRegistry();
|
|
17697
|
+
|
|
17244
17698
|
// src/commands/chat-commands.ts
|
|
17245
17699
|
var RECENT_SEND_WINDOW_MS = 1200;
|
|
17246
17700
|
var READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS = 25e3;
|
|
17247
17701
|
var HERMES_CLI_STARTING_SEND_SETTLE_MS = 2e3;
|
|
17248
|
-
var CLI_NATIVE_HISTORY_FRESH_MS = 5 * 6e4;
|
|
17249
17702
|
var CLI_NATIVE_TRANSCRIPT_PROVIDERS = /* @__PURE__ */ new Set(["codex-cli", "claude-cli", "hermes-cli", "antigravity-cli"]);
|
|
17703
|
+
var warnedLegacyNativeAllowlistHits = /* @__PURE__ */ new Set();
|
|
17704
|
+
function warnLegacyNativeAllowlistHit(providerType) {
|
|
17705
|
+
if (warnedLegacyNativeAllowlistHits.has(providerType)) return;
|
|
17706
|
+
warnedLegacyNativeAllowlistHits.add(providerType);
|
|
17707
|
+
console.warn(
|
|
17708
|
+
`[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.`
|
|
17709
|
+
);
|
|
17710
|
+
}
|
|
17250
17711
|
var recentSendByTarget = /* @__PURE__ */ new Map();
|
|
17251
17712
|
function getCurrentProviderType(h, fallback = "") {
|
|
17252
17713
|
return h.currentSession?.providerType || h.currentProviderType || fallback;
|
|
@@ -17421,7 +17882,11 @@ function readHistorySessionIdFromMessages(messages) {
|
|
|
17421
17882
|
function shouldPreserveNativeIdentity(providerType, sessionId, message) {
|
|
17422
17883
|
const providerUnitKey = typeof message.providerUnitKey === "string" ? message.providerUnitKey.trim() : "";
|
|
17423
17884
|
const turnKey = typeof message._turnKey === "string" ? message._turnKey.trim() : "";
|
|
17424
|
-
if (!providerUnitKey
|
|
17885
|
+
if (!providerUnitKey) return false;
|
|
17886
|
+
if (providerUnitKey.startsWith("v2:") || providerUnitKey.startsWith("v2-pty:")) {
|
|
17887
|
+
return true;
|
|
17888
|
+
}
|
|
17889
|
+
if (!turnKey) return false;
|
|
17425
17890
|
if (providerType === "hermes-cli" && sessionId) {
|
|
17426
17891
|
return providerUnitKey.startsWith(`${providerType}:native:${sessionId}:`) && turnKey.startsWith(`${providerType}:native-turn:${sessionId}:`);
|
|
17427
17892
|
}
|
|
@@ -17450,12 +17915,16 @@ function normalizeNativeHistoryMessages(providerType, messages, nativeSessionId)
|
|
|
17450
17915
|
const meta = message.meta && typeof message.meta === "object" ? message.meta : void 0;
|
|
17451
17916
|
const isSystemSessionStart = role === "system" || kind === "system" || kind === "session_start";
|
|
17452
17917
|
const isActivity = role === "assistant" && (kind === "tool" || kind === "terminal" || kind === "thought");
|
|
17918
|
+
const existingSequence = typeof message.sequence === "number" && Number.isFinite(message.sequence) ? message.sequence : null;
|
|
17919
|
+
const tsCandidate = Number(message.receivedAt || message.timestamp || 0);
|
|
17920
|
+
const sequence = existingSequence !== null ? existingSequence : tsCandidate > 0 ? tsCandidate : index;
|
|
17453
17921
|
return {
|
|
17454
17922
|
...message,
|
|
17455
17923
|
role: role === "human" ? "user" : role || "assistant",
|
|
17456
17924
|
kind: isSystemSessionStart ? "system" : kind,
|
|
17457
17925
|
providerUnitKey,
|
|
17458
17926
|
bubbleId: typeof message.bubbleId === "string" && message.bubbleId.trim() && preserveNativeIdentity ? message.bubbleId.trim() : `bubble:${providerUnitKey}`,
|
|
17927
|
+
sequence,
|
|
17459
17928
|
_turnKey: preserveNativeIdentity ? existingTurnKey : `${providerType}:native-turn:${nativeIdentitySessionId || "workspace"}:${turnIndex}`,
|
|
17460
17929
|
bubbleState: message.bubbleState || "final",
|
|
17461
17930
|
...isSystemSessionStart ? {
|
|
@@ -17514,17 +17983,185 @@ function buildCliMessageSourceProvenance(args) {
|
|
|
17514
17983
|
}
|
|
17515
17984
|
};
|
|
17516
17985
|
}
|
|
17517
|
-
function
|
|
17518
|
-
if (
|
|
17519
|
-
|
|
17520
|
-
|
|
17521
|
-
|
|
17522
|
-
|
|
17523
|
-
|
|
17524
|
-
|
|
17525
|
-
|
|
17526
|
-
|
|
17527
|
-
|
|
17986
|
+
function causeToLegacyFallbackReason(cause, selected, extraDetail) {
|
|
17987
|
+
if (selected === "native-history") return void 0;
|
|
17988
|
+
switch (cause) {
|
|
17989
|
+
case "initial":
|
|
17990
|
+
return "native_history_not_checked";
|
|
17991
|
+
case "native_progressed":
|
|
17992
|
+
return "native_history_not_selected";
|
|
17993
|
+
case "native_regressed_shrunk":
|
|
17994
|
+
return "native_history_empty";
|
|
17995
|
+
case "native_regressed_unsafe_mapping":
|
|
17996
|
+
return "native_history_not_safely_mapped";
|
|
17997
|
+
case "native_regressed_coverage_partial":
|
|
17998
|
+
return "native_history_partial";
|
|
17999
|
+
case "native_regressed_coverage_unavailable":
|
|
18000
|
+
return "native_history_unavailable";
|
|
18001
|
+
case "native_unavailable_read_error":
|
|
18002
|
+
return extraDetail?.unavailableReason ? `native_history_unavailable:${extraDetail.unavailableReason}` : "native_history_unavailable";
|
|
18003
|
+
case "native_unavailable_provider_unsupported":
|
|
18004
|
+
return "provider_native_transcript_not_supported";
|
|
18005
|
+
case "native_unavailable_empty":
|
|
18006
|
+
return "native_history_empty";
|
|
18007
|
+
case "native_unavailable_not_native_source":
|
|
18008
|
+
return extraDetail?.nativeSource ? `native_history_source_${extraDetail.nativeSource}` : "native_history_unavailable";
|
|
18009
|
+
}
|
|
18010
|
+
}
|
|
18011
|
+
function decideCliReadChatSource(args) {
|
|
18012
|
+
const supportsNative = supportsCliNativeTranscript(args.providerType, args.provider);
|
|
18013
|
+
const observation = buildObservationForCli(args, supportsNative);
|
|
18014
|
+
const sessionKey = chatSourceSessionKey(args.providerType, args.sessionId);
|
|
18015
|
+
const decision = CHAT_SOURCE_REGISTRY.observe(sessionKey, observation);
|
|
18016
|
+
const nativeMessages = observation.kind === "native_present" ? extractNativeMessagesFromResult(args.providerType, args.nativeHistoryResult) : [];
|
|
18017
|
+
const nativeSource = typeof args.nativeHistoryResult?.source === "string" ? args.nativeHistoryResult.source : void 0;
|
|
18018
|
+
const sourcePath = typeof args.nativeHistoryResult?.sourcePath === "string" ? args.nativeHistoryResult.sourcePath : void 0;
|
|
18019
|
+
const sourceMtimeMs = typeof args.nativeHistoryResult?.sourceMtimeMs === "number" ? args.nativeHistoryResult.sourceMtimeMs : void 0;
|
|
18020
|
+
const coverageHint = typeof args.nativeHistoryResult?.nativeHistoryCoverage === "string" ? args.nativeHistoryResult.nativeHistoryCoverage : void 0;
|
|
18021
|
+
const partialReason = typeof args.nativeHistoryResult?.partialReason === "string" ? args.nativeHistoryResult.partialReason : void 0;
|
|
18022
|
+
const unavailableReason = typeof args.nativeHistoryResult?.unavailableReason === "string" ? args.nativeHistoryResult.unavailableReason : args.nativeHistoryError ? `error:${args.nativeHistoryError?.message || String(args.nativeHistoryError)}` : void 0;
|
|
18023
|
+
const nativeHandle = typeof args.nativeHistoryResult?.providerSessionId === "string" ? args.nativeHistoryResult.providerSessionId : void 0;
|
|
18024
|
+
const transcriptWorkspace = typeof args.nativeHistoryResult?.workspace === "string" ? args.nativeHistoryResult.workspace : nativeMessages.map((m) => typeof m?.workspace === "string" ? m.workspace.trim() : "").find(Boolean);
|
|
18025
|
+
const fallbackReason = causeToLegacyFallbackReason(decision.transition.cause, decision.selected, {
|
|
18026
|
+
unavailableReason,
|
|
18027
|
+
nativeSource: nativeSource && nativeSource !== "provider-native" ? nativeSource : void 0
|
|
18028
|
+
});
|
|
18029
|
+
const ptyStatusApprovalOnly = decision.selected === "native-history" ? true : args.ptyStatusApprovalOnly;
|
|
18030
|
+
const messageSource = buildCliMessageSourceProvenance({
|
|
18031
|
+
selected: decision.selected,
|
|
18032
|
+
provider: args.providerType,
|
|
18033
|
+
nativeHandle,
|
|
18034
|
+
sessionWorkspace: args.sessionWorkspace,
|
|
18035
|
+
intendedWorkspace: args.intendedWorkspace,
|
|
18036
|
+
transcriptWorkspace,
|
|
18037
|
+
fallbackReason,
|
|
18038
|
+
nativeSource,
|
|
18039
|
+
sourcePath,
|
|
18040
|
+
sourceMtimeMs,
|
|
18041
|
+
nativeHistoryCoverage: coverageHint,
|
|
18042
|
+
partialReason,
|
|
18043
|
+
unavailableReason,
|
|
18044
|
+
nativeMessages,
|
|
18045
|
+
ptyMessages: args.ptyMessages,
|
|
18046
|
+
returnedMessages: decision.selected === "native-history" ? nativeMessages : args.ptyMessages,
|
|
18047
|
+
safeMapping: args.safeMapping,
|
|
18048
|
+
// freshEnough is a v1 concept the machine does not model directly.
|
|
18049
|
+
// We surface lockState.locked here so v1 consumers reading
|
|
18050
|
+
// staleness.freshEnough still get a meaningful boolean.
|
|
18051
|
+
freshEnough: decision.lockState.locked,
|
|
18052
|
+
ptyStatusApprovalOnly
|
|
18053
|
+
});
|
|
18054
|
+
return {
|
|
18055
|
+
decision,
|
|
18056
|
+
messageSource,
|
|
18057
|
+
nativeMessages,
|
|
18058
|
+
nativeSelected: decision.selected === "native-history"
|
|
18059
|
+
};
|
|
18060
|
+
}
|
|
18061
|
+
function buildObservationForCli(args, supportsNative) {
|
|
18062
|
+
if (!supportsNative) {
|
|
18063
|
+
return { kind: "native_unavailable", reason: "provider_not_supported" };
|
|
18064
|
+
}
|
|
18065
|
+
if (args.nativeHistoryError) {
|
|
18066
|
+
return { kind: "native_unavailable", reason: "read_error" };
|
|
18067
|
+
}
|
|
18068
|
+
const result = args.nativeHistoryResult;
|
|
18069
|
+
if (!result || typeof result !== "object") {
|
|
18070
|
+
return { kind: "native_unavailable", reason: "read_error" };
|
|
18071
|
+
}
|
|
18072
|
+
const source = typeof result.source === "string" ? result.source : "";
|
|
18073
|
+
if (source && source !== "provider-native") {
|
|
18074
|
+
return { kind: "native_unavailable", reason: source === "native-unavailable" ? "empty" : "not_native_source" };
|
|
18075
|
+
}
|
|
18076
|
+
const messages = Array.isArray(result.messages) ? result.messages : [];
|
|
18077
|
+
if (messages.length === 0) {
|
|
18078
|
+
return { kind: "native_unavailable", reason: "empty" };
|
|
18079
|
+
}
|
|
18080
|
+
const coverage = typeof result.nativeHistoryCoverage === "string" ? result.nativeHistoryCoverage : "tail";
|
|
18081
|
+
if (coverage === "unavailable") {
|
|
18082
|
+
return { kind: "native_unavailable", reason: "coverage_unavailable" };
|
|
18083
|
+
}
|
|
18084
|
+
return buildV1NativePresentObservation({
|
|
18085
|
+
providerType: args.providerType,
|
|
18086
|
+
sessionId: args.sessionId,
|
|
18087
|
+
messages,
|
|
18088
|
+
coverage: coverage === "full" || coverage === "tail" || coverage === "current-turn" || coverage === "partial" ? coverage : "tail",
|
|
18089
|
+
safeMapping: args.safeMapping
|
|
18090
|
+
});
|
|
18091
|
+
}
|
|
18092
|
+
function extractNativeMessagesFromResult(providerType, result) {
|
|
18093
|
+
if (!result || !Array.isArray(result.messages)) return [];
|
|
18094
|
+
return normalizeNativeHistoryMessages(
|
|
18095
|
+
providerType,
|
|
18096
|
+
result.messages,
|
|
18097
|
+
typeof result.providerSessionId === "string" ? result.providerSessionId : void 0
|
|
18098
|
+
);
|
|
18099
|
+
}
|
|
18100
|
+
function applyUnsafeNativeDaemonFallback(args) {
|
|
18101
|
+
if (args.adapter.cliType !== "codex-cli") {
|
|
18102
|
+
return;
|
|
18103
|
+
}
|
|
18104
|
+
const ms = args.messageSourceRef.get();
|
|
18105
|
+
const fallbackReason = typeof ms.fallbackReason === "string" ? ms.fallbackReason : "";
|
|
18106
|
+
if (!isUnsafeNativeTranscriptFallback(fallbackReason)) {
|
|
18107
|
+
return;
|
|
18108
|
+
}
|
|
18109
|
+
const safeCurrentRuntimePtyMessages = isCurrentRuntimePtySafelyAttributed({
|
|
18110
|
+
adapter: args.adapter,
|
|
18111
|
+
helpers: args.helpers,
|
|
18112
|
+
readChatArgs: args.readChatArgs,
|
|
18113
|
+
sessionWorkspace: args.sessionWorkspace,
|
|
18114
|
+
intendedWorkspace: args.intendedWorkspace,
|
|
18115
|
+
ptyMessages: args.ptyMessages
|
|
18116
|
+
});
|
|
18117
|
+
if (safeCurrentRuntimePtyMessages) {
|
|
18118
|
+
args.apply({
|
|
18119
|
+
messages: args.ptyMessages,
|
|
18120
|
+
transcriptAuthority: "daemon",
|
|
18121
|
+
coverage: args.coverage || "current-turn",
|
|
18122
|
+
status: args.returnedStatus
|
|
18123
|
+
});
|
|
18124
|
+
const next2 = { ...ms, selectedDaemonSource: "current-runtime-pty", transcriptAuthority: "daemon", runtimeMappingSafe: true };
|
|
18125
|
+
args.messageSourceRef.set(next2);
|
|
18126
|
+
return;
|
|
18127
|
+
}
|
|
18128
|
+
const safeRuntimeAckMessages = selectRuntimeInputAckMessages(args.ptyMessages);
|
|
18129
|
+
if (safeRuntimeAckMessages.length > 0) {
|
|
18130
|
+
args.apply({
|
|
18131
|
+
messages: safeRuntimeAckMessages,
|
|
18132
|
+
transcriptAuthority: "daemon",
|
|
18133
|
+
coverage: "tail",
|
|
18134
|
+
status: coerceUnsafeNativeFallbackStatus(args.returnedStatus, args.activeModal)
|
|
18135
|
+
});
|
|
18136
|
+
const next2 = { ...ms, ptyStatusApprovalOnly: true };
|
|
18137
|
+
args.messageSourceRef.set(next2);
|
|
18138
|
+
return;
|
|
18139
|
+
}
|
|
18140
|
+
const exactRuntimeMirrorMessages = readExactRuntimeMirrorMessages({
|
|
18141
|
+
providerType: args.providerType,
|
|
18142
|
+
targetSessionId: typeof args.readChatArgs?.targetSessionId === "string" ? args.readChatArgs.targetSessionId : void 0,
|
|
18143
|
+
currentSessionId: typeof args.helpers.currentSession?.sessionId === "string" ? args.helpers.currentSession.sessionId : void 0,
|
|
18144
|
+
tailLimit: args.nativeHistoryLimit,
|
|
18145
|
+
historyBehavior: args.provider?.historyBehavior
|
|
18146
|
+
});
|
|
18147
|
+
if (exactRuntimeMirrorMessages.length > 0) {
|
|
18148
|
+
args.apply({
|
|
18149
|
+
messages: exactRuntimeMirrorMessages,
|
|
18150
|
+
transcriptAuthority: "daemon",
|
|
18151
|
+
coverage: "tail",
|
|
18152
|
+
status: coerceUnsafeNativeFallbackStatus(args.returnedStatus, args.activeModal)
|
|
18153
|
+
});
|
|
18154
|
+
const next2 = { ...ms, selectedDaemonSource: "exact-runtime-mirror", transcriptAuthority: "daemon", ptyStatusApprovalOnly: true };
|
|
18155
|
+
args.messageSourceRef.set(next2);
|
|
18156
|
+
return;
|
|
18157
|
+
}
|
|
18158
|
+
args.apply({
|
|
18159
|
+
messages: args.ptyMessages,
|
|
18160
|
+
coverage: args.coverage,
|
|
18161
|
+
status: coerceUnsafeNativeFallbackStatus(args.returnedStatus, args.activeModal)
|
|
18162
|
+
});
|
|
18163
|
+
const next = { ...ms, ptyStatusApprovalOnly: true };
|
|
18164
|
+
args.messageSourceRef.set(next);
|
|
17528
18165
|
}
|
|
17529
18166
|
function isUnsafeNativeTranscriptFallback(reason) {
|
|
17530
18167
|
const value = String(reason || "").trim();
|
|
@@ -17596,8 +18233,14 @@ function isCurrentRuntimePtySafelyAttributed(args) {
|
|
|
17596
18233
|
return true;
|
|
17597
18234
|
}
|
|
17598
18235
|
function supportsCliNativeTranscript(providerType, provider) {
|
|
17599
|
-
if (
|
|
17600
|
-
|
|
18236
|
+
if (provider?.category === "cli" && isNativeSourceCanonicalHistory(provider?.canonicalHistory)) {
|
|
18237
|
+
return true;
|
|
18238
|
+
}
|
|
18239
|
+
if (CLI_NATIVE_TRANSCRIPT_PROVIDERS.has(providerType)) {
|
|
18240
|
+
warnLegacyNativeAllowlistHit(providerType);
|
|
18241
|
+
return true;
|
|
18242
|
+
}
|
|
18243
|
+
return false;
|
|
17601
18244
|
}
|
|
17602
18245
|
function getComparableVisibleText(message) {
|
|
17603
18246
|
if (!message) return "";
|
|
@@ -17696,14 +18339,6 @@ function readLiveCodexWorkspaceNativeHistory(agentStr, args) {
|
|
|
17696
18339
|
});
|
|
17697
18340
|
return { ...history, lookup: "workspace" };
|
|
17698
18341
|
}
|
|
17699
|
-
function isNativeHistoryFreshEnough(args) {
|
|
17700
|
-
const nativeNewest = getMessageNewestReceivedAt(args.nativeMessages);
|
|
17701
|
-
const ptyNewest = getMessageNewestReceivedAt(args.ptyMessages);
|
|
17702
|
-
if (nativeNewest > 0 && nativeNewest >= ptyNewest) return true;
|
|
17703
|
-
const sourceMtimeMs = Number(args.sourceMtimeMs || 0);
|
|
17704
|
-
if (sourceMtimeMs > 0 && Date.now() - sourceMtimeMs <= CLI_NATIVE_HISTORY_FRESH_MS) return true;
|
|
17705
|
-
return ptyNewest === 0 && nativeNewest > 0;
|
|
17706
|
-
}
|
|
17707
18342
|
function shouldPreserveReadChatPayloadField(key) {
|
|
17708
18343
|
return key === "messageSource" || key === "transcriptProvenance";
|
|
17709
18344
|
}
|
|
@@ -17768,6 +18403,8 @@ function normalizeReadChatCommandStatus(status, activeModal) {
|
|
|
17768
18403
|
case "disconnected":
|
|
17769
18404
|
case "not_monitored":
|
|
17770
18405
|
return "error";
|
|
18406
|
+
case "waiting_approval":
|
|
18407
|
+
return hasNonEmptyModalButtons(activeModal) ? "waiting_approval" : "generating";
|
|
17771
18408
|
default:
|
|
17772
18409
|
return raw;
|
|
17773
18410
|
}
|
|
@@ -17816,6 +18453,36 @@ function finalizeStreamingMessagesWhenIdle(messages, status) {
|
|
|
17816
18453
|
};
|
|
17817
18454
|
});
|
|
17818
18455
|
}
|
|
18456
|
+
function collapseAdjacentDuplicateChatMessages(messages) {
|
|
18457
|
+
if (!Array.isArray(messages) || messages.length <= 1) return messages;
|
|
18458
|
+
const result = [];
|
|
18459
|
+
let prevRoleKind = "";
|
|
18460
|
+
let prevStripped = "";
|
|
18461
|
+
for (const message of messages) {
|
|
18462
|
+
const role = typeof message.role === "string" ? message.role : "";
|
|
18463
|
+
const kind = typeof message.kind === "string" ? message.kind : "standard";
|
|
18464
|
+
const content = typeof message.content === "string" ? message.content : Array.isArray(message.content) ? message.content.map((p) => typeof p?.text === "string" ? p.text : "").join("") : "";
|
|
18465
|
+
const strippedContent = content.replace(/\s+/g, "");
|
|
18466
|
+
if (!strippedContent || role === "system") {
|
|
18467
|
+
result.push(message);
|
|
18468
|
+
prevRoleKind = "";
|
|
18469
|
+
prevStripped = "";
|
|
18470
|
+
continue;
|
|
18471
|
+
}
|
|
18472
|
+
const roleKind = `${role}:${kind}`;
|
|
18473
|
+
const sameStripped = strippedContent === prevStripped && roleKind === prevRoleKind;
|
|
18474
|
+
if (result.length > 0 && sameStripped) {
|
|
18475
|
+
result[result.length - 1] = message;
|
|
18476
|
+
prevRoleKind = roleKind;
|
|
18477
|
+
prevStripped = strippedContent;
|
|
18478
|
+
continue;
|
|
18479
|
+
}
|
|
18480
|
+
result.push(message);
|
|
18481
|
+
prevRoleKind = roleKind;
|
|
18482
|
+
prevStripped = strippedContent;
|
|
18483
|
+
}
|
|
18484
|
+
return result;
|
|
18485
|
+
}
|
|
17819
18486
|
function buildReadChatCommandResult(payload, args) {
|
|
17820
18487
|
let validatedPayload;
|
|
17821
18488
|
const debugReadChat = payload?.debugReadChat && typeof payload.debugReadChat === "object" ? payload.debugReadChat : void 0;
|
|
@@ -18338,7 +19005,9 @@ async function handleReadChat(h, args) {
|
|
|
18338
19005
|
const activeModal = parsedRecord.activeModal ?? parsedRecord.modal ?? null;
|
|
18339
19006
|
const returnedStatus = normalizeCliReadChatStatus(parsedRecord.status, activeModal, adapter, adapterStatus, parsedRecord.messages);
|
|
18340
19007
|
const runtimeMessageMerger = getTargetInstance(h, args);
|
|
18341
|
-
const parsedMessages =
|
|
19008
|
+
const parsedMessages = collapseAdjacentDuplicateChatMessages(
|
|
19009
|
+
finalizeStreamingMessagesWhenIdle(parsedRecord.messages, returnedStatus)
|
|
19010
|
+
);
|
|
18342
19011
|
const returnedMessages = runtimeMessageMerger?.category === "cli" && runtimeMessageMerger.type === adapter.cliType && typeof runtimeMessageMerger.mergeRuntimeChatMessages === "function" ? runtimeMessageMerger.mergeRuntimeChatMessages(parsedMessages) : parsedMessages;
|
|
18343
19012
|
const providerType = provider?.type || adapter.cliType;
|
|
18344
19013
|
let selectedMessages = returnedMessages;
|
|
@@ -18349,30 +19018,22 @@ async function handleReadChat(h, args) {
|
|
|
18349
19018
|
let selectedStatus = returnedStatus;
|
|
18350
19019
|
const sessionWorkspace = typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : typeof adapter.workingDir === "string" ? adapter.workingDir : void 0;
|
|
18351
19020
|
const intendedWorkspace = typeof args?.workspace === "string" ? args.workspace : void 0;
|
|
18352
|
-
|
|
18353
|
-
|
|
18354
|
-
|
|
18355
|
-
|
|
18356
|
-
|
|
18357
|
-
|
|
18358
|
-
|
|
18359
|
-
|
|
18360
|
-
|
|
18361
|
-
|
|
18362
|
-
|
|
18363
|
-
|
|
18364
|
-
|
|
18365
|
-
|
|
18366
|
-
|
|
18367
|
-
|
|
18368
|
-
200
|
|
18369
|
-
);
|
|
18370
|
-
const nativeHistorySessionId = resolveCliNativeHistorySessionId(args, historySessionId, providerSessionId);
|
|
18371
|
-
const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
|
|
18372
|
-
const exactNativeHistoryScope = Boolean(
|
|
18373
|
-
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()
|
|
18374
|
-
);
|
|
18375
|
-
let nativeHistory = null;
|
|
19021
|
+
const supportsNative = supportsCliNativeTranscript(providerType, provider) && isNativeSourceCanonicalHistory(provider?.canonicalHistory);
|
|
19022
|
+
const agentStr = provider?.type || args?.agentType || getCurrentProviderType(h, adapter.cliType);
|
|
19023
|
+
const workspace = sessionWorkspace;
|
|
19024
|
+
const nativeHistoryLimit = Math.max(
|
|
19025
|
+
normalizeReadChatTailLimit(args) || 0,
|
|
19026
|
+
returnedMessages.length,
|
|
19027
|
+
200
|
|
19028
|
+
);
|
|
19029
|
+
const nativeHistorySessionId = supportsNative ? resolveCliNativeHistorySessionId(args, historySessionId, providerSessionId) : void 0;
|
|
19030
|
+
const targetSessionId = typeof args?.targetSessionId === "string" ? args.targetSessionId.trim() : "";
|
|
19031
|
+
const exactNativeHistoryScope = Boolean(
|
|
19032
|
+
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()
|
|
19033
|
+
);
|
|
19034
|
+
let nativeHistory = null;
|
|
19035
|
+
let nativeHistoryError;
|
|
19036
|
+
if (supportsNative) {
|
|
18376
19037
|
try {
|
|
18377
19038
|
nativeHistory = readCliProviderNativeHistory(agentStr, {
|
|
18378
19039
|
canonicalHistory: provider?.canonicalHistory,
|
|
@@ -18386,210 +19047,148 @@ async function handleReadChat(h, args) {
|
|
|
18386
19047
|
excludeInProgressTurn: returnedStatus === "waiting_approval"
|
|
18387
19048
|
});
|
|
18388
19049
|
} catch (error) {
|
|
18389
|
-
|
|
18390
|
-
messageSource = buildCliMessageSourceProvenance({
|
|
18391
|
-
selected: "pty-parser",
|
|
18392
|
-
provider: adapter.cliType,
|
|
18393
|
-
fallbackReason,
|
|
18394
|
-
sessionWorkspace,
|
|
18395
|
-
intendedWorkspace,
|
|
18396
|
-
ptyMessages: returnedMessages,
|
|
18397
|
-
returnedMessages,
|
|
18398
|
-
ptyStatusApprovalOnly: false
|
|
18399
|
-
});
|
|
19050
|
+
nativeHistoryError = error;
|
|
18400
19051
|
nativeHistory = null;
|
|
18401
19052
|
}
|
|
18402
|
-
|
|
18403
|
-
|
|
18404
|
-
|
|
18405
|
-
|
|
18406
|
-
|
|
18407
|
-
|
|
18408
|
-
|
|
18409
|
-
|
|
18410
|
-
|
|
18411
|
-
|
|
18412
|
-
|
|
18413
|
-
|
|
18414
|
-
|
|
18415
|
-
|
|
19053
|
+
}
|
|
19054
|
+
const nativeMessages = nativeHistory && Array.isArray(nativeHistory.messages) ? normalizeNativeHistoryMessages(agentStr, nativeHistory.messages, nativeHistory.providerSessionId) : [];
|
|
19055
|
+
const historyProviderSessionId = typeof nativeHistory?.providerSessionId === "string" ? nativeHistory.providerSessionId : readHistorySessionIdFromMessages(nativeMessages) || nativeHistorySessionId || historySessionId;
|
|
19056
|
+
const lookup = nativeHistory?.lookup === "workspace" ? "workspace" : "session";
|
|
19057
|
+
const nativeHistorySessionForMapping = adapter.cliType === "antigravity-cli" && historyProviderSessionId && nativeHistorySessionId && historyProviderSessionId !== nativeHistorySessionId ? void 0 : nativeHistorySessionId;
|
|
19058
|
+
const safeMapping = supportsNative && nativeHistory ? hasSafeNativeHistoryMapping({
|
|
19059
|
+
historySessionId: lookup === "workspace" ? void 0 : nativeHistorySessionForMapping,
|
|
19060
|
+
providerSessionId: lookup === "workspace" ? void 0 : historyProviderSessionId || providerSessionId,
|
|
19061
|
+
workspace,
|
|
19062
|
+
nativeMessages,
|
|
19063
|
+
ptyMessages: returnedMessages,
|
|
19064
|
+
requireWorkspaceContentOverlap: lookup === "workspace" && !exactNativeHistoryScope
|
|
19065
|
+
}) : false;
|
|
19066
|
+
const machineSessionKey = String(
|
|
19067
|
+
args?.targetSessionId || providerSessionId || historySessionId || h.currentSession?.sessionId || ""
|
|
19068
|
+
);
|
|
19069
|
+
const primary = decideCliReadChatSource({
|
|
19070
|
+
providerType,
|
|
19071
|
+
provider,
|
|
19072
|
+
sessionId: machineSessionKey,
|
|
19073
|
+
nativeHistoryResult: nativeHistory,
|
|
19074
|
+
nativeHistoryError,
|
|
19075
|
+
safeMapping,
|
|
19076
|
+
sessionWorkspace,
|
|
19077
|
+
intendedWorkspace,
|
|
19078
|
+
ptyMessages: returnedMessages,
|
|
19079
|
+
// Start with PTY visible; decideCliReadChatSource flips this
|
|
19080
|
+
// to true when the machine actually selects native-history.
|
|
19081
|
+
ptyStatusApprovalOnly: false
|
|
19082
|
+
});
|
|
19083
|
+
let messageSource = primary.messageSource;
|
|
19084
|
+
if (primary.nativeSelected) {
|
|
19085
|
+
selectedMessages = finalizeStreamingMessagesWhenIdle(primary.nativeMessages, returnedStatus);
|
|
19086
|
+
selectedProviderSessionId = historyProviderSessionId || providerSessionId;
|
|
19087
|
+
selectedTranscriptAuthority = "provider";
|
|
19088
|
+
selectedCoverage = nativeHistory?.hasMore ? "tail" : "full";
|
|
19089
|
+
} else if (supportsNative) {
|
|
19090
|
+
const liveCurrentRuntimePtySafe = isCurrentRuntimePtySafelyAttributed({
|
|
19091
|
+
adapter,
|
|
19092
|
+
helpers: h,
|
|
19093
|
+
readChatArgs: args,
|
|
19094
|
+
sessionWorkspace,
|
|
19095
|
+
intendedWorkspace,
|
|
19096
|
+
ptyMessages: returnedMessages
|
|
19097
|
+
});
|
|
19098
|
+
const mayProbeLiveCodexWorkspaceNative = adapter.cliType === "codex-cli" && liveCurrentRuntimePtySafe && !(typeof args?.providerSessionId === "string" && args.providerSessionId.trim()) && !(providerSessionId && providerSessionId.trim()) && (!historyProviderSessionId || historyProviderSessionId === nativeHistorySessionId || historyProviderSessionId === historySessionId);
|
|
19099
|
+
const liveWorkspaceNativeHistory = mayProbeLiveCodexWorkspaceNative ? readLiveCodexWorkspaceNativeHistory(agentStr, {
|
|
19100
|
+
canonicalHistory: provider?.canonicalHistory,
|
|
19101
|
+
workspace,
|
|
19102
|
+
offset: 0,
|
|
19103
|
+
limit: nativeHistoryLimit,
|
|
19104
|
+
excludeRecentCount: 0,
|
|
19105
|
+
historyBehavior: provider?.historyBehavior,
|
|
19106
|
+
scripts: provider?.scripts
|
|
19107
|
+
}) : null;
|
|
19108
|
+
const liveWorkspaceNativeMessages = Array.isArray(liveWorkspaceNativeHistory?.messages) ? normalizeNativeHistoryMessages(agentStr, liveWorkspaceNativeHistory.messages, liveWorkspaceNativeHistory?.providerSessionId) : [];
|
|
19109
|
+
const liveWorkspaceNativeProviderSessionId = typeof liveWorkspaceNativeHistory?.providerSessionId === "string" ? liveWorkspaceNativeHistory.providerSessionId : readHistorySessionIdFromMessages(liveWorkspaceNativeMessages);
|
|
19110
|
+
const liveWorkspaceNativeSafeMapping = liveWorkspaceNativeMessages.length > 0 && hasSafeNativeHistoryMapping({
|
|
19111
|
+
workspace,
|
|
19112
|
+
nativeMessages: liveWorkspaceNativeMessages,
|
|
19113
|
+
ptyMessages: returnedMessages,
|
|
19114
|
+
requireWorkspaceContentOverlap: true
|
|
19115
|
+
});
|
|
19116
|
+
if (liveWorkspaceNativeHistory) {
|
|
19117
|
+
const liveDecision = decideCliReadChatSource({
|
|
19118
|
+
providerType,
|
|
19119
|
+
provider,
|
|
19120
|
+
// Distinct session key so a transient codex live-probe does not
|
|
19121
|
+
// clobber the primary session's lock. The machine treats this
|
|
19122
|
+
// as its own session; the primary session's state is untouched.
|
|
19123
|
+
sessionId: `${machineSessionKey}::live-workspace`,
|
|
19124
|
+
nativeHistoryResult: liveWorkspaceNativeHistory,
|
|
19125
|
+
safeMapping: liveWorkspaceNativeSafeMapping,
|
|
19126
|
+
sessionWorkspace,
|
|
19127
|
+
intendedWorkspace,
|
|
18416
19128
|
ptyMessages: returnedMessages,
|
|
18417
|
-
|
|
18418
|
-
});
|
|
18419
|
-
const freshEnough = isNativeHistoryFreshEnough({
|
|
18420
|
-
sourceMtimeMs: nativeHistory.sourceMtimeMs,
|
|
18421
|
-
nativeMessages,
|
|
18422
|
-
ptyMessages: returnedMessages
|
|
19129
|
+
ptyStatusApprovalOnly: true
|
|
18423
19130
|
});
|
|
18424
|
-
|
|
18425
|
-
|
|
18426
|
-
|
|
18427
|
-
const nativeIsAnchored = nativeAnchoredAt > 0 && Date.now() - nativeAnchoredAt < NATIVE_ANCHOR_TTL_MS;
|
|
18428
|
-
const allowStaleNativeChatMessages = (adapter.cliType === "antigravity-cli" || nativeIsAnchored) && nativeUsableForChatMessages;
|
|
18429
|
-
if (nativeUsableForChatMessages && (freshEnough || allowStaleNativeChatMessages)) {
|
|
18430
|
-
adapter.nativeHistoryAnchoredAt = Date.now();
|
|
18431
|
-
selectedMessages = finalizeStreamingMessagesWhenIdle(nativeMessages, returnedStatus);
|
|
18432
|
-
selectedProviderSessionId = historyProviderSessionId || providerSessionId;
|
|
19131
|
+
if (liveDecision.nativeSelected) {
|
|
19132
|
+
selectedMessages = finalizeStreamingMessagesWhenIdle(liveDecision.nativeMessages, returnedStatus);
|
|
19133
|
+
selectedProviderSessionId = liveWorkspaceNativeProviderSessionId || providerSessionId;
|
|
18433
19134
|
selectedTranscriptAuthority = "provider";
|
|
18434
|
-
selectedCoverage =
|
|
18435
|
-
messageSource =
|
|
18436
|
-
|
|
18437
|
-
|
|
18438
|
-
nativeHandle: selectedProviderSessionId || nativeHistorySessionId || historySessionId,
|
|
18439
|
-
sessionWorkspace,
|
|
18440
|
-
intendedWorkspace,
|
|
18441
|
-
transcriptWorkspace,
|
|
18442
|
-
nativeSource: nativeHistory.source,
|
|
18443
|
-
sourcePath: nativeHistory.sourcePath,
|
|
18444
|
-
sourceMtimeMs: nativeHistory.sourceMtimeMs,
|
|
18445
|
-
nativeHistoryCoverage,
|
|
18446
|
-
partialReason,
|
|
18447
|
-
unavailableReason,
|
|
18448
|
-
nativeMessages,
|
|
18449
|
-
ptyMessages: returnedMessages,
|
|
18450
|
-
returnedMessages: selectedMessages,
|
|
18451
|
-
safeMapping,
|
|
18452
|
-
freshEnough,
|
|
18453
|
-
ptyStatusApprovalOnly: true
|
|
18454
|
-
});
|
|
19135
|
+
selectedCoverage = liveWorkspaceNativeHistory.hasMore ? "tail" : "full";
|
|
19136
|
+
messageSource = liveDecision.messageSource;
|
|
19137
|
+
messageSource.selectedDaemonSource = "live-workspace-native-history";
|
|
19138
|
+
messageSource.runtimeMappingSafe = true;
|
|
18455
19139
|
} else {
|
|
18456
|
-
|
|
18457
|
-
|
|
18458
|
-
}
|
|
18459
|
-
const liveCurrentRuntimePtySafe = isCurrentRuntimePtySafelyAttributed({
|
|
19140
|
+
applyUnsafeNativeDaemonFallback({
|
|
19141
|
+
providerType,
|
|
18460
19142
|
adapter,
|
|
18461
19143
|
helpers: h,
|
|
18462
19144
|
readChatArgs: args,
|
|
18463
19145
|
sessionWorkspace,
|
|
18464
19146
|
intendedWorkspace,
|
|
18465
|
-
ptyMessages: returnedMessages
|
|
18466
|
-
});
|
|
18467
|
-
const mayProbeLiveCodexWorkspaceNative = adapter.cliType === "codex-cli" && liveCurrentRuntimePtySafe && !(typeof args?.providerSessionId === "string" && args.providerSessionId.trim()) && !(providerSessionId && providerSessionId.trim()) && (!historyProviderSessionId || historyProviderSessionId === nativeHistorySessionId || historyProviderSessionId === historySessionId);
|
|
18468
|
-
const liveWorkspaceNativeHistory = mayProbeLiveCodexWorkspaceNative ? readLiveCodexWorkspaceNativeHistory(agentStr, {
|
|
18469
|
-
canonicalHistory: provider?.canonicalHistory,
|
|
18470
|
-
workspace,
|
|
18471
|
-
offset: 0,
|
|
18472
|
-
limit: nativeHistoryLimit,
|
|
18473
|
-
excludeRecentCount: 0,
|
|
18474
|
-
historyBehavior: provider?.historyBehavior,
|
|
18475
|
-
scripts: provider?.scripts
|
|
18476
|
-
}) : null;
|
|
18477
|
-
const liveWorkspaceNativeMessages = Array.isArray(liveWorkspaceNativeHistory?.messages) ? normalizeNativeHistoryMessages(agentStr, liveWorkspaceNativeHistory.messages, liveWorkspaceNativeHistory?.providerSessionId) : [];
|
|
18478
|
-
const liveWorkspaceNativeProviderSessionId = typeof liveWorkspaceNativeHistory?.providerSessionId === "string" ? liveWorkspaceNativeHistory.providerSessionId : readHistorySessionIdFromMessages(liveWorkspaceNativeMessages);
|
|
18479
|
-
const liveWorkspaceTranscriptWorkspace = typeof liveWorkspaceNativeHistory?.workspace === "string" ? liveWorkspaceNativeHistory.workspace : liveWorkspaceNativeMessages.map((message) => typeof message?.workspace === "string" ? message.workspace.trim() : "").find(Boolean);
|
|
18480
|
-
const liveWorkspaceNativeSafeMapping = liveWorkspaceNativeMessages.length > 0 && hasSafeNativeHistoryMapping({
|
|
18481
|
-
workspace,
|
|
18482
|
-
nativeMessages: liveWorkspaceNativeMessages,
|
|
18483
19147
|
ptyMessages: returnedMessages,
|
|
18484
|
-
|
|
18485
|
-
|
|
18486
|
-
|
|
18487
|
-
|
|
18488
|
-
|
|
18489
|
-
|
|
19148
|
+
nativeHistoryLimit,
|
|
19149
|
+
provider,
|
|
19150
|
+
messageSourceRef: { set(value) {
|
|
19151
|
+
messageSource = value;
|
|
19152
|
+
}, get() {
|
|
19153
|
+
return messageSource;
|
|
19154
|
+
} },
|
|
19155
|
+
apply(selection) {
|
|
19156
|
+
selectedMessages = selection.messages;
|
|
19157
|
+
selectedTranscriptAuthority = selection.transcriptAuthority;
|
|
19158
|
+
selectedCoverage = selection.coverage ?? coverage;
|
|
19159
|
+
selectedStatus = selection.status ?? returnedStatus;
|
|
19160
|
+
},
|
|
19161
|
+
activeModal,
|
|
19162
|
+
returnedStatus,
|
|
19163
|
+
coverage
|
|
18490
19164
|
});
|
|
18491
|
-
const liveWorkspaceNativeUsable = liveWorkspaceNativeHistory?.source === "provider-native" && liveWorkspaceNativeMessages.length > 0 && liveWorkspaceNativeHistory?.nativeHistoryCoverage !== "partial" && liveWorkspaceNativeHistory?.nativeHistoryCoverage !== "unavailable" && liveWorkspaceNativeSafeMapping && liveWorkspaceNativeFreshEnough;
|
|
18492
|
-
if (liveWorkspaceNativeUsable) {
|
|
18493
|
-
selectedMessages = finalizeStreamingMessagesWhenIdle(liveWorkspaceNativeMessages, returnedStatus);
|
|
18494
|
-
selectedProviderSessionId = liveWorkspaceNativeProviderSessionId || providerSessionId;
|
|
18495
|
-
selectedTranscriptAuthority = "provider";
|
|
18496
|
-
selectedCoverage = liveWorkspaceNativeHistory.hasMore ? "tail" : "full";
|
|
18497
|
-
messageSource = buildCliMessageSourceProvenance({
|
|
18498
|
-
selected: "native-history",
|
|
18499
|
-
provider: adapter.cliType,
|
|
18500
|
-
nativeHandle: selectedProviderSessionId || nativeHistorySessionId || historySessionId,
|
|
18501
|
-
sessionWorkspace,
|
|
18502
|
-
intendedWorkspace,
|
|
18503
|
-
transcriptWorkspace: liveWorkspaceTranscriptWorkspace,
|
|
18504
|
-
nativeSource: liveWorkspaceNativeHistory.source,
|
|
18505
|
-
sourcePath: liveWorkspaceNativeHistory.sourcePath,
|
|
18506
|
-
sourceMtimeMs: liveWorkspaceNativeHistory.sourceMtimeMs,
|
|
18507
|
-
nativeHistoryCoverage: liveWorkspaceNativeHistory.nativeHistoryCoverage,
|
|
18508
|
-
partialReason: liveWorkspaceNativeHistory.partialReason,
|
|
18509
|
-
unavailableReason: liveWorkspaceNativeHistory.unavailableReason,
|
|
18510
|
-
nativeMessages: liveWorkspaceNativeMessages,
|
|
18511
|
-
ptyMessages: returnedMessages,
|
|
18512
|
-
returnedMessages: selectedMessages,
|
|
18513
|
-
safeMapping: true,
|
|
18514
|
-
freshEnough: true,
|
|
18515
|
-
ptyStatusApprovalOnly: true
|
|
18516
|
-
});
|
|
18517
|
-
messageSource.selectedDaemonSource = "live-workspace-native-history";
|
|
18518
|
-
messageSource.runtimeMappingSafe = true;
|
|
18519
|
-
} else {
|
|
18520
|
-
const fallbackReason = buildNativeHistoryFallbackReason({
|
|
18521
|
-
providerType,
|
|
18522
|
-
provider,
|
|
18523
|
-
nativeSource: nativeHistory.source,
|
|
18524
|
-
nativeHistoryCoverage,
|
|
18525
|
-
unavailableReason,
|
|
18526
|
-
nativeMessageCount: nativeMessages.length,
|
|
18527
|
-
safeMapping,
|
|
18528
|
-
freshEnough
|
|
18529
|
-
});
|
|
18530
|
-
const unsafeNativeFallback = adapter.cliType === "codex-cli" && isUnsafeNativeTranscriptFallback(fallbackReason);
|
|
18531
|
-
const safeCurrentRuntimePtyMessages = unsafeNativeFallback && isCurrentRuntimePtySafelyAttributed({
|
|
18532
|
-
adapter,
|
|
18533
|
-
helpers: h,
|
|
18534
|
-
readChatArgs: args,
|
|
18535
|
-
sessionWorkspace,
|
|
18536
|
-
intendedWorkspace,
|
|
18537
|
-
ptyMessages: returnedMessages
|
|
18538
|
-
});
|
|
18539
|
-
const safeRuntimeAckMessages = unsafeNativeFallback && !safeCurrentRuntimePtyMessages ? selectRuntimeInputAckMessages(returnedMessages) : [];
|
|
18540
|
-
const exactRuntimeMirrorMessages = unsafeNativeFallback && !safeCurrentRuntimePtyMessages && safeRuntimeAckMessages.length === 0 ? readExactRuntimeMirrorMessages({
|
|
18541
|
-
providerType,
|
|
18542
|
-
targetSessionId: typeof args?.targetSessionId === "string" ? args.targetSessionId : void 0,
|
|
18543
|
-
currentSessionId: typeof h.currentSession?.sessionId === "string" ? h.currentSession.sessionId : void 0,
|
|
18544
|
-
tailLimit: nativeHistoryLimit,
|
|
18545
|
-
historyBehavior: provider?.historyBehavior
|
|
18546
|
-
}) : [];
|
|
18547
|
-
const safeDaemonMessages = safeRuntimeAckMessages.length > 0 ? safeRuntimeAckMessages : exactRuntimeMirrorMessages;
|
|
18548
|
-
if (unsafeNativeFallback) {
|
|
18549
|
-
if (safeCurrentRuntimePtyMessages) {
|
|
18550
|
-
selectedMessages = returnedMessages;
|
|
18551
|
-
selectedTranscriptAuthority = "daemon";
|
|
18552
|
-
selectedCoverage = coverage || "current-turn";
|
|
18553
|
-
selectedStatus = returnedStatus;
|
|
18554
|
-
} else {
|
|
18555
|
-
selectedMessages = safeDaemonMessages;
|
|
18556
|
-
selectedTranscriptAuthority = safeDaemonMessages.length > 0 ? "daemon" : void 0;
|
|
18557
|
-
selectedCoverage = safeDaemonMessages.length > 0 ? "tail" : void 0;
|
|
18558
|
-
selectedStatus = coerceUnsafeNativeFallbackStatus(returnedStatus, activeModal);
|
|
18559
|
-
}
|
|
18560
|
-
}
|
|
18561
|
-
messageSource = buildCliMessageSourceProvenance({
|
|
18562
|
-
selected: "pty-parser",
|
|
18563
|
-
provider: adapter.cliType,
|
|
18564
|
-
nativeHandle: historyProviderSessionId || nativeHistorySessionId || historySessionId,
|
|
18565
|
-
sessionWorkspace,
|
|
18566
|
-
intendedWorkspace,
|
|
18567
|
-
transcriptWorkspace,
|
|
18568
|
-
fallbackReason,
|
|
18569
|
-
nativeSource: nativeHistory.source,
|
|
18570
|
-
sourcePath: nativeHistory.sourcePath,
|
|
18571
|
-
sourceMtimeMs: nativeHistory.sourceMtimeMs,
|
|
18572
|
-
nativeHistoryCoverage,
|
|
18573
|
-
partialReason,
|
|
18574
|
-
unavailableReason,
|
|
18575
|
-
nativeMessages,
|
|
18576
|
-
ptyMessages: returnedMessages,
|
|
18577
|
-
returnedMessages: unsafeNativeFallback && !safeCurrentRuntimePtyMessages ? safeDaemonMessages : returnedMessages,
|
|
18578
|
-
safeMapping,
|
|
18579
|
-
freshEnough,
|
|
18580
|
-
ptyStatusApprovalOnly: unsafeNativeFallback && !safeCurrentRuntimePtyMessages
|
|
18581
|
-
});
|
|
18582
|
-
if (safeCurrentRuntimePtyMessages) {
|
|
18583
|
-
messageSource.selectedDaemonSource = "current-runtime-pty";
|
|
18584
|
-
messageSource.transcriptAuthority = "daemon";
|
|
18585
|
-
messageSource.runtimeMappingSafe = true;
|
|
18586
|
-
}
|
|
18587
|
-
if (unsafeNativeFallback && exactRuntimeMirrorMessages.length > 0) {
|
|
18588
|
-
messageSource.selectedDaemonSource = "exact-runtime-mirror";
|
|
18589
|
-
messageSource.transcriptAuthority = "daemon";
|
|
18590
|
-
}
|
|
18591
|
-
}
|
|
18592
19165
|
}
|
|
19166
|
+
} else {
|
|
19167
|
+
applyUnsafeNativeDaemonFallback({
|
|
19168
|
+
providerType,
|
|
19169
|
+
adapter,
|
|
19170
|
+
helpers: h,
|
|
19171
|
+
readChatArgs: args,
|
|
19172
|
+
sessionWorkspace,
|
|
19173
|
+
intendedWorkspace,
|
|
19174
|
+
ptyMessages: returnedMessages,
|
|
19175
|
+
nativeHistoryLimit,
|
|
19176
|
+
provider,
|
|
19177
|
+
messageSourceRef: { set(value) {
|
|
19178
|
+
messageSource = value;
|
|
19179
|
+
}, get() {
|
|
19180
|
+
return messageSource;
|
|
19181
|
+
} },
|
|
19182
|
+
apply(selection) {
|
|
19183
|
+
selectedMessages = selection.messages;
|
|
19184
|
+
selectedTranscriptAuthority = selection.transcriptAuthority;
|
|
19185
|
+
selectedCoverage = selection.coverage ?? coverage;
|
|
19186
|
+
selectedStatus = selection.status ?? returnedStatus;
|
|
19187
|
+
},
|
|
19188
|
+
activeModal,
|
|
19189
|
+
returnedStatus,
|
|
19190
|
+
coverage
|
|
19191
|
+
});
|
|
18593
19192
|
}
|
|
18594
19193
|
}
|
|
18595
19194
|
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}`);
|
|
@@ -18622,10 +19221,8 @@ async function handleReadChat(h, args) {
|
|
|
18622
19221
|
const agentStr = provider?.type || args?.agentType || getCurrentProviderType(h);
|
|
18623
19222
|
const workspace = typeof h.currentSession?.workspace === "string" ? h.currentSession.workspace : void 0;
|
|
18624
19223
|
const intendedWorkspace = typeof args?.workspace === "string" ? args.workspace : void 0;
|
|
18625
|
-
const
|
|
18626
|
-
|
|
18627
|
-
);
|
|
18628
|
-
const history = supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.canonicalHistory) ? readCliProviderNativeHistory(agentStr, {
|
|
19224
|
+
const supportsNative = supportsCliNativeTranscript(agentStr, provider) && isNativeSourceCanonicalHistory(provider?.canonicalHistory);
|
|
19225
|
+
const history = supportsNative ? readCliProviderNativeHistory(agentStr, {
|
|
18629
19226
|
canonicalHistory: provider?.canonicalHistory,
|
|
18630
19227
|
historySessionId,
|
|
18631
19228
|
workspace,
|
|
@@ -18644,65 +19241,44 @@ async function handleReadChat(h, args) {
|
|
|
18644
19241
|
historyBehavior: provider?.historyBehavior,
|
|
18645
19242
|
scripts: provider?.scripts
|
|
18646
19243
|
});
|
|
18647
|
-
const lookup = history
|
|
19244
|
+
const lookup = history?.lookup === "workspace" ? "workspace" : "session";
|
|
18648
19245
|
const historyMessages = Array.isArray(history?.messages) ? normalizeNativeHistoryMessages(agentStr, history.messages, history?.providerSessionId) : [];
|
|
18649
19246
|
const historyProviderSessionId = typeof history?.providerSessionId === "string" ? history.providerSessionId : readHistorySessionIdFromMessages(historyMessages) || historySessionId;
|
|
18650
|
-
const
|
|
18651
|
-
const partialReason = typeof history?.partialReason === "string" ? history.partialReason : void 0;
|
|
18652
|
-
const unavailableReason = typeof history?.unavailableReason === "string" ? history.unavailableReason : void 0;
|
|
18653
|
-
const transcriptWorkspace = typeof history?.workspace === "string" ? history.workspace : historyMessages.map((message) => typeof message?.workspace === "string" ? message.workspace.trim() : "").find(Boolean);
|
|
18654
|
-
const safeMapping = supportsCliNativeTranscript(agentStr, provider) ? hasSafeNativeHistoryMapping({
|
|
19247
|
+
const safeMapping = supportsNative ? hasSafeNativeHistoryMapping({
|
|
18655
19248
|
historySessionId: lookup === "workspace" ? void 0 : historySessionId,
|
|
18656
19249
|
providerSessionId: lookup === "workspace" ? void 0 : historyProviderSessionId,
|
|
18657
19250
|
workspace,
|
|
18658
19251
|
nativeMessages: historyMessages
|
|
18659
19252
|
}) : false;
|
|
18660
|
-
const
|
|
18661
|
-
|
|
18662
|
-
|
|
18663
|
-
|
|
18664
|
-
|
|
19253
|
+
const machineSessionKey = String(
|
|
19254
|
+
args?.targetSessionId || historyProviderSessionId || historySessionId || h.currentSession?.sessionId || ""
|
|
19255
|
+
);
|
|
19256
|
+
const decision = decideCliReadChatSource({
|
|
19257
|
+
providerType: agentStr,
|
|
19258
|
+
provider,
|
|
19259
|
+
sessionId: machineSessionKey,
|
|
19260
|
+
nativeHistoryResult: history,
|
|
19261
|
+
safeMapping,
|
|
18665
19262
|
sessionWorkspace: workspace,
|
|
18666
19263
|
intendedWorkspace,
|
|
18667
|
-
|
|
18668
|
-
fallbackReason: nativeSelected ? void 0 : buildNativeHistoryFallbackReason({
|
|
18669
|
-
providerType: agentStr,
|
|
18670
|
-
provider,
|
|
18671
|
-
nativeSource: history.source,
|
|
18672
|
-
nativeHistoryCoverage,
|
|
18673
|
-
unavailableReason,
|
|
18674
|
-
nativeMessageCount: historyMessages.length,
|
|
18675
|
-
safeMapping,
|
|
18676
|
-
freshEnough: true
|
|
18677
|
-
}),
|
|
18678
|
-
nativeSource: history.source,
|
|
18679
|
-
sourcePath: history.sourcePath,
|
|
18680
|
-
sourceMtimeMs: history.sourceMtimeMs,
|
|
18681
|
-
nativeHistoryCoverage,
|
|
18682
|
-
partialReason,
|
|
18683
|
-
unavailableReason,
|
|
18684
|
-
nativeMessages: historyMessages,
|
|
18685
|
-
returnedMessages: historyMessages,
|
|
18686
|
-
safeMapping,
|
|
18687
|
-
freshEnough: true,
|
|
19264
|
+
ptyMessages: [],
|
|
18688
19265
|
ptyStatusApprovalOnly: false
|
|
18689
19266
|
});
|
|
18690
|
-
|
|
18691
|
-
if (requiresNativeSource && !nativeSelected) {
|
|
19267
|
+
if (supportsNative && !decision.nativeSelected) {
|
|
18692
19268
|
return {
|
|
18693
19269
|
success: false,
|
|
18694
19270
|
code: "native_history_not_safely_available",
|
|
18695
19271
|
error: "Provider-native history was not safely available for the requested CLI session.",
|
|
18696
19272
|
providerSessionId: historyProviderSessionId,
|
|
18697
|
-
messageSource,
|
|
18698
|
-
transcriptProvenance: messageSource
|
|
19273
|
+
messageSource: decision.messageSource,
|
|
19274
|
+
transcriptProvenance: decision.messageSource
|
|
18699
19275
|
};
|
|
18700
19276
|
}
|
|
18701
19277
|
return buildReadChatCommandResult({
|
|
18702
19278
|
messages: historyMessages,
|
|
18703
19279
|
status: "idle",
|
|
18704
|
-
messageSource,
|
|
18705
|
-
transcriptProvenance: messageSource,
|
|
19280
|
+
messageSource: decision.messageSource,
|
|
19281
|
+
transcriptProvenance: decision.messageSource,
|
|
18706
19282
|
...typeof history?.title === "string" ? { title: history.title } : {},
|
|
18707
19283
|
...historyProviderSessionId ? { providerSessionId: historyProviderSessionId } : {},
|
|
18708
19284
|
...provider?.historyBehavior?.transcriptAuthority === "provider" || provider?.historyBehavior?.transcriptAuthority === "daemon" ? { transcriptAuthority: (provider?.historyBehavior).transcriptAuthority } : {},
|
|
@@ -24930,6 +25506,10 @@ function validateCanonicalHistory(raw, errors) {
|
|
|
24930
25506
|
if (mode !== void 0 && !["native-source", "materialized-mirror", "disabled"].includes(String(mode))) {
|
|
24931
25507
|
errors.push("canonicalHistory.mode must be one of: native-source, materialized-mirror, disabled");
|
|
24932
25508
|
}
|
|
25509
|
+
const chatContractVersion = canonicalHistory.contractVersion;
|
|
25510
|
+
if (chatContractVersion !== void 0 && chatContractVersion !== "1.0" && chatContractVersion !== "2.0") {
|
|
25511
|
+
errors.push(`canonicalHistory.contractVersion must be '1.0' or '2.0' when provided (got ${JSON.stringify(chatContractVersion)})`);
|
|
25512
|
+
}
|
|
24933
25513
|
const scripts = canonicalHistory.scripts;
|
|
24934
25514
|
if (scripts === void 0) return;
|
|
24935
25515
|
if (!scripts || typeof scripts !== "object" || Array.isArray(scripts)) {
|
|
@@ -26168,7 +26748,7 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
26168
26748
|
return args ? args.map((arg) => /\s/.test(arg) ? JSON.stringify(arg) : arg).join(" ") : "";
|
|
26169
26749
|
}
|
|
26170
26750
|
const schemaDef = this.getSettingsSchema(providerType)[key];
|
|
26171
|
-
const defaultVal = schemaDef ?
|
|
26751
|
+
const defaultVal = schemaDef ? schemaDef.default : void 0;
|
|
26172
26752
|
const config = this.readConfig();
|
|
26173
26753
|
const userVal = config?.providerSettings?.[providerType]?.[key];
|
|
26174
26754
|
return userVal !== void 0 ? userVal : defaultVal;
|
|
@@ -26270,7 +26850,6 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
26270
26850
|
if (result.autoApprove?.type === "boolean") {
|
|
26271
26851
|
result.autoApprove = {
|
|
26272
26852
|
...result.autoApprove,
|
|
26273
|
-
default: true,
|
|
26274
26853
|
public: true,
|
|
26275
26854
|
label: result.autoApprove.label || "Auto Approve",
|
|
26276
26855
|
description: result.autoApprove.description || "Automatically approve actionable prompts without sending approval alerts."
|
|
@@ -26292,7 +26871,10 @@ var ProviderLoader = class _ProviderLoader {
|
|
|
26292
26871
|
if (!provider.settings?.autoApprove) {
|
|
26293
26872
|
result.autoApprove = {
|
|
26294
26873
|
type: "boolean",
|
|
26295
|
-
default
|
|
26874
|
+
// (fix) Safe default is *off*. Auto-approving every modal without the
|
|
26875
|
+
// user opting in produced silent-bash-execution surprises and the
|
|
26876
|
+
// "Auto-approved: ..." system-message flood seen on AGY/Codex.
|
|
26877
|
+
default: false,
|
|
26296
26878
|
public: true,
|
|
26297
26879
|
label: "Auto Approve",
|
|
26298
26880
|
description: "Automatically approve actionable prompts without sending approval alerts."
|
|
@@ -27589,15 +28171,22 @@ function getSessionMessageUpdatedAt(session) {
|
|
|
27589
28171
|
return getMessageEventTime(lastMessage);
|
|
27590
28172
|
}
|
|
27591
28173
|
function getSessionCompletionMarker(session) {
|
|
27592
|
-
const
|
|
27593
|
-
if (!
|
|
27594
|
-
|
|
27595
|
-
|
|
27596
|
-
|
|
27597
|
-
|
|
27598
|
-
|
|
27599
|
-
|
|
27600
|
-
|
|
28174
|
+
const messages = session.activeChat?.messages;
|
|
28175
|
+
if (!Array.isArray(messages) || messages.length === 0) return "";
|
|
28176
|
+
for (let i = messages.length - 1; i >= 0; i -= 1) {
|
|
28177
|
+
const m = messages[i];
|
|
28178
|
+
const role = typeof m?.role === "string" ? m.role : "";
|
|
28179
|
+
const kind = typeof m?.kind === "string" ? m.kind : "";
|
|
28180
|
+
if (role === "user" || role === "human") return "";
|
|
28181
|
+
if (role === "system") continue;
|
|
28182
|
+
if (kind === "tool") continue;
|
|
28183
|
+
if (typeof m._turnKey === "string" && m._turnKey) return `turn:${m._turnKey}`;
|
|
28184
|
+
if (typeof m.id === "string" && m.id) return `id:${m.id}`;
|
|
28185
|
+
if (typeof m.index === "number" && Number.isFinite(m.index)) return `idx:${m.index}`;
|
|
28186
|
+
const timestamp = getMessageEventTime(m);
|
|
28187
|
+
return timestamp > 0 ? `ts:${timestamp}` : "";
|
|
28188
|
+
}
|
|
28189
|
+
return "";
|
|
27601
28190
|
}
|
|
27602
28191
|
function getSessionLastUsedAt(session) {
|
|
27603
28192
|
return getSessionMessageUpdatedAt(session) || session.lastUpdated || Date.now();
|
|
@@ -27612,7 +28201,8 @@ function getUnreadState(hasContentChange, status, lastUsedAt, lastSeenAt, lastRo
|
|
|
27612
28201
|
if (status === "generating" || status === "starting") {
|
|
27613
28202
|
return { unread: false, inboxBucket: "working" };
|
|
27614
28203
|
}
|
|
27615
|
-
const
|
|
28204
|
+
const ignorableTrailingRoles = lastRole === "user" || lastRole === "human" || lastRole === "system" || lastRole === "tool";
|
|
28205
|
+
const unread = completionMarker ? seenCompletionMarker ? completionMarker !== seenCompletionMarker : hasContentChange && lastUsedAt > lastSeenAt && !ignorableTrailingRoles : hasContentChange && lastUsedAt > lastSeenAt && !ignorableTrailingRoles;
|
|
27616
28206
|
return { unread, inboxBucket: unread ? "task_complete" : "idle" };
|
|
27617
28207
|
}
|
|
27618
28208
|
function projectLiveSessionFromFull(session) {
|
|
@@ -30976,7 +31566,8 @@ var DaemonCommandRouter = class {
|
|
|
30976
31566
|
}
|
|
30977
31567
|
case "get_pending_mesh_events": {
|
|
30978
31568
|
const meshId = typeof args?.meshId === "string" ? args.meshId.trim() : "";
|
|
30979
|
-
const
|
|
31569
|
+
const coordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : void 0;
|
|
31570
|
+
const events = drainPendingMeshCoordinatorEvents(meshId || void 0, coordinatorDaemonId);
|
|
30980
31571
|
return { success: true, events };
|
|
30981
31572
|
}
|
|
30982
31573
|
case "launch_cli":
|
|
@@ -32952,7 +33543,8 @@ ${block2}`);
|
|
|
32952
33543
|
finalizeMeshNodeStatus({ status, node, daemonId, isSelfNode });
|
|
32953
33544
|
nodeStatuses.push(status);
|
|
32954
33545
|
}
|
|
32955
|
-
const
|
|
33546
|
+
const callerCoordinatorDaemonId = typeof args?.coordinatorDaemonId === "string" && args.coordinatorDaemonId.trim() ? args.coordinatorDaemonId.trim() : void 0;
|
|
33547
|
+
const pendingCoordinatorEvents = drainPendingMeshCoordinatorEvents(meshId, callerCoordinatorDaemonId);
|
|
32956
33548
|
const previewFreshness = (() => {
|
|
32957
33549
|
const localRepoRoot = nodeStatuses.map((node) => readStringValue(node?.git?.repoRoot, node?.repoRoot, node?.workspace)).find((candidate) => !!candidate && fs11.existsSync(candidate));
|
|
32958
33550
|
return localRepoRoot ? buildPreviewFreshness(localRepoRoot) : void 0;
|
|
@@ -33430,6 +34022,7 @@ function prepareSessionChatTailUpdate(input) {
|
|
|
33430
34022
|
const title = typeof result.title === "string" ? result.title : void 0;
|
|
33431
34023
|
const activeModal = normalizeChatTailActiveModal(result.activeModal);
|
|
33432
34024
|
const status = typeof result.status === "string" ? result.status : "idle";
|
|
34025
|
+
const messageSource = result.messageSource && typeof result.messageSource === "object" ? result.messageSource : void 0;
|
|
33433
34026
|
const deliverySignature = buildChatTailDeliverySignature({
|
|
33434
34027
|
sessionId: input.sessionId,
|
|
33435
34028
|
...input.historySessionId ? { historySessionId: input.historySessionId } : {},
|
|
@@ -33462,7 +34055,8 @@ function prepareSessionChatTailUpdate(input) {
|
|
|
33462
34055
|
messages,
|
|
33463
34056
|
status,
|
|
33464
34057
|
...title ? { title } : {},
|
|
33465
|
-
...activeModal ? { activeModal } : {}
|
|
34058
|
+
...activeModal ? { activeModal } : {},
|
|
34059
|
+
...messageSource ? { messageSource } : {}
|
|
33466
34060
|
}
|
|
33467
34061
|
};
|
|
33468
34062
|
}
|