@adhdev/daemon-core 0.9.64 → 0.9.66
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/chat-signatures.d.ts +0 -4
- package/dist/chat/chat-signatures.js +0 -4
- package/dist/chat/chat-signatures.js.map +1 -1
- package/dist/chat/chat-signatures.mjs +0 -4
- package/dist/chat/chat-signatures.mjs.map +1 -1
- package/dist/chat/subscription-updates.d.ts +0 -2
- package/dist/cli-adapters/provider-cli-adapter.d.ts +2 -30
- package/dist/cli-adapters/provider-cli-parse.d.ts +1 -8
- package/dist/cli-adapters/provider-cli-shared.d.ts +8 -3
- package/dist/commands/chat-commands.d.ts +0 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.js +646 -1712
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +646 -1712
- package/dist/index.mjs.map +1 -1
- package/dist/shared-types.d.ts +0 -7
- package/node_modules/@adhdev/session-host-core/package.json +1 -1
- package/package.json +1 -1
- package/src/chat/chat-signatures.ts +0 -8
- package/src/chat/subscription-updates.ts +7 -46
- package/src/cli-adapters/provider-cli-adapter.d.ts +2 -10
- package/src/cli-adapters/provider-cli-adapter.ts +66 -692
- package/src/cli-adapters/provider-cli-parse.d.ts +0 -7
- package/src/cli-adapters/provider-cli-parse.ts +2 -226
- package/src/cli-adapters/provider-cli-shared.d.ts +0 -1
- package/src/cli-adapters/provider-cli-shared.ts +8 -3
- package/src/commands/chat-commands.ts +54 -366
- package/src/daemon/dev-auto-implement.ts +3 -3
- package/src/daemon/dev-server.ts +3 -3
- package/src/index.d.ts +1 -1
- package/src/index.ts +0 -1
- package/src/launch.ts +10 -3
- package/src/providers/cli-provider-instance.ts +2 -39
- package/src/shared-types.d.ts +0 -7
- package/src/shared-types.ts +0 -8
package/dist/index.js
CHANGED
|
@@ -482,525 +482,6 @@ var init_logger = __esm({
|
|
|
482
482
|
}
|
|
483
483
|
});
|
|
484
484
|
|
|
485
|
-
// src/providers/io-contracts.ts
|
|
486
|
-
function normalizeInputEnvelope(input) {
|
|
487
|
-
const normalized = normalizeInputEnvelopePayload(input);
|
|
488
|
-
const textFallback = normalized.textFallback ?? flattenInputParts(normalized.parts);
|
|
489
|
-
return {
|
|
490
|
-
parts: normalized.parts,
|
|
491
|
-
textFallback,
|
|
492
|
-
...normalized.metadata ? { metadata: normalized.metadata } : {}
|
|
493
|
-
};
|
|
494
|
-
}
|
|
495
|
-
function normalizeMessageParts(content) {
|
|
496
|
-
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
497
|
-
if (!Array.isArray(content)) {
|
|
498
|
-
if (content && typeof content === "object" && typeof content.text === "string") {
|
|
499
|
-
return [{ type: "text", text: String(content.text) }];
|
|
500
|
-
}
|
|
501
|
-
return [];
|
|
502
|
-
}
|
|
503
|
-
const parts = [];
|
|
504
|
-
for (const raw of content) {
|
|
505
|
-
if (typeof raw === "string") {
|
|
506
|
-
parts.push({ type: "text", text: raw });
|
|
507
|
-
continue;
|
|
508
|
-
}
|
|
509
|
-
if (!raw || typeof raw !== "object") continue;
|
|
510
|
-
const part = normalizeMessagePartObject(raw);
|
|
511
|
-
if (part) parts.push(part);
|
|
512
|
-
}
|
|
513
|
-
return parts;
|
|
514
|
-
}
|
|
515
|
-
function flattenMessageParts(parts) {
|
|
516
|
-
return parts.map((part) => {
|
|
517
|
-
if (part.type === "text") return part.text;
|
|
518
|
-
if (part.type === "resource") return part.resource.text || "";
|
|
519
|
-
return "";
|
|
520
|
-
}).filter((value) => value.length > 0).join("\n");
|
|
521
|
-
}
|
|
522
|
-
function normalizeInputEnvelopePayload(input) {
|
|
523
|
-
if (typeof input === "string") {
|
|
524
|
-
return { parts: [{ type: "text", text: input }], textFallback: input };
|
|
525
|
-
}
|
|
526
|
-
if (!input || typeof input !== "object") {
|
|
527
|
-
return { parts: [], textFallback: "" };
|
|
528
|
-
}
|
|
529
|
-
const record = input;
|
|
530
|
-
const nestedInput = record.input;
|
|
531
|
-
if (nestedInput && typeof nestedInput === "object") {
|
|
532
|
-
const nested = nestedInput;
|
|
533
|
-
return {
|
|
534
|
-
parts: normalizeInputParts(nested.parts ?? nested.prompt),
|
|
535
|
-
textFallback: typeof nested.textFallback === "string" ? nested.textFallback : void 0,
|
|
536
|
-
metadata: normalizeInputMetadata(nested.metadata)
|
|
537
|
-
};
|
|
538
|
-
}
|
|
539
|
-
const directText = typeof record.text === "string" ? record.text : typeof record.message === "string" ? record.message : void 0;
|
|
540
|
-
if (directText !== void 0) {
|
|
541
|
-
return { parts: [{ type: "text", text: directText }], textFallback: directText };
|
|
542
|
-
}
|
|
543
|
-
const directParts = normalizeInputParts(record.parts ?? record.prompt);
|
|
544
|
-
return {
|
|
545
|
-
parts: directParts,
|
|
546
|
-
textFallback: typeof record.textFallback === "string" ? record.textFallback : void 0,
|
|
547
|
-
metadata: normalizeInputMetadata(record.metadata)
|
|
548
|
-
};
|
|
549
|
-
}
|
|
550
|
-
function normalizeInputMetadata(value) {
|
|
551
|
-
if (!value || typeof value !== "object") return void 0;
|
|
552
|
-
const record = value;
|
|
553
|
-
const metadata = {};
|
|
554
|
-
if (record.source === "dashboard" || record.source === "shortcut_api" || record.source === "provider_script" || record.source === "session_replay") {
|
|
555
|
-
metadata.source = record.source;
|
|
556
|
-
}
|
|
557
|
-
if (typeof record.clientTimestamp === "number" && Number.isFinite(record.clientTimestamp)) {
|
|
558
|
-
metadata.clientTimestamp = record.clientTimestamp;
|
|
559
|
-
}
|
|
560
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
561
|
-
}
|
|
562
|
-
function normalizeInputParts(value) {
|
|
563
|
-
if (!Array.isArray(value)) return [];
|
|
564
|
-
const parts = [];
|
|
565
|
-
for (const raw of value) {
|
|
566
|
-
if (typeof raw === "string") {
|
|
567
|
-
parts.push({ type: "text", text: raw });
|
|
568
|
-
continue;
|
|
569
|
-
}
|
|
570
|
-
if (!raw || typeof raw !== "object") continue;
|
|
571
|
-
const part = normalizeInputPartObject(raw);
|
|
572
|
-
if (part) parts.push(part);
|
|
573
|
-
}
|
|
574
|
-
return parts;
|
|
575
|
-
}
|
|
576
|
-
function normalizeInputPartObject(raw) {
|
|
577
|
-
const type = raw.type;
|
|
578
|
-
if (type === "text" && typeof raw.text === "string") {
|
|
579
|
-
return { type, text: raw.text };
|
|
580
|
-
}
|
|
581
|
-
if (type === "image" && typeof raw.mimeType === "string") {
|
|
582
|
-
return {
|
|
583
|
-
type,
|
|
584
|
-
mimeType: raw.mimeType,
|
|
585
|
-
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
586
|
-
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
587
|
-
...typeof raw.alt === "string" ? { alt: raw.alt } : {}
|
|
588
|
-
};
|
|
589
|
-
}
|
|
590
|
-
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
591
|
-
return {
|
|
592
|
-
type,
|
|
593
|
-
mimeType: raw.mimeType,
|
|
594
|
-
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
595
|
-
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
596
|
-
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
|
|
597
|
-
};
|
|
598
|
-
}
|
|
599
|
-
if (type === "video" && typeof raw.mimeType === "string") {
|
|
600
|
-
return {
|
|
601
|
-
type,
|
|
602
|
-
mimeType: raw.mimeType,
|
|
603
|
-
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
604
|
-
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
605
|
-
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
606
|
-
};
|
|
607
|
-
}
|
|
608
|
-
if (type === "resource" && typeof raw.uri === "string") {
|
|
609
|
-
return {
|
|
610
|
-
type,
|
|
611
|
-
uri: raw.uri,
|
|
612
|
-
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
613
|
-
...typeof raw.name === "string" ? { name: raw.name } : {},
|
|
614
|
-
...typeof raw.text === "string" ? { text: raw.text } : {},
|
|
615
|
-
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
616
|
-
};
|
|
617
|
-
}
|
|
618
|
-
if (type === "resource_link" && typeof raw.uri === "string") {
|
|
619
|
-
return {
|
|
620
|
-
type: "resource",
|
|
621
|
-
uri: raw.uri,
|
|
622
|
-
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
623
|
-
...typeof raw.name === "string" ? { name: raw.name } : {}
|
|
624
|
-
};
|
|
625
|
-
}
|
|
626
|
-
return null;
|
|
627
|
-
}
|
|
628
|
-
function normalizeMessagePartObject(raw) {
|
|
629
|
-
const type = raw.type;
|
|
630
|
-
if (type === "text" && typeof raw.text === "string") {
|
|
631
|
-
return { type, text: raw.text };
|
|
632
|
-
}
|
|
633
|
-
if (type === "image" && typeof raw.mimeType === "string") {
|
|
634
|
-
return {
|
|
635
|
-
type,
|
|
636
|
-
mimeType: raw.mimeType,
|
|
637
|
-
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
638
|
-
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
639
|
-
};
|
|
640
|
-
}
|
|
641
|
-
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
642
|
-
return {
|
|
643
|
-
type,
|
|
644
|
-
mimeType: raw.mimeType,
|
|
645
|
-
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
646
|
-
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
647
|
-
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
|
|
648
|
-
};
|
|
649
|
-
}
|
|
650
|
-
if (type === "video" && typeof raw.mimeType === "string") {
|
|
651
|
-
return {
|
|
652
|
-
type,
|
|
653
|
-
mimeType: raw.mimeType,
|
|
654
|
-
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
655
|
-
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
656
|
-
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
657
|
-
};
|
|
658
|
-
}
|
|
659
|
-
if (type === "resource_link" && typeof raw.uri === "string" && typeof raw.name === "string") {
|
|
660
|
-
return {
|
|
661
|
-
type,
|
|
662
|
-
uri: raw.uri,
|
|
663
|
-
name: raw.name,
|
|
664
|
-
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
665
|
-
...typeof raw.size === "number" ? { size: raw.size } : {}
|
|
666
|
-
};
|
|
667
|
-
}
|
|
668
|
-
if (type === "resource" && raw.resource && typeof raw.resource === "object") {
|
|
669
|
-
const resource = raw.resource;
|
|
670
|
-
if (typeof resource.uri !== "string") return null;
|
|
671
|
-
return {
|
|
672
|
-
type,
|
|
673
|
-
resource: {
|
|
674
|
-
uri: resource.uri,
|
|
675
|
-
...typeof resource.mimeType === "string" || resource.mimeType === null ? { mimeType: resource.mimeType } : {},
|
|
676
|
-
...typeof resource.text === "string" ? { text: resource.text } : {},
|
|
677
|
-
...typeof resource.blob === "string" ? { blob: resource.blob } : {}
|
|
678
|
-
}
|
|
679
|
-
};
|
|
680
|
-
}
|
|
681
|
-
return null;
|
|
682
|
-
}
|
|
683
|
-
function flattenInputParts(parts) {
|
|
684
|
-
return parts.map((part) => {
|
|
685
|
-
if (part.type === "text") return part.text;
|
|
686
|
-
if (part.type === "audio") return part.transcript || "";
|
|
687
|
-
if (part.type === "resource") return part.text || "";
|
|
688
|
-
return "";
|
|
689
|
-
}).filter((value) => value.length > 0).join("\n");
|
|
690
|
-
}
|
|
691
|
-
var init_io_contracts = __esm({
|
|
692
|
-
"src/providers/io-contracts.ts"() {
|
|
693
|
-
"use strict";
|
|
694
|
-
}
|
|
695
|
-
});
|
|
696
|
-
|
|
697
|
-
// src/providers/contracts.ts
|
|
698
|
-
function flattenContent(content) {
|
|
699
|
-
if (typeof content === "string") return content;
|
|
700
|
-
return flattenMessageParts(normalizeMessageParts(content));
|
|
701
|
-
}
|
|
702
|
-
var init_contracts = __esm({
|
|
703
|
-
"src/providers/contracts.ts"() {
|
|
704
|
-
"use strict";
|
|
705
|
-
init_io_contracts();
|
|
706
|
-
init_io_contracts();
|
|
707
|
-
}
|
|
708
|
-
});
|
|
709
|
-
|
|
710
|
-
// src/providers/chat-message-normalization.ts
|
|
711
|
-
function canonicalizeKindHint(value) {
|
|
712
|
-
return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
713
|
-
}
|
|
714
|
-
function resolveBuiltinOrAliasKind(kind) {
|
|
715
|
-
if (typeof kind !== "string") return null;
|
|
716
|
-
const normalizedKind = canonicalizeKindHint(kind);
|
|
717
|
-
if (!normalizedKind) return null;
|
|
718
|
-
if (KNOWN_CHAT_MESSAGE_KINDS.has(normalizedKind)) return normalizedKind;
|
|
719
|
-
return CHAT_MESSAGE_KIND_ALIASES[normalizedKind] || null;
|
|
720
|
-
}
|
|
721
|
-
function inferHintKind(value) {
|
|
722
|
-
const direct = resolveBuiltinOrAliasKind(value);
|
|
723
|
-
if (direct) return direct;
|
|
724
|
-
if (typeof value !== "string") return null;
|
|
725
|
-
const normalized = canonicalizeKindHint(value);
|
|
726
|
-
if (!normalized) return null;
|
|
727
|
-
if (/thought|thinking|reasoning/.test(normalized)) return "thought";
|
|
728
|
-
if (/tool/.test(normalized)) return "tool";
|
|
729
|
-
if (/terminal|command|shell|console/.test(normalized)) return "terminal";
|
|
730
|
-
return null;
|
|
731
|
-
}
|
|
732
|
-
function inferKindFromToolCalls(message) {
|
|
733
|
-
const toolCalls = Array.isArray(message?.toolCalls) ? message.toolCalls : [];
|
|
734
|
-
if (toolCalls.length === 0) return null;
|
|
735
|
-
if (toolCalls.some((toolCall) => toolCall?.kind === "think")) return "thought";
|
|
736
|
-
if (toolCalls.some((toolCall) => toolCall?.kind === "execute")) return "terminal";
|
|
737
|
-
if (toolCalls.some((toolCall) => Array.isArray(toolCall?.content) && toolCall.content.some((entry) => entry?.type === "terminal"))) {
|
|
738
|
-
return "terminal";
|
|
739
|
-
}
|
|
740
|
-
return "tool";
|
|
741
|
-
}
|
|
742
|
-
function inferMissingChatMessageKind(message) {
|
|
743
|
-
const role = typeof message?.role === "string" ? message.role.trim().toLowerCase() : "";
|
|
744
|
-
if (role === "system") return "system";
|
|
745
|
-
const meta = message?.meta && typeof message.meta === "object" ? message.meta : void 0;
|
|
746
|
-
const hintCandidates = [
|
|
747
|
-
message?._sub,
|
|
748
|
-
message?._type,
|
|
749
|
-
meta?.label,
|
|
750
|
-
typeof message?.senderName === "string" ? message.senderName : void 0
|
|
751
|
-
];
|
|
752
|
-
for (const candidate of hintCandidates) {
|
|
753
|
-
const inferred = inferHintKind(candidate);
|
|
754
|
-
if (inferred) return inferred;
|
|
755
|
-
}
|
|
756
|
-
const inferredFromToolCalls = inferKindFromToolCalls(message);
|
|
757
|
-
if (inferredFromToolCalls) return inferredFromToolCalls;
|
|
758
|
-
return null;
|
|
759
|
-
}
|
|
760
|
-
function isBuiltinChatMessageKind(kind) {
|
|
761
|
-
return resolveBuiltinOrAliasKind(kind) !== null;
|
|
762
|
-
}
|
|
763
|
-
function normalizeChatMessageKind(kind, role) {
|
|
764
|
-
const resolvedKind = resolveBuiltinOrAliasKind(kind);
|
|
765
|
-
if (resolvedKind) return resolvedKind;
|
|
766
|
-
const normalizedRole = typeof role === "string" ? role.trim().toLowerCase() : "";
|
|
767
|
-
return normalizedRole === "system" ? "system" : "standard";
|
|
768
|
-
}
|
|
769
|
-
function resolveChatMessageKind(message) {
|
|
770
|
-
const explicitKind = resolveBuiltinOrAliasKind(message?.kind);
|
|
771
|
-
if (explicitKind) return explicitKind;
|
|
772
|
-
const inferredKind = inferMissingChatMessageKind(message);
|
|
773
|
-
if (inferredKind) return inferredKind;
|
|
774
|
-
return normalizeChatMessageKind(message?.kind, message?.role);
|
|
775
|
-
}
|
|
776
|
-
function buildChatMessage(message) {
|
|
777
|
-
return {
|
|
778
|
-
...message,
|
|
779
|
-
kind: resolveChatMessageKind(message)
|
|
780
|
-
};
|
|
781
|
-
}
|
|
782
|
-
function buildSystemChatMessage(message) {
|
|
783
|
-
return buildChatMessage({
|
|
784
|
-
...message,
|
|
785
|
-
role: "system",
|
|
786
|
-
kind: message?.kind || "system"
|
|
787
|
-
});
|
|
788
|
-
}
|
|
789
|
-
function buildRuntimeSystemChatMessage(message) {
|
|
790
|
-
return buildSystemChatMessage({
|
|
791
|
-
...message,
|
|
792
|
-
senderName: typeof message?.senderName === "string" && message.senderName.trim() ? message.senderName : "System"
|
|
793
|
-
});
|
|
794
|
-
}
|
|
795
|
-
function buildAssistantChatMessage(message) {
|
|
796
|
-
return buildChatMessage({
|
|
797
|
-
...message,
|
|
798
|
-
role: "assistant",
|
|
799
|
-
kind: message?.kind || "standard"
|
|
800
|
-
});
|
|
801
|
-
}
|
|
802
|
-
function buildThoughtChatMessage(message) {
|
|
803
|
-
return buildAssistantChatMessage({
|
|
804
|
-
...message,
|
|
805
|
-
kind: message?.kind || "thought"
|
|
806
|
-
});
|
|
807
|
-
}
|
|
808
|
-
function buildToolChatMessage(message) {
|
|
809
|
-
return buildAssistantChatMessage({
|
|
810
|
-
...message,
|
|
811
|
-
kind: message?.kind || "tool"
|
|
812
|
-
});
|
|
813
|
-
}
|
|
814
|
-
function buildTerminalChatMessage(message) {
|
|
815
|
-
return buildAssistantChatMessage({
|
|
816
|
-
...message,
|
|
817
|
-
kind: message?.kind || "terminal"
|
|
818
|
-
});
|
|
819
|
-
}
|
|
820
|
-
function buildUserChatMessage(message) {
|
|
821
|
-
return buildChatMessage({
|
|
822
|
-
...message,
|
|
823
|
-
role: "user",
|
|
824
|
-
kind: message?.kind || "standard"
|
|
825
|
-
});
|
|
826
|
-
}
|
|
827
|
-
function normalizeChatMessage(message) {
|
|
828
|
-
return buildChatMessage(message);
|
|
829
|
-
}
|
|
830
|
-
function normalizeChatMessages(messages) {
|
|
831
|
-
return (Array.isArray(messages) ? messages : []).map((message) => normalizeChatMessage(message));
|
|
832
|
-
}
|
|
833
|
-
var BUILTIN_CHAT_MESSAGE_KINDS, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES;
|
|
834
|
-
var init_chat_message_normalization = __esm({
|
|
835
|
-
"src/providers/chat-message-normalization.ts"() {
|
|
836
|
-
"use strict";
|
|
837
|
-
BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
|
|
838
|
-
KNOWN_CHAT_MESSAGE_KINDS = new Set(BUILTIN_CHAT_MESSAGE_KINDS);
|
|
839
|
-
CHAT_MESSAGE_KIND_ALIASES = {
|
|
840
|
-
text: "standard",
|
|
841
|
-
message: "standard",
|
|
842
|
-
assistant: "standard",
|
|
843
|
-
thinking: "thought",
|
|
844
|
-
think: "thought",
|
|
845
|
-
reasoning: "thought",
|
|
846
|
-
reason: "thought",
|
|
847
|
-
toolcall: "tool",
|
|
848
|
-
tool_call: "tool",
|
|
849
|
-
tooluse: "tool",
|
|
850
|
-
tool_use: "tool",
|
|
851
|
-
action: "tool",
|
|
852
|
-
command: "terminal",
|
|
853
|
-
cmd: "terminal",
|
|
854
|
-
shell: "terminal",
|
|
855
|
-
console: "terminal"
|
|
856
|
-
};
|
|
857
|
-
}
|
|
858
|
-
});
|
|
859
|
-
|
|
860
|
-
// src/providers/read-chat-contract.ts
|
|
861
|
-
function isPlainObject3(value) {
|
|
862
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
863
|
-
}
|
|
864
|
-
function isFiniteNumber(value) {
|
|
865
|
-
return typeof value === "number" && Number.isFinite(value);
|
|
866
|
-
}
|
|
867
|
-
function validateStatus(status, source) {
|
|
868
|
-
if (typeof status !== "string" || !VALID_STATUSES.includes(status)) {
|
|
869
|
-
throw new Error(`${source}: status must be one of ${VALID_STATUSES.join(", ")}`);
|
|
870
|
-
}
|
|
871
|
-
return status;
|
|
872
|
-
}
|
|
873
|
-
function validateRole(role, source, index) {
|
|
874
|
-
if (typeof role !== "string" || !VALID_ROLES.includes(role)) {
|
|
875
|
-
throw new Error(`${source}: messages[${index}].role must be one of ${VALID_ROLES.join(", ")}`);
|
|
876
|
-
}
|
|
877
|
-
return role;
|
|
878
|
-
}
|
|
879
|
-
function validateBubbleState(state, source, index) {
|
|
880
|
-
if (typeof state !== "string" || !VALID_BUBBLE_STATES.includes(state)) {
|
|
881
|
-
throw new Error(`${source}: messages[${index}].bubbleState must be one of ${VALID_BUBBLE_STATES.join(", ")}`);
|
|
882
|
-
}
|
|
883
|
-
return state;
|
|
884
|
-
}
|
|
885
|
-
function validateTurnStatus(turnStatus, source) {
|
|
886
|
-
if (typeof turnStatus !== "string" || !VALID_TURN_STATUSES.includes(turnStatus)) {
|
|
887
|
-
throw new Error(`${source}: turnStatus must be one of ${VALID_TURN_STATUSES.join(", ")}`);
|
|
888
|
-
}
|
|
889
|
-
return turnStatus;
|
|
890
|
-
}
|
|
891
|
-
function validateMessageContent(content, source, index) {
|
|
892
|
-
if (typeof content === "string") return content;
|
|
893
|
-
if (Array.isArray(content)) return normalizeMessageParts(content);
|
|
894
|
-
throw new Error(`${source}: messages[${index}].content must be a string or structured content array`);
|
|
895
|
-
}
|
|
896
|
-
function validateMessage(message, source, index) {
|
|
897
|
-
if (!isPlainObject3(message)) {
|
|
898
|
-
throw new Error(`${source}: messages[${index}] must be an object`);
|
|
899
|
-
}
|
|
900
|
-
const normalized = {
|
|
901
|
-
role: validateRole(message.role, source, index),
|
|
902
|
-
content: validateMessageContent(message.content, source, index)
|
|
903
|
-
};
|
|
904
|
-
if (typeof message.kind === "string") normalized.kind = message.kind;
|
|
905
|
-
if (typeof message.id === "string") normalized.id = message.id;
|
|
906
|
-
if (typeof message.bubbleId === "string") normalized.bubbleId = message.bubbleId;
|
|
907
|
-
if (typeof message.providerUnitKey === "string") normalized.providerUnitKey = message.providerUnitKey;
|
|
908
|
-
if (message.bubbleState !== void 0) normalized.bubbleState = validateBubbleState(message.bubbleState, source, index);
|
|
909
|
-
if (isFiniteNumber(message.index)) normalized.index = message.index;
|
|
910
|
-
if (isFiniteNumber(message.timestamp)) normalized.timestamp = message.timestamp;
|
|
911
|
-
if (isFiniteNumber(message.receivedAt)) normalized.receivedAt = message.receivedAt;
|
|
912
|
-
if (typeof message._turnKey === "string") normalized._turnKey = message._turnKey;
|
|
913
|
-
if (Array.isArray(message.toolCalls)) normalized.toolCalls = message.toolCalls;
|
|
914
|
-
if (isPlainObject3(message.meta)) normalized.meta = message.meta;
|
|
915
|
-
if (typeof message.senderName === "string") normalized.senderName = message.senderName;
|
|
916
|
-
if (typeof message._type === "string") normalized._type = message._type;
|
|
917
|
-
if (typeof message._sub === "string") normalized._sub = message._sub;
|
|
918
|
-
return normalized;
|
|
919
|
-
}
|
|
920
|
-
function validateModal(activeModal, status, source) {
|
|
921
|
-
if (activeModal == null) {
|
|
922
|
-
if (status === "waiting_approval") {
|
|
923
|
-
throw new Error(`${source}: waiting_approval status requires activeModal with buttons`);
|
|
924
|
-
}
|
|
925
|
-
return activeModal === null ? null : void 0;
|
|
926
|
-
}
|
|
927
|
-
if (!isPlainObject3(activeModal)) {
|
|
928
|
-
throw new Error(`${source}: activeModal must be an object when provided`);
|
|
929
|
-
}
|
|
930
|
-
if (typeof activeModal.message !== "string") {
|
|
931
|
-
throw new Error(`${source}: activeModal.message must be a string`);
|
|
932
|
-
}
|
|
933
|
-
if (!Array.isArray(activeModal.buttons) || activeModal.buttons.some((button) => typeof button !== "string" || !button.trim())) {
|
|
934
|
-
throw new Error(`${source}: activeModal.buttons must be a non-empty string array`);
|
|
935
|
-
}
|
|
936
|
-
const normalized = {
|
|
937
|
-
message: activeModal.message,
|
|
938
|
-
buttons: activeModal.buttons.map((button) => button.trim())
|
|
939
|
-
};
|
|
940
|
-
if (isFiniteNumber(activeModal.width)) normalized.width = activeModal.width;
|
|
941
|
-
if (isFiniteNumber(activeModal.height)) normalized.height = activeModal.height;
|
|
942
|
-
return normalized;
|
|
943
|
-
}
|
|
944
|
-
function validateControlValues(controlValues, source) {
|
|
945
|
-
if (controlValues === void 0) return void 0;
|
|
946
|
-
if (!isPlainObject3(controlValues)) {
|
|
947
|
-
throw new Error(`${source}: controlValues must be an object when provided`);
|
|
948
|
-
}
|
|
949
|
-
const normalized = {};
|
|
950
|
-
for (const [key, value] of Object.entries(controlValues)) {
|
|
951
|
-
if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") {
|
|
952
|
-
throw new Error(`${source}: controlValues.${key} must be string, number, or boolean`);
|
|
953
|
-
}
|
|
954
|
-
normalized[key] = value;
|
|
955
|
-
}
|
|
956
|
-
return normalized;
|
|
957
|
-
}
|
|
958
|
-
function validateReadChatResultPayload(raw, source = "read_chat") {
|
|
959
|
-
if (!isPlainObject3(raw)) {
|
|
960
|
-
throw new Error(`${source}: payload must be an object`);
|
|
961
|
-
}
|
|
962
|
-
const status = validateStatus(raw.status, source);
|
|
963
|
-
if (!Array.isArray(raw.messages)) {
|
|
964
|
-
throw new Error(`${source}: messages must be an array`);
|
|
965
|
-
}
|
|
966
|
-
const messages = raw.messages.map((message, index) => validateMessage(message, source, index));
|
|
967
|
-
const activeModal = validateModal(raw.activeModal, status, source);
|
|
968
|
-
const controlValues = validateControlValues(raw.controlValues, source);
|
|
969
|
-
const normalized = {
|
|
970
|
-
status,
|
|
971
|
-
messages
|
|
972
|
-
};
|
|
973
|
-
if (activeModal !== void 0) normalized.activeModal = activeModal;
|
|
974
|
-
if (typeof raw.id === "string") normalized.id = raw.id;
|
|
975
|
-
if (typeof raw.title === "string") normalized.title = raw.title;
|
|
976
|
-
if (typeof raw.currentTurnId === "string") normalized.currentTurnId = raw.currentTurnId;
|
|
977
|
-
if (raw.turnStatus !== void 0) normalized.turnStatus = validateTurnStatus(raw.turnStatus, source);
|
|
978
|
-
if (typeof raw.agentType === "string") normalized.agentType = raw.agentType;
|
|
979
|
-
if (typeof raw.agentName === "string") normalized.agentName = raw.agentName;
|
|
980
|
-
if (typeof raw.extensionId === "string") normalized.extensionId = raw.extensionId;
|
|
981
|
-
if (typeof raw.inputContent === "string") normalized.inputContent = raw.inputContent;
|
|
982
|
-
if (typeof raw.isVisible === "boolean") normalized.isVisible = raw.isVisible;
|
|
983
|
-
if (typeof raw.isWelcomeScreen === "boolean") normalized.isWelcomeScreen = raw.isWelcomeScreen;
|
|
984
|
-
if (controlValues) normalized.controlValues = controlValues;
|
|
985
|
-
if (raw.summaryMetadata !== void 0) normalized.summaryMetadata = raw.summaryMetadata;
|
|
986
|
-
if (Array.isArray(raw.effects)) normalized.effects = raw.effects;
|
|
987
|
-
if (typeof raw.providerSessionId === "string") normalized.providerSessionId = raw.providerSessionId;
|
|
988
|
-
if (raw.transcriptAuthority === "provider" || raw.transcriptAuthority === "daemon") normalized.transcriptAuthority = raw.transcriptAuthority;
|
|
989
|
-
if (raw.coverage === "full" || raw.coverage === "tail" || raw.coverage === "current-turn") normalized.coverage = raw.coverage;
|
|
990
|
-
return normalized;
|
|
991
|
-
}
|
|
992
|
-
var VALID_STATUSES, VALID_ROLES, VALID_BUBBLE_STATES, VALID_TURN_STATUSES;
|
|
993
|
-
var init_read_chat_contract = __esm({
|
|
994
|
-
"src/providers/read-chat-contract.ts"() {
|
|
995
|
-
"use strict";
|
|
996
|
-
init_contracts();
|
|
997
|
-
VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "streaming", "long_generating"];
|
|
998
|
-
VALID_ROLES = ["user", "assistant", "system", "human"];
|
|
999
|
-
VALID_BUBBLE_STATES = ["draft", "streaming", "final", "removed"];
|
|
1000
|
-
VALID_TURN_STATUSES = ["open", "waiting_approval", "complete", "error"];
|
|
1001
|
-
}
|
|
1002
|
-
});
|
|
1003
|
-
|
|
1004
485
|
// src/logging/debug-config.ts
|
|
1005
486
|
function normalizeCategories(categories) {
|
|
1006
487
|
if (!Array.isArray(categories)) return [];
|
|
@@ -1562,67 +1043,6 @@ function promptLikelyVisible(screenText, promptSnippet) {
|
|
|
1562
1043
|
function normalizeScreenSnapshot(text) {
|
|
1563
1044
|
return sanitizeTerminalText(String(text || "")).replace(/\s+/g, " ").trim();
|
|
1564
1045
|
}
|
|
1565
|
-
function shouldReflowComparableMessageLines(lines) {
|
|
1566
|
-
return Array.isArray(lines) && lines.length > 1 && lines.slice(0, -1).every((line) => String(line || "").trim().length >= 48) && !lines.some((line) => /^```/.test(line)) && !lines.some((line) => /^\|/.test(line)) && !lines.some((line) => /^\s*(?:[-*+] |\d+\.\s)/.test(line));
|
|
1567
|
-
}
|
|
1568
|
-
function joinComparableMessageLines(lines) {
|
|
1569
|
-
return lines.reduce((acc, line) => {
|
|
1570
|
-
const next = String(line || "").trim();
|
|
1571
|
-
if (!next) return acc;
|
|
1572
|
-
if (!acc) return next;
|
|
1573
|
-
if (/[,\d]$/.test(acc) && /^\d/.test(next)) {
|
|
1574
|
-
return `${acc}${next}`;
|
|
1575
|
-
}
|
|
1576
|
-
if (/[A-Za-z]$/.test(acc) && /^\d/.test(next)) {
|
|
1577
|
-
return `${acc}${next}`;
|
|
1578
|
-
}
|
|
1579
|
-
const fragmentMatch = acc.match(/([A-Za-z]{1,4})$/);
|
|
1580
|
-
const fragment = fragmentMatch ? fragmentMatch[1].toLowerCase() : "";
|
|
1581
|
-
if (/^[a-z]/.test(next) && fragment && !COMMON_COMPARABLE_WRAP_WORDS.has(fragment)) {
|
|
1582
|
-
return `${acc}${next}`;
|
|
1583
|
-
}
|
|
1584
|
-
return `${acc} ${next}`;
|
|
1585
|
-
}, "").replace(/\s+([,.;:!?])/g, "$1").replace(/(\d)\s+,/g, "$1,").replace(/\s+/g, " ").trim();
|
|
1586
|
-
}
|
|
1587
|
-
function normalizeComparableMessageContent(text) {
|
|
1588
|
-
const lines = String(text || "").split(/\r\n|\n|\r/g).map((line) => line.trim()).filter(Boolean);
|
|
1589
|
-
if (lines.length === 0) return "";
|
|
1590
|
-
if (shouldReflowComparableMessageLines(lines)) {
|
|
1591
|
-
return joinComparableMessageLines(lines);
|
|
1592
|
-
}
|
|
1593
|
-
return lines.join(" ").replace(/\s+/g, " ").trim();
|
|
1594
|
-
}
|
|
1595
|
-
function trimPromptEchoPrefix(text, promptText) {
|
|
1596
|
-
const prompt = normalizeComparableMessageContent(String(promptText || ""));
|
|
1597
|
-
if (!prompt) return String(text || "");
|
|
1598
|
-
const lines = String(text || "").split(/\r\n|\n|\r/g);
|
|
1599
|
-
let dropCount = 0;
|
|
1600
|
-
for (let index = 0; index < Math.min(lines.length, 6); index += 1) {
|
|
1601
|
-
const fragment = normalizeComparableMessageContent(lines[index].replace(/^[.…]+\s*/, ""));
|
|
1602
|
-
if (!fragment) {
|
|
1603
|
-
if (dropCount === index) dropCount = index + 1;
|
|
1604
|
-
continue;
|
|
1605
|
-
}
|
|
1606
|
-
const fragmentWordCount = fragment ? fragment.split(/\s+/).filter(Boolean).length : 0;
|
|
1607
|
-
const canBePromptEcho = fragment.length >= 16 || fragmentWordCount >= 4;
|
|
1608
|
-
if (canBePromptEcho && prompt.includes(fragment)) {
|
|
1609
|
-
dropCount = index + 1;
|
|
1610
|
-
continue;
|
|
1611
|
-
}
|
|
1612
|
-
break;
|
|
1613
|
-
}
|
|
1614
|
-
return lines.slice(dropCount).join("\n").trim();
|
|
1615
|
-
}
|
|
1616
|
-
function getLastUserPromptText(messages) {
|
|
1617
|
-
const items = Array.isArray(messages) ? messages : [];
|
|
1618
|
-
for (let index = items.length - 1; index >= 0; index -= 1) {
|
|
1619
|
-
const message = items[index];
|
|
1620
|
-
if (message?.role === "user" && typeof message.content === "string" && message.content.trim()) {
|
|
1621
|
-
return message.content;
|
|
1622
|
-
}
|
|
1623
|
-
}
|
|
1624
|
-
return "";
|
|
1625
|
-
}
|
|
1626
1046
|
function parsePatternEntry(x) {
|
|
1627
1047
|
if (x instanceof RegExp) return x;
|
|
1628
1048
|
if (x && typeof x === "object" && typeof x.source === "string") {
|
|
@@ -1649,7 +1069,7 @@ function normalizeCliProviderForRuntime(raw) {
|
|
|
1649
1069
|
}
|
|
1650
1070
|
};
|
|
1651
1071
|
}
|
|
1652
|
-
var os9, path13, import_child_process4, buildCliSpawnEnv
|
|
1072
|
+
var os9, path13, import_child_process4, buildCliSpawnEnv;
|
|
1653
1073
|
var init_provider_cli_shared = __esm({
|
|
1654
1074
|
"src/cli-adapters/provider-cli-shared.ts"() {
|
|
1655
1075
|
"use strict";
|
|
@@ -1658,32 +1078,6 @@ var init_provider_cli_shared = __esm({
|
|
|
1658
1078
|
import_child_process4 = require("child_process");
|
|
1659
1079
|
init_spawn_env();
|
|
1660
1080
|
buildCliSpawnEnv = import_session_host_core.sanitizeSpawnEnv;
|
|
1661
|
-
COMMON_COMPARABLE_WRAP_WORDS = /* @__PURE__ */ new Set([
|
|
1662
|
-
"a",
|
|
1663
|
-
"an",
|
|
1664
|
-
"and",
|
|
1665
|
-
"as",
|
|
1666
|
-
"at",
|
|
1667
|
-
"but",
|
|
1668
|
-
"by",
|
|
1669
|
-
"for",
|
|
1670
|
-
"from",
|
|
1671
|
-
"in",
|
|
1672
|
-
"into",
|
|
1673
|
-
"is",
|
|
1674
|
-
"it",
|
|
1675
|
-
"of",
|
|
1676
|
-
"on",
|
|
1677
|
-
"or",
|
|
1678
|
-
"that",
|
|
1679
|
-
"the",
|
|
1680
|
-
"their",
|
|
1681
|
-
"then",
|
|
1682
|
-
"this",
|
|
1683
|
-
"to",
|
|
1684
|
-
"was",
|
|
1685
|
-
"with"
|
|
1686
|
-
]);
|
|
1687
1081
|
}
|
|
1688
1082
|
});
|
|
1689
1083
|
|
|
@@ -1694,169 +1088,8 @@ function sliceFromOffset(text, start) {
|
|
|
1694
1088
|
if (start >= text.length) return "";
|
|
1695
1089
|
return text.slice(start);
|
|
1696
1090
|
}
|
|
1697
|
-
function
|
|
1698
|
-
|
|
1699
|
-
const referenceMessages = [...committedMessages];
|
|
1700
|
-
const referenceComparables = new Array(referenceMessages.length);
|
|
1701
|
-
const usedReferenceIndexes = /* @__PURE__ */ new Set();
|
|
1702
|
-
const now = options.now ?? Date.now();
|
|
1703
|
-
let exactReferenceIndexesByKey = null;
|
|
1704
|
-
const exactReferenceCursorByKey = /* @__PURE__ */ new Map();
|
|
1705
|
-
const hasFiniteTimestamp = (message) => typeof message?.timestamp === "number" && Number.isFinite(message.timestamp);
|
|
1706
|
-
const getReferenceComparable = (index) => {
|
|
1707
|
-
if (typeof referenceComparables[index] === "string") return referenceComparables[index] || "";
|
|
1708
|
-
const comparable = normalizeComparableMessageContent(referenceMessages[index]?.content || "");
|
|
1709
|
-
referenceComparables[index] = comparable;
|
|
1710
|
-
return comparable;
|
|
1711
|
-
};
|
|
1712
|
-
const messagesShareStableIdentity = (parsed, reference) => {
|
|
1713
|
-
if (!parsed || !reference) return false;
|
|
1714
|
-
const parsedId = typeof parsed.id === "string" ? parsed.id.trim() : "";
|
|
1715
|
-
const referenceId = typeof reference.id === "string" ? reference.id.trim() : "";
|
|
1716
|
-
if (parsedId && referenceId && parsedId === referenceId) return true;
|
|
1717
|
-
return typeof parsed.index === "number" && Number.isFinite(parsed.index) && typeof reference.index === "number" && Number.isFinite(reference.index) && parsed.index === reference.index;
|
|
1718
|
-
};
|
|
1719
|
-
const exactReferenceKey = (role, comparable) => `${role}\0${comparable}`;
|
|
1720
|
-
const ensureExactReferenceIndex = () => {
|
|
1721
|
-
if (exactReferenceIndexesByKey) return exactReferenceIndexesByKey;
|
|
1722
|
-
const byKey = /* @__PURE__ */ new Map();
|
|
1723
|
-
for (let i = 0; i < referenceMessages.length; i++) {
|
|
1724
|
-
const candidate = referenceMessages[i];
|
|
1725
|
-
if (!candidate || candidate.role !== "user" && candidate.role !== "assistant" || !hasFiniteTimestamp(candidate)) continue;
|
|
1726
|
-
const comparable = getReferenceComparable(i);
|
|
1727
|
-
if (!comparable) continue;
|
|
1728
|
-
const key = exactReferenceKey(candidate.role, comparable);
|
|
1729
|
-
const indexes = byKey.get(key);
|
|
1730
|
-
if (indexes) {
|
|
1731
|
-
indexes.push(i);
|
|
1732
|
-
} else {
|
|
1733
|
-
byKey.set(key, [i]);
|
|
1734
|
-
}
|
|
1735
|
-
}
|
|
1736
|
-
exactReferenceIndexesByKey = byKey;
|
|
1737
|
-
return byKey;
|
|
1738
|
-
};
|
|
1739
|
-
const takeExactReferenceTimestamp = (role, normalizedContent) => {
|
|
1740
|
-
const key = exactReferenceKey(role, normalizedContent);
|
|
1741
|
-
const indexes = ensureExactReferenceIndex().get(key);
|
|
1742
|
-
if (!indexes) return void 0;
|
|
1743
|
-
let cursor = exactReferenceCursorByKey.get(key) || 0;
|
|
1744
|
-
while (cursor < indexes.length) {
|
|
1745
|
-
const candidateIndex = indexes[cursor];
|
|
1746
|
-
cursor += 1;
|
|
1747
|
-
if (usedReferenceIndexes.has(candidateIndex)) continue;
|
|
1748
|
-
const candidate = referenceMessages[candidateIndex];
|
|
1749
|
-
if (!candidate || candidate.role !== role || !hasFiniteTimestamp(candidate)) continue;
|
|
1750
|
-
usedReferenceIndexes.add(candidateIndex);
|
|
1751
|
-
exactReferenceCursorByKey.set(key, cursor);
|
|
1752
|
-
return candidate.timestamp;
|
|
1753
|
-
}
|
|
1754
|
-
exactReferenceCursorByKey.set(key, cursor);
|
|
1755
|
-
return void 0;
|
|
1756
|
-
};
|
|
1757
|
-
const findReferenceTimestamp = (message, role, content, parsedIndex) => {
|
|
1758
|
-
const sameIndex = referenceMessages[parsedIndex];
|
|
1759
|
-
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && hasFiniteTimestamp(sameIndex) && messagesShareStableIdentity(message, sameIndex)) {
|
|
1760
|
-
usedReferenceIndexes.add(parsedIndex);
|
|
1761
|
-
return sameIndex.timestamp;
|
|
1762
|
-
}
|
|
1763
|
-
const normalizedContent = normalizeComparableMessageContent(content);
|
|
1764
|
-
if (!normalizedContent) return void 0;
|
|
1765
|
-
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && getReferenceComparable(parsedIndex) === normalizedContent && hasFiniteTimestamp(sameIndex)) {
|
|
1766
|
-
usedReferenceIndexes.add(parsedIndex);
|
|
1767
|
-
return sameIndex.timestamp;
|
|
1768
|
-
}
|
|
1769
|
-
const exactTimestamp = takeExactReferenceTimestamp(role, normalizedContent);
|
|
1770
|
-
if (typeof exactTimestamp === "number") return exactTimestamp;
|
|
1771
|
-
for (let i = 0; i < referenceMessages.length; i++) {
|
|
1772
|
-
if (usedReferenceIndexes.has(i)) continue;
|
|
1773
|
-
const candidate = referenceMessages[i];
|
|
1774
|
-
if (!candidate || candidate.role !== role) continue;
|
|
1775
|
-
const candidateContent = getReferenceComparable(i);
|
|
1776
|
-
if (!candidateContent) continue;
|
|
1777
|
-
const fuzzyMatch = candidateContent.includes(normalizedContent) || normalizedContent.includes(candidateContent);
|
|
1778
|
-
if (!fuzzyMatch) continue;
|
|
1779
|
-
if (hasFiniteTimestamp(candidate)) {
|
|
1780
|
-
usedReferenceIndexes.add(i);
|
|
1781
|
-
return candidate.timestamp;
|
|
1782
|
-
}
|
|
1783
|
-
}
|
|
1784
|
-
return void 0;
|
|
1785
|
-
};
|
|
1786
|
-
return parsedMessages.filter((message) => message && (message.role === "user" || message.role === "assistant")).map((message, index) => {
|
|
1787
|
-
const role = message.role;
|
|
1788
|
-
const content = typeof message.content === "string" ? message.content : String(message.content || "");
|
|
1789
|
-
const parsedTimestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0;
|
|
1790
|
-
const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(message, role, content, index);
|
|
1791
|
-
const fallbackTimestamp = role === "user" ? scope?.startedAt || now : lastOutputAt || scope?.startedAt || now;
|
|
1792
|
-
const timestamp = referenceTimestamp ?? fallbackTimestamp;
|
|
1793
|
-
return {
|
|
1794
|
-
...message,
|
|
1795
|
-
role,
|
|
1796
|
-
content,
|
|
1797
|
-
timestamp,
|
|
1798
|
-
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : timestamp
|
|
1799
|
-
};
|
|
1800
|
-
});
|
|
1801
|
-
}
|
|
1802
|
-
function chooseMoreComparableCliMessage(left, right, leftComparable = normalizeComparableMessageContent(left.content || ""), rightComparable = normalizeComparableMessageContent(right.content || "")) {
|
|
1803
|
-
if (leftComparable && leftComparable === rightComparable) {
|
|
1804
|
-
const leftNewlines = String(left.content || "").split(/\r\n|\n|\r/g).length - 1;
|
|
1805
|
-
const rightNewlines = String(right.content || "").split(/\r\n|\n|\r/g).length - 1;
|
|
1806
|
-
return rightNewlines < leftNewlines ? right : left;
|
|
1807
|
-
}
|
|
1808
|
-
return rightComparable.length > leftComparable.length ? right : left;
|
|
1809
|
-
}
|
|
1810
|
-
function dedupeConsecutiveComparableCliMessages(messages) {
|
|
1811
|
-
const deduped = [];
|
|
1812
|
-
for (const message of messages) {
|
|
1813
|
-
const current = {
|
|
1814
|
-
...message,
|
|
1815
|
-
content: typeof message.content === "string" ? message.content : String(message.content || "")
|
|
1816
|
-
};
|
|
1817
|
-
const currentComparable = normalizeComparableMessageContent(current.content || "");
|
|
1818
|
-
const previous = deduped[deduped.length - 1];
|
|
1819
|
-
if (!previous) {
|
|
1820
|
-
deduped.push({ message: current, comparable: currentComparable });
|
|
1821
|
-
continue;
|
|
1822
|
-
}
|
|
1823
|
-
const sameRole = previous.message.role === current.role;
|
|
1824
|
-
const sameKind = (previous.message.kind || "standard") === (current.kind || "standard");
|
|
1825
|
-
const sameSender = (previous.message.senderName || "") === (current.senderName || "");
|
|
1826
|
-
const comparableMatch = previous.comparable && previous.comparable === currentComparable;
|
|
1827
|
-
if (sameRole && sameKind && sameSender && comparableMatch) {
|
|
1828
|
-
const selected = chooseMoreComparableCliMessage(
|
|
1829
|
-
previous.message,
|
|
1830
|
-
current,
|
|
1831
|
-
previous.comparable,
|
|
1832
|
-
currentComparable
|
|
1833
|
-
);
|
|
1834
|
-
deduped[deduped.length - 1] = {
|
|
1835
|
-
message: selected,
|
|
1836
|
-
comparable: selected === current ? currentComparable : previous.comparable
|
|
1837
|
-
};
|
|
1838
|
-
continue;
|
|
1839
|
-
}
|
|
1840
|
-
deduped.push({ message: current, comparable: currentComparable });
|
|
1841
|
-
}
|
|
1842
|
-
return deduped.map((entry) => entry.message);
|
|
1843
|
-
}
|
|
1844
|
-
function normalizeCliParsedMessages(parsedMessages, options) {
|
|
1845
|
-
return dedupeConsecutiveComparableCliMessages(hydrateCliParsedMessages(parsedMessages, options).map((message) => ({
|
|
1846
|
-
role: message.role,
|
|
1847
|
-
content: message.content,
|
|
1848
|
-
timestamp: message.timestamp,
|
|
1849
|
-
receivedAt: message.receivedAt,
|
|
1850
|
-
kind: message.kind,
|
|
1851
|
-
id: message.id,
|
|
1852
|
-
index: message.index,
|
|
1853
|
-
providerUnitKey: message.providerUnitKey,
|
|
1854
|
-
bubbleId: message.bubbleId,
|
|
1855
|
-
bubbleState: message.bubbleState,
|
|
1856
|
-
_turnKey: message._turnKey,
|
|
1857
|
-
meta: message.meta,
|
|
1858
|
-
senderName: message.senderName
|
|
1859
|
-
})));
|
|
1091
|
+
function normalizeCliParsedMessages(parsedMessages, _options) {
|
|
1092
|
+
return Array.isArray(parsedMessages) ? parsedMessages : [];
|
|
1860
1093
|
}
|
|
1861
1094
|
function buildCliParseInput(options) {
|
|
1862
1095
|
const {
|
|
@@ -2066,40 +1299,8 @@ var provider_cli_adapter_exports = {};
|
|
|
2066
1299
|
__export(provider_cli_adapter_exports, {
|
|
2067
1300
|
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
2068
1301
|
appendBoundedText: () => appendBoundedText,
|
|
2069
|
-
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
2070
|
-
sanitizeCliStandardMessageContent: () => sanitizeCliStandardMessageContent,
|
|
2071
|
-
trimLastAssistantEchoForCliMessages: () => trimLastAssistantEchoForCliMessages
|
|
1302
|
+
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
2072
1303
|
});
|
|
2073
|
-
function normalizeComparableTranscriptText(value) {
|
|
2074
|
-
return sanitizeTerminalText(String(value || "")).replace(/\s+/g, " ").trim();
|
|
2075
|
-
}
|
|
2076
|
-
function hasVisibleInterruptPrompt(text) {
|
|
2077
|
-
const interruptCopyPattern = /\bEnter\s+to\s+interrupt\b(?:\s*,?\s*Ctrl\s*(?:\+|-)?\s*C\s+to\s+cancel)?/i;
|
|
2078
|
-
return sanitizeTerminalText(text || "").split(/\r?\n/g).some((line) => {
|
|
2079
|
-
const trimmed = line.trim();
|
|
2080
|
-
if (!interruptCopyPattern.test(trimmed)) return false;
|
|
2081
|
-
return /^(?:[^A-Za-z0-9\s]{1,8}\s+)?[❯›>]\s+/.test(trimmed);
|
|
2082
|
-
});
|
|
2083
|
-
}
|
|
2084
|
-
function parsedTranscriptIsRicherThanCommitted(parsedMessages, committedMessages) {
|
|
2085
|
-
if (!Array.isArray(parsedMessages) || !Array.isArray(committedMessages)) return false;
|
|
2086
|
-
if (parsedMessages.length > committedMessages.length) return true;
|
|
2087
|
-
if (parsedMessages.length !== committedMessages.length) return false;
|
|
2088
|
-
for (let index = 0; index < parsedMessages.length; index += 1) {
|
|
2089
|
-
const parsed = parsedMessages[index];
|
|
2090
|
-
const committed = committedMessages[index];
|
|
2091
|
-
if (!parsed || !committed) return false;
|
|
2092
|
-
if ((parsed.role || "") !== (committed.role || "")) return false;
|
|
2093
|
-
if (parsed.id && committed.id && String(parsed.id) !== String(committed.id)) return false;
|
|
2094
|
-
if (typeof parsed.index === "number" && typeof committed.index === "number" && parsed.index !== committed.index) return false;
|
|
2095
|
-
const parsedText = normalizeComparableTranscriptText(parsed.content);
|
|
2096
|
-
const committedText = normalizeComparableTranscriptText(committed.content);
|
|
2097
|
-
if (!parsedText || !committedText || parsedText === committedText) continue;
|
|
2098
|
-
if (parsedText.length > committedText.length && parsedText.startsWith(committedText)) return true;
|
|
2099
|
-
return false;
|
|
2100
|
-
}
|
|
2101
|
-
return false;
|
|
2102
|
-
}
|
|
2103
1304
|
function appendBoundedText(current, chunk, maxChars) {
|
|
2104
1305
|
if (!chunk) return current.length <= maxChars ? current : current.slice(-maxChars);
|
|
2105
1306
|
if (maxChars <= 0) return "";
|
|
@@ -2108,76 +1309,7 @@ function appendBoundedText(current, chunk, maxChars) {
|
|
|
2108
1309
|
if (current.length <= keepFromCurrent) return current + chunk;
|
|
2109
1310
|
return current.slice(-keepFromCurrent) + chunk;
|
|
2110
1311
|
}
|
|
2111
|
-
|
|
2112
|
-
const trimmed = String(line || "").trim();
|
|
2113
|
-
if (!trimmed) return false;
|
|
2114
|
-
if (COMMITTED_ACTIVITY_PREFIX_BLOCK_RE.test(trimmed)) return false;
|
|
2115
|
-
if (/\s/.test(trimmed)) return false;
|
|
2116
|
-
if (/[가-힣]/.test(trimmed)) return false;
|
|
2117
|
-
if (trimmed.length > 96) return false;
|
|
2118
|
-
return /^[A-Za-z0-9_./:@+%=-]+$/.test(trimmed);
|
|
2119
|
-
}
|
|
2120
|
-
function parseCommittedActivityPrefixBlock(lines, index) {
|
|
2121
|
-
const first = String(lines[index] || "").trim();
|
|
2122
|
-
if (!COMMITTED_ACTIVITY_PREFIX_BLOCK_RE.test(first)) return null;
|
|
2123
|
-
const parts = [first];
|
|
2124
|
-
let nextIndex = index + 1;
|
|
2125
|
-
while (nextIndex < lines.length && isLikelyCommittedActivityPrefixContinuation(lines[nextIndex])) {
|
|
2126
|
-
parts.push(String(lines[nextIndex] || "").trim());
|
|
2127
|
-
nextIndex += 1;
|
|
2128
|
-
}
|
|
2129
|
-
return { label: parts.join(""), nextIndex };
|
|
2130
|
-
}
|
|
2131
|
-
function sanitizeCliStandardMessageContent(content) {
|
|
2132
|
-
const source = String(content || "").trim();
|
|
2133
|
-
if (!source) return "";
|
|
2134
|
-
const lines = source.split(/\r?\n/);
|
|
2135
|
-
if (lines.length < 4) return source;
|
|
2136
|
-
const counts = /* @__PURE__ */ new Map();
|
|
2137
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
2138
|
-
const block = parseCommittedActivityPrefixBlock(lines, index);
|
|
2139
|
-
if (!block) continue;
|
|
2140
|
-
counts.set(block.label, (counts.get(block.label) || 0) + 1);
|
|
2141
|
-
index = block.nextIndex - 1;
|
|
2142
|
-
}
|
|
2143
|
-
const repeatedLabels = new Set(
|
|
2144
|
-
Array.from(counts.entries()).filter(([, count]) => count >= 3).map(([label]) => label)
|
|
2145
|
-
);
|
|
2146
|
-
if (repeatedLabels.size === 0) return source;
|
|
2147
|
-
const stripped = [];
|
|
2148
|
-
let removed = 0;
|
|
2149
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
2150
|
-
const block = parseCommittedActivityPrefixBlock(lines, index);
|
|
2151
|
-
if (block && repeatedLabels.has(block.label)) {
|
|
2152
|
-
removed += 1;
|
|
2153
|
-
index = block.nextIndex - 1;
|
|
2154
|
-
continue;
|
|
2155
|
-
}
|
|
2156
|
-
stripped.push(lines[index]);
|
|
2157
|
-
}
|
|
2158
|
-
const next = stripped.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
2159
|
-
return removed >= 3 && next.length >= 80 ? next : source;
|
|
2160
|
-
}
|
|
2161
|
-
function sanitizeCommittedMessageForDisplay(message) {
|
|
2162
|
-
if (!message || message.role !== "assistant" || (message.kind || "standard") !== "standard") return message;
|
|
2163
|
-
const content = sanitizeCliStandardMessageContent(message.content);
|
|
2164
|
-
if (content === message.content) return message;
|
|
2165
|
-
return { ...message, content };
|
|
2166
|
-
}
|
|
2167
|
-
function trimLastAssistantEchoForCliMessages(messages, prompt) {
|
|
2168
|
-
if (!prompt) return;
|
|
2169
|
-
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
2170
|
-
const message = messages[index];
|
|
2171
|
-
if (!message || message.role !== "assistant" || typeof message.content !== "string") continue;
|
|
2172
|
-
if ((message.kind || "standard") !== "standard") continue;
|
|
2173
|
-
message.content = trimPromptEchoPrefix(message.content, prompt);
|
|
2174
|
-
if (!message.content.trim()) {
|
|
2175
|
-
messages.splice(index, 1);
|
|
2176
|
-
}
|
|
2177
|
-
return;
|
|
2178
|
-
}
|
|
2179
|
-
}
|
|
2180
|
-
var os11, COMMITTED_ACTIVITY_PREFIX_BLOCK_RE, ProviderCliAdapter;
|
|
1312
|
+
var os11, ProviderCliAdapter;
|
|
2181
1313
|
var init_provider_cli_adapter = __esm({
|
|
2182
1314
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
2183
1315
|
"use strict";
|
|
@@ -2187,13 +1319,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
2187
1319
|
init_terminal_screen();
|
|
2188
1320
|
init_pty_transport();
|
|
2189
1321
|
init_provider_cli_shared();
|
|
2190
|
-
init_chat_message_normalization();
|
|
2191
|
-
init_read_chat_contract();
|
|
2192
1322
|
init_provider_cli_parse();
|
|
2193
1323
|
init_provider_cli_config();
|
|
2194
1324
|
init_provider_cli_runtime();
|
|
2195
1325
|
init_provider_cli_shared();
|
|
2196
|
-
COMMITTED_ACTIVITY_PREFIX_BLOCK_RE = /^(?:📖|💻|🔎|📚|📋|✏️|📝|🔧|🛠️|⚙️)\s+(.+)$/;
|
|
2197
1326
|
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
2198
1327
|
constructor(provider, workingDir, extraArgs = [], transportFactory = new NodePtyTransportFactory()) {
|
|
2199
1328
|
this.extraArgs = extraArgs;
|
|
@@ -2236,11 +1365,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
2236
1365
|
provider;
|
|
2237
1366
|
ptyProcess = null;
|
|
2238
1367
|
transportFactory;
|
|
2239
|
-
messages = [];
|
|
2240
|
-
committedMessages = [];
|
|
2241
|
-
structuredMessages = [];
|
|
2242
|
-
committedMessagesActivitySignature = "";
|
|
2243
|
-
committedMessagesChangedAt = 0;
|
|
2244
1368
|
currentStatus = "starting";
|
|
2245
1369
|
onStatusChange = null;
|
|
2246
1370
|
responseBuffer = "";
|
|
@@ -2320,11 +1444,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
2320
1444
|
traceSeq = 0;
|
|
2321
1445
|
traceSessionId = "";
|
|
2322
1446
|
parsedStatusCache = null;
|
|
2323
|
-
lastStatusHotPathParseAt = Number.NEGATIVE_INFINITY;
|
|
2324
|
-
static STATUS_HOT_PATH_PARSE_MIN_INTERVAL_MS = 1e3;
|
|
2325
1447
|
static SCREEN_SNAPSHOT_MIN_INTERVAL_MS = 250;
|
|
2326
1448
|
static MAX_TRACE_ENTRIES = 250;
|
|
2327
|
-
static PARSE_MESSAGE_TAIL_LIMIT = 100;
|
|
2328
1449
|
providerResolutionMeta;
|
|
2329
1450
|
static FINISH_RETRY_DELAY_MS = 300;
|
|
2330
1451
|
static MAX_FINISH_RETRIES = 2;
|
|
@@ -2345,35 +1466,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
2345
1466
|
recordBoundedAppendDrop(previousLength, appendedLength, nextLength) {
|
|
2346
1467
|
return Math.max(0, previousLength + appendedLength - nextLength);
|
|
2347
1468
|
}
|
|
2348
|
-
buildCommittedMessagesActivitySignature() {
|
|
2349
|
-
const last = this.committedMessages[this.committedMessages.length - 1];
|
|
2350
|
-
return [
|
|
2351
|
-
String(this.committedMessages.length),
|
|
2352
|
-
String(last?.role || ""),
|
|
2353
|
-
String(last?.kind || ""),
|
|
2354
|
-
String(last?.senderName || ""),
|
|
2355
|
-
String(last?.timestamp || ""),
|
|
2356
|
-
String(last?.receivedAt || ""),
|
|
2357
|
-
normalizeComparableMessageContent(last?.content || "").slice(-240)
|
|
2358
|
-
].join("|");
|
|
2359
|
-
}
|
|
2360
|
-
syncMessageViews() {
|
|
2361
|
-
const signature = this.buildCommittedMessagesActivitySignature();
|
|
2362
|
-
if (signature !== this.committedMessagesActivitySignature) {
|
|
2363
|
-
this.committedMessagesActivitySignature = signature;
|
|
2364
|
-
this.committedMessagesChangedAt = Date.now();
|
|
2365
|
-
}
|
|
2366
|
-
this.messages = [...this.committedMessages];
|
|
2367
|
-
this.structuredMessages = [...this.committedMessages];
|
|
2368
|
-
}
|
|
2369
|
-
getLastCommittedMessageActivityAt() {
|
|
2370
|
-
const last = this.committedMessages[this.committedMessages.length - 1];
|
|
2371
|
-
const messageTime = Math.max(
|
|
2372
|
-
typeof last?.receivedAt === "number" && Number.isFinite(last.receivedAt) ? last.receivedAt : 0,
|
|
2373
|
-
typeof last?.timestamp === "number" && Number.isFinite(last.timestamp) ? last.timestamp : 0
|
|
2374
|
-
);
|
|
2375
|
-
return Math.max(messageTime, this.committedMessagesChangedAt || 0);
|
|
2376
|
-
}
|
|
2377
1469
|
readTerminalScreenText(now = Date.now()) {
|
|
2378
1470
|
const screenText = this.terminalScreen.getText() || "";
|
|
2379
1471
|
this.lastScreenText = screenText;
|
|
@@ -2393,7 +1485,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
2393
1485
|
}
|
|
2394
1486
|
getFreshParsedStatusCache() {
|
|
2395
1487
|
const cached = this.parsedStatusCache;
|
|
2396
|
-
if (cached && cached.
|
|
1488
|
+
if (cached && cached.responseBuffer === this.responseBuffer && cached.currentTurnScope === this.currentTurnScope && cached.recentOutputBuffer === this.recentOutputBuffer && cached.accumulatedBuffer === this.accumulatedBuffer && cached.screenText === this.lastScreenText && cached.currentStatus === this.currentStatus && cached.activeModal === this.activeModal && cached.cliName === this.cliName) {
|
|
2397
1489
|
return cached.result;
|
|
2398
1490
|
}
|
|
2399
1491
|
return null;
|
|
@@ -2404,45 +1496,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
2404
1496
|
shouldUseFullProviderTranscriptContext() {
|
|
2405
1497
|
return this.providerOwnsTranscript() && this.provider.transcriptContext === "full";
|
|
2406
1498
|
}
|
|
2407
|
-
selectParseBaseMessages(baseMessages) {
|
|
2408
|
-
if (this.shouldUseFullProviderTranscriptContext()) return baseMessages;
|
|
2409
|
-
if (baseMessages.length <= _ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT) return baseMessages;
|
|
2410
|
-
return baseMessages.slice(-_ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT);
|
|
2411
|
-
}
|
|
2412
|
-
messagesShareStableIdentity(left, right) {
|
|
2413
|
-
if (left === right) return true;
|
|
2414
|
-
if (!left || !right) return false;
|
|
2415
|
-
if ((left.role || "") !== (right.role || "")) return false;
|
|
2416
|
-
if (left.id && right.id && String(left.id) === String(right.id)) return true;
|
|
2417
|
-
if (typeof left.index === "number" && typeof right.index === "number" && left.index === right.index) return true;
|
|
2418
|
-
return false;
|
|
2419
|
-
}
|
|
2420
|
-
messagesComparable(left, right) {
|
|
2421
|
-
if (this.messagesShareStableIdentity(left, right)) return true;
|
|
2422
|
-
if (!left || !right) return false;
|
|
2423
|
-
if ((left.role || "") !== (right.role || "")) return false;
|
|
2424
|
-
const leftText = normalizeComparableTranscriptText(left.content);
|
|
2425
|
-
const rightText = normalizeComparableTranscriptText(right.content);
|
|
2426
|
-
return !!leftText && leftText === rightText;
|
|
2427
|
-
}
|
|
2428
|
-
stitchParsedMessagesWithCommittedBase(parsedMessages, fullBaseMessages, parseBaseMessages) {
|
|
2429
|
-
if (!Array.isArray(parsedMessages) || parsedMessages.length === 0) return parsedMessages;
|
|
2430
|
-
if (fullBaseMessages.length <= parseBaseMessages.length) return parsedMessages;
|
|
2431
|
-
const parsedFirst = parsedMessages[0];
|
|
2432
|
-
const fullFirst = fullBaseMessages[0];
|
|
2433
|
-
if (parsedMessages.length >= fullBaseMessages.length && this.messagesComparable(parsedFirst, fullFirst)) {
|
|
2434
|
-
return parsedMessages;
|
|
2435
|
-
}
|
|
2436
|
-
const tailFirst = parseBaseMessages[0];
|
|
2437
|
-
if (tailFirst && this.messagesComparable(parsedFirst, tailFirst)) {
|
|
2438
|
-
const prefixLength = fullBaseMessages.length - parseBaseMessages.length;
|
|
2439
|
-
const prefix = fullBaseMessages.slice(0, prefixLength);
|
|
2440
|
-
const shouldSanitizePrefix = !!this.currentTurnScope || this.currentStatus !== "idle" || !!this.activeModal;
|
|
2441
|
-
const nextPrefix = shouldSanitizePrefix ? prefix.map((message) => sanitizeCommittedMessageForDisplay(message)) : prefix;
|
|
2442
|
-
return [...nextPrefix, ...parsedMessages];
|
|
2443
|
-
}
|
|
2444
|
-
return [...fullBaseMessages, ...parsedMessages];
|
|
2445
|
-
}
|
|
2446
1499
|
getIdleFinishConfirmMs() {
|
|
2447
1500
|
return this.timeouts.idleFinishConfirm;
|
|
2448
1501
|
}
|
|
@@ -2895,9 +1948,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
2895
1948
|
`[${this.cliType}] Interactive prompt wait timed out after ${maxWaitMs}ms; proceeding with screen=${JSON.stringify(summarizeCliTraceText(finalScreenText, 240)).slice(0, 280)}`
|
|
2896
1949
|
);
|
|
2897
1950
|
}
|
|
2898
|
-
trimLastAssistantEcho(messages, prompt) {
|
|
2899
|
-
trimLastAssistantEchoForCliMessages(messages, prompt);
|
|
2900
|
-
}
|
|
2901
1951
|
clearAllTimers() {
|
|
2902
1952
|
if (this.responseTimeout) {
|
|
2903
1953
|
clearTimeout(this.responseTimeout);
|
|
@@ -2993,10 +2043,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
2993
2043
|
}
|
|
2994
2044
|
const session = this.runParseSession();
|
|
2995
2045
|
if (!session) return;
|
|
2996
|
-
const { status, messages,
|
|
2046
|
+
const { status, messages, parsedStatus } = session;
|
|
2047
|
+
const modal = session.activeModal ?? session.modal ?? null;
|
|
2997
2048
|
const parsedMessages = normalizeCliParsedMessages(messages, {
|
|
2998
|
-
|
|
2999
|
-
scope: this.currentTurnScope,
|
|
2049
|
+
scope: null,
|
|
3000
2050
|
lastOutputAt: this.lastOutputAt
|
|
3001
2051
|
});
|
|
3002
2052
|
if (this.maybeCommitVisibleIdleTranscript(session, parsedMessages)) return;
|
|
@@ -3176,7 +2226,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
3176
2226
|
const effectiveScreenText = screenText || this.accumulatedBuffer;
|
|
3177
2227
|
const noActiveTurn = !this.currentTurnScope;
|
|
3178
2228
|
const looksIdleChrome = /(^|\n)\s*[❯›>]\s*(?:\n|$)/m.test(effectiveScreenText);
|
|
3179
|
-
const parsedShowsLiveAssistantProgress = parsedStatus === "generating" && !!lastParsedAssistant
|
|
2229
|
+
const parsedShowsLiveAssistantProgress = parsedStatus === "generating" && !!lastParsedAssistant;
|
|
3180
2230
|
if (prevStatus === "idle" && !this.isWaitingForResponse && noActiveTurn && !modal && looksIdleChrome && !parsedShowsLiveAssistantProgress) {
|
|
3181
2231
|
return;
|
|
3182
2232
|
}
|
|
@@ -3333,10 +2383,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
3333
2383
|
}
|
|
3334
2384
|
const visibleAssistant = [...parsedMessages].reverse().find((m) => m.role === "assistant" && m.content.trim());
|
|
3335
2385
|
if (!visibleAssistant) return false;
|
|
3336
|
-
this.committedMessages = parsedMessages;
|
|
3337
|
-
this.trimLastAssistantEcho(this.committedMessages, this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages));
|
|
3338
2386
|
this.clearAllTimers();
|
|
3339
|
-
this.syncMessageViews();
|
|
3340
2387
|
this.responseBuffer = "";
|
|
3341
2388
|
this.isWaitingForResponse = false;
|
|
3342
2389
|
this.responseSettleIgnoreUntil = 0;
|
|
@@ -3348,37 +2395,34 @@ var init_provider_cli_adapter = __esm({
|
|
|
3348
2395
|
this.setStatus("idle", "script_idle_commit");
|
|
3349
2396
|
this.onStatusChange?.();
|
|
3350
2397
|
this.recordTrace("script_idle_commit", {
|
|
3351
|
-
messageCount:
|
|
2398
|
+
messageCount: parsedMessages.length,
|
|
3352
2399
|
lastAssistant: summarizeCliTraceText(visibleAssistant.content, 320)
|
|
3353
2400
|
});
|
|
3354
2401
|
return true;
|
|
3355
2402
|
}
|
|
3356
2403
|
commitCurrentTranscript() {
|
|
3357
2404
|
const parsed = this.parseCurrentTranscript(
|
|
3358
|
-
|
|
2405
|
+
[],
|
|
3359
2406
|
this.responseBuffer,
|
|
3360
2407
|
this.currentTurnScope
|
|
3361
2408
|
);
|
|
3362
2409
|
if (parsed && Array.isArray(parsed.messages)) {
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
scope: this.currentTurnScope,
|
|
2410
|
+
const parsedMessages = normalizeCliParsedMessages(parsed.messages, {
|
|
2411
|
+
scope: null,
|
|
3366
2412
|
lastOutputAt: this.lastOutputAt
|
|
3367
2413
|
});
|
|
3368
|
-
|
|
3369
|
-
this.syncMessageViews();
|
|
3370
|
-
const lastAssistant = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
|
|
2414
|
+
const lastAssistant = [...parsedMessages].reverse().find((message) => message.role === "assistant");
|
|
3371
2415
|
if (this.currentTurnScope) {
|
|
3372
2416
|
LOG.info(
|
|
3373
2417
|
"CLI",
|
|
3374
|
-
`[${this.cliType}] commitCurrentTranscript
|
|
2418
|
+
`[${this.cliType}] commitCurrentTranscript parserMessages=${parsedMessages.length} finalLastAssistant=${JSON.stringify(summarizeCliTraceText(lastAssistant?.content || "", 220)).slice(0, 260)}`
|
|
3375
2419
|
);
|
|
3376
2420
|
}
|
|
3377
2421
|
this.recordTrace("commit_transcript", {
|
|
3378
2422
|
parsedStatus: parsed.status || null,
|
|
3379
|
-
messageCount:
|
|
2423
|
+
messageCount: parsedMessages.length,
|
|
3380
2424
|
lastAssistant: lastAssistant ? summarizeCliTraceText(lastAssistant.content, 320) : "",
|
|
3381
|
-
messages: summarizeCliTraceMessages(
|
|
2425
|
+
messages: summarizeCliTraceMessages(parsedMessages),
|
|
3382
2426
|
...buildCliTraceParseSnapshot({
|
|
3383
2427
|
accumulatedBuffer: this.accumulatedBuffer,
|
|
3384
2428
|
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
@@ -3412,63 +2456,31 @@ var init_provider_cli_adapter = __esm({
|
|
|
3412
2456
|
}
|
|
3413
2457
|
// ─── Script Execution ──────────────────────────
|
|
3414
2458
|
runParseSession() {
|
|
3415
|
-
if (typeof this.cliScripts?.parseSession
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
const tail = this.recentOutputBuffer.slice(-500);
|
|
3419
|
-
const parseBaseMessages = this.selectParseBaseMessages(this.committedMessages);
|
|
3420
|
-
const input = buildCliParseInput({
|
|
3421
|
-
accumulatedBuffer: this.accumulatedBuffer,
|
|
3422
|
-
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
3423
|
-
recentOutputBuffer: this.recentOutputBuffer,
|
|
3424
|
-
terminalScreenText: screenText,
|
|
3425
|
-
baseMessages: parseBaseMessages,
|
|
3426
|
-
partialResponse: this.responseBuffer,
|
|
3427
|
-
isWaitingForResponse: this.isWaitingForResponse,
|
|
3428
|
-
scope: this.currentTurnScope,
|
|
3429
|
-
runtimeSettings: this.runtimeSettings
|
|
3430
|
-
});
|
|
3431
|
-
const session = this.cliScripts.parseSession({ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
|
|
3432
|
-
if (session && typeof session === "object" && Array.isArray(session.messages)) {
|
|
3433
|
-
session.messages = this.stitchParsedMessagesWithCommittedBase(
|
|
3434
|
-
session.messages,
|
|
3435
|
-
this.committedMessages,
|
|
3436
|
-
parseBaseMessages
|
|
3437
|
-
);
|
|
3438
|
-
}
|
|
3439
|
-
this.parseErrorMessage = null;
|
|
3440
|
-
return session && typeof session === "object" ? session : null;
|
|
3441
|
-
} catch (e) {
|
|
3442
|
-
const message = e?.message || String(e);
|
|
3443
|
-
this.parseErrorMessage = message;
|
|
3444
|
-
LOG.warn("CLI", `[${this.cliType}] parseSession error: ${message}`);
|
|
3445
|
-
return null;
|
|
3446
|
-
}
|
|
2459
|
+
if (typeof this.cliScripts?.parseSession !== "function") {
|
|
2460
|
+
this.parseErrorMessage = `${this.cliType} parseSession unavailable`;
|
|
2461
|
+
return null;
|
|
3447
2462
|
}
|
|
3448
|
-
if (!this.cliScripts?.detectStatus && !this.cliScripts?.parseOutput) return null;
|
|
3449
2463
|
try {
|
|
3450
|
-
const
|
|
3451
|
-
const
|
|
3452
|
-
|
|
3453
|
-
this.
|
|
3454
|
-
this.
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
parsedStatus
|
|
3467
|
-
};
|
|
2464
|
+
const screenText = this.terminalScreen.getText();
|
|
2465
|
+
const tail = this.recentOutputBuffer.slice(-500);
|
|
2466
|
+
const input = buildCliParseInput({
|
|
2467
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2468
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2469
|
+
recentOutputBuffer: this.recentOutputBuffer,
|
|
2470
|
+
terminalScreenText: screenText,
|
|
2471
|
+
baseMessages: [],
|
|
2472
|
+
partialResponse: this.responseBuffer,
|
|
2473
|
+
isWaitingForResponse: this.isWaitingForResponse,
|
|
2474
|
+
scope: this.currentTurnScope,
|
|
2475
|
+
runtimeSettings: this.runtimeSettings
|
|
2476
|
+
});
|
|
2477
|
+
const session = this.cliScripts.parseSession({ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
|
|
2478
|
+
this.parseErrorMessage = null;
|
|
2479
|
+
return session && typeof session === "object" ? session : null;
|
|
3468
2480
|
} catch (e) {
|
|
3469
2481
|
const message = e?.message || String(e);
|
|
3470
2482
|
this.parseErrorMessage = message;
|
|
3471
|
-
LOG.warn("CLI", `[${this.cliType}] parseSession
|
|
2483
|
+
LOG.warn("CLI", `[${this.cliType}] parseSession error: ${message}`);
|
|
3472
2484
|
return null;
|
|
3473
2485
|
}
|
|
3474
2486
|
}
|
|
@@ -3518,45 +2530,14 @@ var init_provider_cli_adapter = __esm({
|
|
|
3518
2530
|
if (this.isWaitingForResponse && this.currentTurnScope && this.currentStatus !== "stopped") return "generating";
|
|
3519
2531
|
return this.currentStatus;
|
|
3520
2532
|
}
|
|
3521
|
-
suppressStaleParsedApproval(parsed, recentBuffer, screenText) {
|
|
3522
|
-
const actionableParsedModal = parsed?.activeModal && Array.isArray(parsed.activeModal.buttons) && parsed.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsed.activeModal : null;
|
|
3523
|
-
if (!parsed || parsed?.status !== "waiting_approval" || !actionableParsedModal) {
|
|
3524
|
-
return parsed;
|
|
3525
|
-
}
|
|
3526
|
-
const inApprovalCooldown = this.lastApprovalResolvedAt > 0 && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
|
|
3527
|
-
if (!inApprovalCooldown) {
|
|
3528
|
-
return parsed;
|
|
3529
|
-
}
|
|
3530
|
-
const visibleModal = this.runParseApproval(recentBuffer);
|
|
3531
|
-
if (visibleModal) {
|
|
3532
|
-
return parsed;
|
|
3533
|
-
}
|
|
3534
|
-
const detectedStatus = this.runDetectStatus(recentBuffer);
|
|
3535
|
-
const resolvedStatus = detectedStatus && detectedStatus !== "waiting_approval" ? detectedStatus : this.isWaitingForResponse || this.currentTurnScope ? "generating" : this.currentStatus === "waiting_approval" ? "idle" : this.currentStatus;
|
|
3536
|
-
return {
|
|
3537
|
-
...parsed,
|
|
3538
|
-
status: resolvedStatus,
|
|
3539
|
-
activeModal: null
|
|
3540
|
-
};
|
|
3541
|
-
}
|
|
3542
2533
|
// ─── Public API (CliAdapter) ───────────────────
|
|
3543
2534
|
getStatus(options = {}) {
|
|
3544
2535
|
const allowParse = options.allowParse !== false;
|
|
3545
2536
|
const startupModal = allowParse && this.startupParseGate ? this.runParseApproval(this.recentOutputBuffer) : null;
|
|
3546
2537
|
let effectiveStatus = this.projectEffectiveStatus(startupModal);
|
|
3547
2538
|
let effectiveModal = startupModal || this.activeModal;
|
|
3548
|
-
if (allowParse && !startupModal && !effectiveModal
|
|
3549
|
-
|
|
3550
|
-
if (!parsed && effectiveStatus !== "idle") {
|
|
3551
|
-
const now = Date.now();
|
|
3552
|
-
if (now - this.lastStatusHotPathParseAt >= _ProviderCliAdapter.STATUS_HOT_PATH_PARSE_MIN_INTERVAL_MS) {
|
|
3553
|
-
this.lastStatusHotPathParseAt = now;
|
|
3554
|
-
try {
|
|
3555
|
-
parsed = this.getScriptParsedStatus();
|
|
3556
|
-
} catch {
|
|
3557
|
-
}
|
|
3558
|
-
}
|
|
3559
|
-
}
|
|
2539
|
+
if (allowParse && !startupModal && !effectiveModal) {
|
|
2540
|
+
const parsed = this.getFreshParsedStatusCache();
|
|
3560
2541
|
const parsedModal = parsed?.activeModal && Array.isArray(parsed.activeModal.buttons) && parsed.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsed.activeModal : null;
|
|
3561
2542
|
if (parsed?.status === "waiting_approval" && parsedModal) {
|
|
3562
2543
|
effectiveStatus = "waiting_approval";
|
|
@@ -3566,7 +2547,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
3566
2547
|
const bufferState = this.getBufferState();
|
|
3567
2548
|
return {
|
|
3568
2549
|
status: effectiveStatus,
|
|
3569
|
-
messages: [
|
|
2550
|
+
messages: [],
|
|
3570
2551
|
workingDir: this.workingDir,
|
|
3571
2552
|
activeModal: effectiveModal,
|
|
3572
2553
|
errorMessage: this.parseErrorMessage || void 0,
|
|
@@ -3574,98 +2555,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
3574
2555
|
...bufferState ? { bufferState } : {}
|
|
3575
2556
|
};
|
|
3576
2557
|
}
|
|
3577
|
-
seedCommittedMessages(messages) {
|
|
3578
|
-
const normalized = (Array.isArray(messages) ? messages : []).filter((message) => message && (message.role === "user" || message.role === "assistant")).map((message) => ({
|
|
3579
|
-
role: message.role,
|
|
3580
|
-
content: typeof message.content === "string" ? message.content : String(message.content || ""),
|
|
3581
|
-
timestamp: typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0,
|
|
3582
|
-
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : void 0,
|
|
3583
|
-
kind: typeof message.kind === "string" ? message.kind : void 0,
|
|
3584
|
-
id: typeof message.id === "string" ? message.id : void 0,
|
|
3585
|
-
index: typeof message.index === "number" ? message.index : void 0,
|
|
3586
|
-
providerUnitKey: typeof message.providerUnitKey === "string" ? message.providerUnitKey : void 0,
|
|
3587
|
-
bubbleId: typeof message.bubbleId === "string" ? message.bubbleId : void 0,
|
|
3588
|
-
bubbleState: typeof message.bubbleState === "string" ? message.bubbleState : void 0,
|
|
3589
|
-
_turnKey: typeof message._turnKey === "string" ? message._turnKey : void 0,
|
|
3590
|
-
meta: message.meta && typeof message.meta === "object" ? { ...message.meta } : void 0,
|
|
3591
|
-
senderName: typeof message.senderName === "string" ? message.senderName : void 0
|
|
3592
|
-
}));
|
|
3593
|
-
this.committedMessages = normalized;
|
|
3594
|
-
this.syncMessageViews();
|
|
3595
|
-
}
|
|
3596
|
-
getSharedCommittedPrefixLength(parsedMessages) {
|
|
3597
|
-
const committedMessages = this.committedMessages;
|
|
3598
|
-
const max = Math.min(parsedMessages.length, committedMessages.length);
|
|
3599
|
-
let index = 0;
|
|
3600
|
-
while (index < max && this.messagesShareStableIdentity(parsedMessages[index], committedMessages[index])) {
|
|
3601
|
-
index += 1;
|
|
3602
|
-
}
|
|
3603
|
-
return index;
|
|
3604
|
-
}
|
|
3605
|
-
hydrateCommittedPrefixForParsedStatus(parsedMessages) {
|
|
3606
|
-
const sharedPrefixLength = this.getSharedCommittedPrefixLength(parsedMessages);
|
|
3607
|
-
if (sharedPrefixLength !== this.committedMessages.length) return null;
|
|
3608
|
-
const committedHydratedMessages = this.committedMessages.map((message, index) => {
|
|
3609
|
-
const timestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : this.lastOutputAt || this.currentTurnScope?.startedAt || Date.now();
|
|
3610
|
-
const contentValue = message.content;
|
|
3611
|
-
return {
|
|
3612
|
-
role: message.role,
|
|
3613
|
-
content: typeof contentValue === "string" ? contentValue : String(contentValue || ""),
|
|
3614
|
-
timestamp,
|
|
3615
|
-
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : timestamp,
|
|
3616
|
-
kind: message.kind,
|
|
3617
|
-
id: message.id || `msg_${index}`,
|
|
3618
|
-
index: typeof message.index === "number" ? message.index : index,
|
|
3619
|
-
providerUnitKey: message.providerUnitKey,
|
|
3620
|
-
bubbleId: message.bubbleId,
|
|
3621
|
-
bubbleState: message.bubbleState,
|
|
3622
|
-
_turnKey: message._turnKey,
|
|
3623
|
-
meta: message.meta,
|
|
3624
|
-
senderName: message.senderName
|
|
3625
|
-
};
|
|
3626
|
-
});
|
|
3627
|
-
const extraMessages = parsedMessages.slice(sharedPrefixLength);
|
|
3628
|
-
if (extraMessages.length === 0) return committedHydratedMessages;
|
|
3629
|
-
const extraHydratedMessages = hydrateCliParsedMessages(extraMessages, {
|
|
3630
|
-
committedMessages: [],
|
|
3631
|
-
scope: this.currentTurnScope,
|
|
3632
|
-
lastOutputAt: this.lastOutputAt
|
|
3633
|
-
}).map((message, offset) => ({
|
|
3634
|
-
...message,
|
|
3635
|
-
id: message.id || `msg_${sharedPrefixLength + offset}`,
|
|
3636
|
-
index: typeof message.index === "number" ? message.index : sharedPrefixLength + offset
|
|
3637
|
-
}));
|
|
3638
|
-
return [...committedHydratedMessages, ...extraHydratedMessages];
|
|
3639
|
-
}
|
|
3640
|
-
hydrateParsedMessagesForStatus(parsedMessages) {
|
|
3641
|
-
return this.hydrateCommittedPrefixForParsedStatus(parsedMessages) || hydrateCliParsedMessages(parsedMessages, {
|
|
3642
|
-
committedMessages: this.committedMessages,
|
|
3643
|
-
scope: this.currentTurnScope,
|
|
3644
|
-
lastOutputAt: this.lastOutputAt
|
|
3645
|
-
});
|
|
3646
|
-
}
|
|
3647
|
-
buildCommittedChatMessages() {
|
|
3648
|
-
return this.committedMessages.map((message, index) => {
|
|
3649
|
-
const rawContentValue = message.content;
|
|
3650
|
-
const rawContent = typeof rawContentValue === "string" ? rawContentValue : String(rawContentValue || "");
|
|
3651
|
-
const content = message.role === "assistant" && (message.kind || "standard") === "standard" ? sanitizeCliStandardMessageContent(rawContent) : rawContent;
|
|
3652
|
-
return buildChatMessage({
|
|
3653
|
-
role: message.role,
|
|
3654
|
-
content,
|
|
3655
|
-
timestamp: message.timestamp,
|
|
3656
|
-
kind: message.kind,
|
|
3657
|
-
meta: message.meta,
|
|
3658
|
-
senderName: message.senderName,
|
|
3659
|
-
id: message.id || `msg_${index}`,
|
|
3660
|
-
index: typeof message.index === "number" ? message.index : index,
|
|
3661
|
-
providerUnitKey: message.providerUnitKey,
|
|
3662
|
-
bubbleId: message.bubbleId,
|
|
3663
|
-
bubbleState: message.bubbleState,
|
|
3664
|
-
_turnKey: message._turnKey,
|
|
3665
|
-
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
3666
|
-
});
|
|
3667
|
-
});
|
|
3668
|
-
}
|
|
3669
2558
|
/**
|
|
3670
2559
|
* Script-based full parse — returns ReadChatResult.
|
|
3671
2560
|
* Called by command handler / dashboard for rich content rendering.
|
|
@@ -3673,125 +2562,30 @@ var init_provider_cli_adapter = __esm({
|
|
|
3673
2562
|
getScriptParsedStatus() {
|
|
3674
2563
|
const screenText = this.readTerminalScreenText();
|
|
3675
2564
|
const cached = this.parsedStatusCache;
|
|
3676
|
-
if (cached && cached.
|
|
2565
|
+
if (cached && cached.responseBuffer === this.responseBuffer && cached.currentTurnScope === this.currentTurnScope && cached.recentOutputBuffer === this.recentOutputBuffer && cached.accumulatedBuffer === this.accumulatedBuffer && cached.screenText === screenText && cached.currentStatus === this.currentStatus && cached.activeModal === this.activeModal && cached.cliName === this.cliName) {
|
|
3677
2566
|
return cached.result;
|
|
3678
2567
|
}
|
|
3679
|
-
const parsed = this.
|
|
3680
|
-
|
|
3681
|
-
this.
|
|
3682
|
-
this.currentTurnScope,
|
|
3683
|
-
screenText
|
|
3684
|
-
);
|
|
3685
|
-
const parsedModal = parsed?.activeModal && Array.isArray(parsed.activeModal.buttons) && parsed.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsed.activeModal : null;
|
|
3686
|
-
if (parsedModal && parsed?.status === "waiting_approval") {
|
|
3687
|
-
this.activeModal = parsedModal;
|
|
3688
|
-
this.isWaitingForResponse = true;
|
|
3689
|
-
if (this.currentStatus !== "waiting_approval") {
|
|
3690
|
-
this.setStatus("waiting_approval", "parsed_waiting_approval");
|
|
3691
|
-
this.onStatusChange?.();
|
|
3692
|
-
}
|
|
2568
|
+
const parsed = this.runParseSession();
|
|
2569
|
+
if (!parsed || !Array.isArray(parsed.messages)) {
|
|
2570
|
+
throw new Error(this.parseErrorMessage || `${this.cliType} parseSession did not return messages`);
|
|
3693
2571
|
}
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
2572
|
+
const activeModal = parsed.activeModal ?? parsed.modal ?? null;
|
|
2573
|
+
const bufferState = this.getBufferState();
|
|
2574
|
+
const result = {
|
|
2575
|
+
id: parsed.id || "cli_session",
|
|
2576
|
+
status: parsed.status || this.currentStatus,
|
|
2577
|
+
title: parsed.title || this.cliName,
|
|
2578
|
+
messages: normalizeCliParsedMessages(parsed.messages, {
|
|
2579
|
+
scope: null,
|
|
3698
2580
|
lastOutputAt: this.lastOutputAt
|
|
3699
|
-
})
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
|
|
3704
|
-
|
|
3705
|
-
|
|
3706
|
-
if (this.maybeCommitVisibleIdleTranscript(fakeSession, hydratedForCommit)) {
|
|
3707
|
-
return this.getScriptParsedStatus();
|
|
3708
|
-
}
|
|
3709
|
-
}
|
|
3710
|
-
const shouldPreferCommittedMessages = !this.currentTurnScope && !this.activeModal && this.currentStatus === "idle";
|
|
3711
|
-
let result;
|
|
3712
|
-
if (parsed && Array.isArray(parsed.messages)) {
|
|
3713
|
-
const parsedHydratedMessages = this.hydrateParsedMessagesForStatus(parsed.messages);
|
|
3714
|
-
const parsedLastAssistant = [...parsedHydratedMessages].reverse().find((message) => message.role === "assistant" && typeof message.content === "string" && message.content.trim());
|
|
3715
|
-
const shouldAdoptParsedIdleReplay = !this.currentTurnScope && !this.activeModal && !!parsedLastAssistant && parsedTranscriptIsRicherThanCommitted(parsedHydratedMessages, this.committedMessages) && (this.currentStatus === "idle" || this.currentStatus === "generating" && this.isWaitingForResponse && parsed.status === "idle" && this.runDetectStatus(this.recentOutputBuffer) === "idle");
|
|
3716
|
-
if (shouldAdoptParsedIdleReplay) {
|
|
3717
|
-
this.committedMessages = this.getSharedCommittedPrefixLength(parsed.messages) === this.committedMessages.length ? parsedHydratedMessages.map((message) => ({
|
|
3718
|
-
role: message.role,
|
|
3719
|
-
content: typeof message.content === "string" ? message.content : String(message.content || ""),
|
|
3720
|
-
timestamp: message.timestamp,
|
|
3721
|
-
receivedAt: message.receivedAt,
|
|
3722
|
-
kind: message.kind,
|
|
3723
|
-
id: message.id,
|
|
3724
|
-
index: message.index,
|
|
3725
|
-
meta: message.meta,
|
|
3726
|
-
senderName: message.senderName
|
|
3727
|
-
})) : normalizeCliParsedMessages(parsed.messages, {
|
|
3728
|
-
committedMessages: this.committedMessages,
|
|
3729
|
-
scope: this.currentTurnScope,
|
|
3730
|
-
lastOutputAt: this.lastOutputAt
|
|
3731
|
-
});
|
|
3732
|
-
this.syncMessageViews();
|
|
3733
|
-
if (this.currentStatus !== "idle" || this.isWaitingForResponse) {
|
|
3734
|
-
this.responseBuffer = "";
|
|
3735
|
-
this.isWaitingForResponse = false;
|
|
3736
|
-
this.responseSettleIgnoreUntil = 0;
|
|
3737
|
-
this.submitRetryUsed = false;
|
|
3738
|
-
this.submitRetryPromptSnippet = "";
|
|
3739
|
-
this.finishRetryCount = 0;
|
|
3740
|
-
this.currentTurnScope = null;
|
|
3741
|
-
this.activeModal = null;
|
|
3742
|
-
this.setStatus("idle", "parsed_idle_replay_commit");
|
|
3743
|
-
this.onStatusChange?.();
|
|
3744
|
-
}
|
|
3745
|
-
}
|
|
3746
|
-
const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && this.committedMessages.length > parsedHydratedMessages.length;
|
|
3747
|
-
const shouldPreferCommittedIdleReplay = shouldPreferCommittedMessages && !shouldAdoptParsedIdleReplay;
|
|
3748
|
-
const hydratedMessages = shouldPreferCommittedIdleReplay || shouldPreferCommittedHistoryReplay ? this.buildCommittedChatMessages() : parsedHydratedMessages;
|
|
3749
|
-
result = {
|
|
3750
|
-
id: parsed.id || "cli_session",
|
|
3751
|
-
status: parsed.status || this.currentStatus,
|
|
3752
|
-
title: parsed.title || this.cliName,
|
|
3753
|
-
messages: hydratedMessages,
|
|
3754
|
-
activeModal: parsed.activeModal ?? this.activeModal,
|
|
3755
|
-
providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0,
|
|
3756
|
-
...this.getBufferState() ? { bufferState: this.getBufferState() } : {},
|
|
3757
|
-
...this.providerOwnsTranscript() ? { transcriptAuthority: "provider", coverage: this.shouldUseFullProviderTranscriptContext() ? "full" : "tail" } : {}
|
|
3758
|
-
};
|
|
3759
|
-
} else {
|
|
3760
|
-
const messages = [...this.committedMessages];
|
|
3761
|
-
const bufferState = this.getBufferState();
|
|
3762
|
-
result = {
|
|
3763
|
-
id: "cli_session",
|
|
3764
|
-
status: this.currentStatus,
|
|
3765
|
-
title: this.cliName,
|
|
3766
|
-
messages: messages.map((message, index) => buildChatMessage({
|
|
3767
|
-
...message,
|
|
3768
|
-
id: message.id || `msg_${index}`,
|
|
3769
|
-
index: typeof message.index === "number" ? message.index : index,
|
|
3770
|
-
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
3771
|
-
})),
|
|
3772
|
-
activeModal: this.activeModal,
|
|
3773
|
-
...bufferState ? { bufferState } : {}
|
|
3774
|
-
};
|
|
3775
|
-
}
|
|
3776
|
-
const hasVisibleAssistantMessage = Array.isArray(result?.messages) && result.messages.some((message) => message?.role === "assistant" && typeof message?.content === "string" && message.content.trim());
|
|
3777
|
-
const shouldClampStaleGeneratingToIdle = result?.status === "generating" && this.currentStatus === "idle" && !this.currentTurnScope && !result?.activeModal && hasVisibleAssistantMessage && !hasVisibleInterruptPrompt(screenText);
|
|
3778
|
-
if (shouldClampStaleGeneratingToIdle) {
|
|
3779
|
-
result = {
|
|
3780
|
-
...result,
|
|
3781
|
-
status: "idle",
|
|
3782
|
-
messages: Array.isArray(result.messages) ? result.messages.map((message) => {
|
|
3783
|
-
if (message?.role !== "assistant" || !message?.meta?.streaming) return message;
|
|
3784
|
-
const nextMeta = { ...message.meta || {} };
|
|
3785
|
-
delete nextMeta.streaming;
|
|
3786
|
-
return {
|
|
3787
|
-
...message,
|
|
3788
|
-
...Object.keys(nextMeta).length > 0 ? { meta: nextMeta } : { meta: void 0 }
|
|
3789
|
-
};
|
|
3790
|
-
}) : result.messages
|
|
3791
|
-
};
|
|
3792
|
-
}
|
|
2581
|
+
}),
|
|
2582
|
+
activeModal,
|
|
2583
|
+
providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0,
|
|
2584
|
+
...bufferState ? { bufferState } : {},
|
|
2585
|
+
...parsed.transcriptAuthority === "provider" || parsed.transcriptAuthority === "daemon" ? { transcriptAuthority: parsed.transcriptAuthority } : this.providerOwnsTranscript() ? { transcriptAuthority: "provider" } : {},
|
|
2586
|
+
...parsed.coverage === "full" || parsed.coverage === "tail" || parsed.coverage === "current-turn" ? { coverage: parsed.coverage } : this.providerOwnsTranscript() ? { coverage: this.shouldUseFullProviderTranscriptContext() ? "full" : "tail" } : {}
|
|
2587
|
+
};
|
|
3793
2588
|
this.parsedStatusCache = {
|
|
3794
|
-
committedMessagesRef: this.committedMessages,
|
|
3795
2589
|
responseBuffer: this.responseBuffer,
|
|
3796
2590
|
currentTurnScope: this.currentTurnScope,
|
|
3797
2591
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
@@ -3814,7 +2608,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
3814
2608
|
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
3815
2609
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
3816
2610
|
terminalScreenText: this.terminalScreen.getText(),
|
|
3817
|
-
baseMessages:
|
|
2611
|
+
baseMessages: [],
|
|
3818
2612
|
partialResponse: this.responseBuffer,
|
|
3819
2613
|
isWaitingForResponse: this.isWaitingForResponse,
|
|
3820
2614
|
scope: this.currentTurnScope,
|
|
@@ -3825,46 +2619,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
3825
2619
|
args: args && typeof args === "object" ? { ...args } : {}
|
|
3826
2620
|
}));
|
|
3827
2621
|
}
|
|
3828
|
-
parseCurrentTranscript(
|
|
3829
|
-
|
|
3830
|
-
this.parseErrorMessage = null;
|
|
3831
|
-
return null;
|
|
3832
|
-
}
|
|
3833
|
-
try {
|
|
3834
|
-
const screenText = typeof screenTextOverride === "string" ? screenTextOverride : this.terminalScreen.getText();
|
|
3835
|
-
const parseBaseMessages = this.selectParseBaseMessages(baseMessages);
|
|
3836
|
-
const input = buildCliParseInput({
|
|
3837
|
-
accumulatedBuffer: this.accumulatedBuffer,
|
|
3838
|
-
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
3839
|
-
recentOutputBuffer: this.recentOutputBuffer,
|
|
3840
|
-
terminalScreenText: screenText,
|
|
3841
|
-
baseMessages: parseBaseMessages,
|
|
3842
|
-
partialResponse,
|
|
3843
|
-
isWaitingForResponse: this.isWaitingForResponse,
|
|
3844
|
-
scope,
|
|
3845
|
-
runtimeSettings: this.runtimeSettings
|
|
3846
|
-
});
|
|
3847
|
-
const parsed = this.cliScripts.parseOutput(input);
|
|
3848
|
-
if (parsed && typeof parsed === "object") {
|
|
3849
|
-
Object.assign(parsed, validateReadChatResultPayload(parsed, `${this.cliType} parseOutput`));
|
|
3850
|
-
}
|
|
3851
|
-
const normalizedParsed = this.suppressStaleParsedApproval(parsed, input.recentBuffer, input.screenText);
|
|
3852
|
-
if (normalizedParsed && Array.isArray(normalizedParsed.messages)) {
|
|
3853
|
-
normalizedParsed.messages = this.stitchParsedMessagesWithCommittedBase(
|
|
3854
|
-
normalizedParsed.messages,
|
|
3855
|
-
baseMessages,
|
|
3856
|
-
parseBaseMessages
|
|
3857
|
-
);
|
|
3858
|
-
this.trimLastAssistantEcho(normalizedParsed.messages, scope?.prompt || getLastUserPromptText(baseMessages));
|
|
3859
|
-
}
|
|
3860
|
-
this.parseErrorMessage = null;
|
|
3861
|
-
return normalizedParsed;
|
|
3862
|
-
} catch (e) {
|
|
3863
|
-
const message = e?.message || String(e);
|
|
3864
|
-
this.parseErrorMessage = message;
|
|
3865
|
-
LOG.warn("CLI", `[${this.cliType}] parseOutput error: ${message}`);
|
|
3866
|
-
throw e;
|
|
3867
|
-
}
|
|
2622
|
+
parseCurrentTranscript(_baseMessages, _partialResponse, _scope, _screenTextOverride) {
|
|
2623
|
+
return this.runParseSession();
|
|
3868
2624
|
}
|
|
3869
2625
|
/** Whether this adapter has CLI scripts loaded */
|
|
3870
2626
|
hasCliScripts() {
|
|
@@ -3926,8 +2682,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
3926
2682
|
commitSendUserTurn(state) {
|
|
3927
2683
|
if (state.didCommitUserTurn) return;
|
|
3928
2684
|
state.didCommitUserTurn = true;
|
|
3929
|
-
this.committedMessages.push({ role: "user", content: state.text, timestamp: Date.now() });
|
|
3930
|
-
this.syncMessageViews();
|
|
3931
2685
|
}
|
|
3932
2686
|
armResponseTimeout() {
|
|
3933
2687
|
if (this.responseTimeout) clearTimeout(this.responseTimeout);
|
|
@@ -4119,11 +2873,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
4119
2873
|
}
|
|
4120
2874
|
})() : null;
|
|
4121
2875
|
const parsedSessionStatus = typeof parsedStatusBeforeSend?.status === "string" ? String(parsedStatusBeforeSend.status) : "";
|
|
4122
|
-
const parsedMessagesBeforeSend = Array.isArray(parsedStatusBeforeSend?.messages) ? parsedStatusBeforeSend.messages.filter((message) => message && (message.role === "user" || message.role === "assistant")) : [];
|
|
4123
|
-
const shouldCommitParsedIdleBeforeSend = !allowInputDuringGeneration && parsedSessionStatus === "idle" && parsedMessagesBeforeSend.length > this.committedMessages.length && parsedMessagesBeforeSend.some((message) => message?.role === "assistant" && typeof message?.content === "string" && message.content.trim());
|
|
4124
|
-
if (shouldCommitParsedIdleBeforeSend) {
|
|
4125
|
-
this.commitCurrentTranscript();
|
|
4126
|
-
}
|
|
4127
2876
|
if (!allowInputDuringGeneration && (parsedSessionStatus === "generating" || parsedSessionStatus === "long_generating")) {
|
|
4128
2877
|
throw new Error(`${this.cliName} is still processing the previous prompt`);
|
|
4129
2878
|
}
|
|
@@ -4229,9 +2978,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
4229
2978
|
activeModal: this.activeModal,
|
|
4230
2979
|
parseErrorMessage: this.parseErrorMessage,
|
|
4231
2980
|
messageCounts: {
|
|
4232
|
-
committed: this.committedMessages.length,
|
|
4233
|
-
structured: this.structuredMessages.length,
|
|
4234
|
-
visible: this.messages.length,
|
|
4235
2981
|
parsedCache: Array.isArray(parsedResult?.messages) ? parsedResult.messages.length : void 0
|
|
4236
2982
|
},
|
|
4237
2983
|
buffers: {
|
|
@@ -4282,8 +3028,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
4282
3028
|
responseSettleIgnoreUntil: this.responseSettleIgnoreUntil,
|
|
4283
3029
|
responseEpoch: this.responseEpoch,
|
|
4284
3030
|
resizeSuppressUntil: this.resizeSuppressUntil,
|
|
4285
|
-
lastApprovalResolvedAt: this.lastApprovalResolvedAt
|
|
4286
|
-
committedMessagesChangedAt: this.committedMessagesChangedAt
|
|
3031
|
+
lastApprovalResolvedAt: this.lastApprovalResolvedAt
|
|
4287
3032
|
},
|
|
4288
3033
|
finish: {
|
|
4289
3034
|
idleFinishCandidate: this.idleFinishCandidate,
|
|
@@ -4408,8 +3153,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
4408
3153
|
}
|
|
4409
3154
|
clearHistory() {
|
|
4410
3155
|
this.clearIdleFinishCandidate("clear_history");
|
|
4411
|
-
this.committedMessages = [];
|
|
4412
|
-
this.syncMessageViews();
|
|
4413
3156
|
this.accumulatedBuffer = "";
|
|
4414
3157
|
this.accumulatedRawBuffer = "";
|
|
4415
3158
|
this.currentTurnScope = null;
|
|
@@ -4450,7 +3193,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
4450
3193
|
}
|
|
4451
3194
|
resolveModal(buttonIndex) {
|
|
4452
3195
|
let modal = this.activeModal || this.runParseApproval(this.recentOutputBuffer);
|
|
4453
|
-
if (!modal && typeof this.cliScripts?.
|
|
3196
|
+
if (!modal && typeof this.cliScripts?.parseSession === "function") {
|
|
4454
3197
|
try {
|
|
4455
3198
|
const parsed = this.getScriptParsedStatus();
|
|
4456
3199
|
const parsedModal = parsed?.activeModal && Array.isArray(parsed.activeModal.buttons) && parsed.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsed.activeModal : null;
|
|
@@ -4517,10 +3260,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
4517
3260
|
startupParseGate: this.startupParseGate,
|
|
4518
3261
|
spawnAt: this.spawnAt,
|
|
4519
3262
|
workingDir: this.workingDir,
|
|
4520
|
-
messages:
|
|
4521
|
-
|
|
4522
|
-
structuredMessages: this.structuredMessages,
|
|
4523
|
-
messageCount: this.committedMessages.length,
|
|
3263
|
+
messages: [],
|
|
3264
|
+
messageCount: 0,
|
|
4524
3265
|
screenText: screenText.slice(-4e3),
|
|
4525
3266
|
currentTurnScope: this.currentTurnScope,
|
|
4526
3267
|
startupBuffer: this.startupBuffer.slice(-4e3),
|
|
@@ -4572,7 +3313,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
4572
3313
|
lifecycleStatus: this.isWaitingForResponse ? "awaiting_response" : "idle",
|
|
4573
3314
|
activeModal: this.activeModal,
|
|
4574
3315
|
currentTurnScope: this.currentTurnScope,
|
|
4575
|
-
messages:
|
|
3316
|
+
messages: []
|
|
4576
3317
|
};
|
|
4577
3318
|
}
|
|
4578
3319
|
getProviderResolutionMeta() {
|
|
@@ -8362,14 +7103,223 @@ var CdpDomHandlers = class {
|
|
|
8362
7103
|
return { success: false, error: e.message };
|
|
8363
7104
|
}
|
|
8364
7105
|
}
|
|
8365
|
-
};
|
|
8366
|
-
|
|
8367
|
-
// src/providers/ide-provider-instance.ts
|
|
8368
|
-
var crypto2 = __toESM(require("crypto"));
|
|
8369
|
-
|
|
7106
|
+
};
|
|
7107
|
+
|
|
7108
|
+
// src/providers/ide-provider-instance.ts
|
|
7109
|
+
var crypto2 = __toESM(require("crypto"));
|
|
7110
|
+
|
|
7111
|
+
// src/providers/io-contracts.ts
|
|
7112
|
+
function normalizeInputEnvelope(input) {
|
|
7113
|
+
const normalized = normalizeInputEnvelopePayload(input);
|
|
7114
|
+
const textFallback = normalized.textFallback ?? flattenInputParts(normalized.parts);
|
|
7115
|
+
return {
|
|
7116
|
+
parts: normalized.parts,
|
|
7117
|
+
textFallback,
|
|
7118
|
+
...normalized.metadata ? { metadata: normalized.metadata } : {}
|
|
7119
|
+
};
|
|
7120
|
+
}
|
|
7121
|
+
function normalizeMessageParts(content) {
|
|
7122
|
+
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
7123
|
+
if (!Array.isArray(content)) {
|
|
7124
|
+
if (content && typeof content === "object" && typeof content.text === "string") {
|
|
7125
|
+
return [{ type: "text", text: String(content.text) }];
|
|
7126
|
+
}
|
|
7127
|
+
return [];
|
|
7128
|
+
}
|
|
7129
|
+
const parts = [];
|
|
7130
|
+
for (const raw of content) {
|
|
7131
|
+
if (typeof raw === "string") {
|
|
7132
|
+
parts.push({ type: "text", text: raw });
|
|
7133
|
+
continue;
|
|
7134
|
+
}
|
|
7135
|
+
if (!raw || typeof raw !== "object") continue;
|
|
7136
|
+
const part = normalizeMessagePartObject(raw);
|
|
7137
|
+
if (part) parts.push(part);
|
|
7138
|
+
}
|
|
7139
|
+
return parts;
|
|
7140
|
+
}
|
|
7141
|
+
function flattenMessageParts(parts) {
|
|
7142
|
+
return parts.map((part) => {
|
|
7143
|
+
if (part.type === "text") return part.text;
|
|
7144
|
+
if (part.type === "resource") return part.resource.text || "";
|
|
7145
|
+
return "";
|
|
7146
|
+
}).filter((value) => value.length > 0).join("\n");
|
|
7147
|
+
}
|
|
7148
|
+
function normalizeInputEnvelopePayload(input) {
|
|
7149
|
+
if (typeof input === "string") {
|
|
7150
|
+
return { parts: [{ type: "text", text: input }], textFallback: input };
|
|
7151
|
+
}
|
|
7152
|
+
if (!input || typeof input !== "object") {
|
|
7153
|
+
return { parts: [], textFallback: "" };
|
|
7154
|
+
}
|
|
7155
|
+
const record = input;
|
|
7156
|
+
const nestedInput = record.input;
|
|
7157
|
+
if (nestedInput && typeof nestedInput === "object") {
|
|
7158
|
+
const nested = nestedInput;
|
|
7159
|
+
return {
|
|
7160
|
+
parts: normalizeInputParts(nested.parts ?? nested.prompt),
|
|
7161
|
+
textFallback: typeof nested.textFallback === "string" ? nested.textFallback : void 0,
|
|
7162
|
+
metadata: normalizeInputMetadata(nested.metadata)
|
|
7163
|
+
};
|
|
7164
|
+
}
|
|
7165
|
+
const directText = typeof record.text === "string" ? record.text : typeof record.message === "string" ? record.message : void 0;
|
|
7166
|
+
if (directText !== void 0) {
|
|
7167
|
+
return { parts: [{ type: "text", text: directText }], textFallback: directText };
|
|
7168
|
+
}
|
|
7169
|
+
const directParts = normalizeInputParts(record.parts ?? record.prompt);
|
|
7170
|
+
return {
|
|
7171
|
+
parts: directParts,
|
|
7172
|
+
textFallback: typeof record.textFallback === "string" ? record.textFallback : void 0,
|
|
7173
|
+
metadata: normalizeInputMetadata(record.metadata)
|
|
7174
|
+
};
|
|
7175
|
+
}
|
|
7176
|
+
function normalizeInputMetadata(value) {
|
|
7177
|
+
if (!value || typeof value !== "object") return void 0;
|
|
7178
|
+
const record = value;
|
|
7179
|
+
const metadata = {};
|
|
7180
|
+
if (record.source === "dashboard" || record.source === "shortcut_api" || record.source === "provider_script" || record.source === "session_replay") {
|
|
7181
|
+
metadata.source = record.source;
|
|
7182
|
+
}
|
|
7183
|
+
if (typeof record.clientTimestamp === "number" && Number.isFinite(record.clientTimestamp)) {
|
|
7184
|
+
metadata.clientTimestamp = record.clientTimestamp;
|
|
7185
|
+
}
|
|
7186
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
7187
|
+
}
|
|
7188
|
+
function normalizeInputParts(value) {
|
|
7189
|
+
if (!Array.isArray(value)) return [];
|
|
7190
|
+
const parts = [];
|
|
7191
|
+
for (const raw of value) {
|
|
7192
|
+
if (typeof raw === "string") {
|
|
7193
|
+
parts.push({ type: "text", text: raw });
|
|
7194
|
+
continue;
|
|
7195
|
+
}
|
|
7196
|
+
if (!raw || typeof raw !== "object") continue;
|
|
7197
|
+
const part = normalizeInputPartObject(raw);
|
|
7198
|
+
if (part) parts.push(part);
|
|
7199
|
+
}
|
|
7200
|
+
return parts;
|
|
7201
|
+
}
|
|
7202
|
+
function normalizeInputPartObject(raw) {
|
|
7203
|
+
const type = raw.type;
|
|
7204
|
+
if (type === "text" && typeof raw.text === "string") {
|
|
7205
|
+
return { type, text: raw.text };
|
|
7206
|
+
}
|
|
7207
|
+
if (type === "image" && typeof raw.mimeType === "string") {
|
|
7208
|
+
return {
|
|
7209
|
+
type,
|
|
7210
|
+
mimeType: raw.mimeType,
|
|
7211
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7212
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7213
|
+
...typeof raw.alt === "string" ? { alt: raw.alt } : {}
|
|
7214
|
+
};
|
|
7215
|
+
}
|
|
7216
|
+
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
7217
|
+
return {
|
|
7218
|
+
type,
|
|
7219
|
+
mimeType: raw.mimeType,
|
|
7220
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7221
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7222
|
+
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
|
|
7223
|
+
};
|
|
7224
|
+
}
|
|
7225
|
+
if (type === "video" && typeof raw.mimeType === "string") {
|
|
7226
|
+
return {
|
|
7227
|
+
type,
|
|
7228
|
+
mimeType: raw.mimeType,
|
|
7229
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7230
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7231
|
+
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
7232
|
+
};
|
|
7233
|
+
}
|
|
7234
|
+
if (type === "resource" && typeof raw.uri === "string") {
|
|
7235
|
+
return {
|
|
7236
|
+
type,
|
|
7237
|
+
uri: raw.uri,
|
|
7238
|
+
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7239
|
+
...typeof raw.name === "string" ? { name: raw.name } : {},
|
|
7240
|
+
...typeof raw.text === "string" ? { text: raw.text } : {},
|
|
7241
|
+
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
7242
|
+
};
|
|
7243
|
+
}
|
|
7244
|
+
if (type === "resource_link" && typeof raw.uri === "string") {
|
|
7245
|
+
return {
|
|
7246
|
+
type: "resource",
|
|
7247
|
+
uri: raw.uri,
|
|
7248
|
+
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7249
|
+
...typeof raw.name === "string" ? { name: raw.name } : {}
|
|
7250
|
+
};
|
|
7251
|
+
}
|
|
7252
|
+
return null;
|
|
7253
|
+
}
|
|
7254
|
+
function normalizeMessagePartObject(raw) {
|
|
7255
|
+
const type = raw.type;
|
|
7256
|
+
if (type === "text" && typeof raw.text === "string") {
|
|
7257
|
+
return { type, text: raw.text };
|
|
7258
|
+
}
|
|
7259
|
+
if (type === "image" && typeof raw.mimeType === "string") {
|
|
7260
|
+
return {
|
|
7261
|
+
type,
|
|
7262
|
+
mimeType: raw.mimeType,
|
|
7263
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7264
|
+
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
7265
|
+
};
|
|
7266
|
+
}
|
|
7267
|
+
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
7268
|
+
return {
|
|
7269
|
+
type,
|
|
7270
|
+
mimeType: raw.mimeType,
|
|
7271
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7272
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7273
|
+
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
|
|
7274
|
+
};
|
|
7275
|
+
}
|
|
7276
|
+
if (type === "video" && typeof raw.mimeType === "string") {
|
|
7277
|
+
return {
|
|
7278
|
+
type,
|
|
7279
|
+
mimeType: raw.mimeType,
|
|
7280
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7281
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7282
|
+
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
7283
|
+
};
|
|
7284
|
+
}
|
|
7285
|
+
if (type === "resource_link" && typeof raw.uri === "string" && typeof raw.name === "string") {
|
|
7286
|
+
return {
|
|
7287
|
+
type,
|
|
7288
|
+
uri: raw.uri,
|
|
7289
|
+
name: raw.name,
|
|
7290
|
+
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7291
|
+
...typeof raw.size === "number" ? { size: raw.size } : {}
|
|
7292
|
+
};
|
|
7293
|
+
}
|
|
7294
|
+
if (type === "resource" && raw.resource && typeof raw.resource === "object") {
|
|
7295
|
+
const resource = raw.resource;
|
|
7296
|
+
if (typeof resource.uri !== "string") return null;
|
|
7297
|
+
return {
|
|
7298
|
+
type,
|
|
7299
|
+
resource: {
|
|
7300
|
+
uri: resource.uri,
|
|
7301
|
+
...typeof resource.mimeType === "string" || resource.mimeType === null ? { mimeType: resource.mimeType } : {},
|
|
7302
|
+
...typeof resource.text === "string" ? { text: resource.text } : {},
|
|
7303
|
+
...typeof resource.blob === "string" ? { blob: resource.blob } : {}
|
|
7304
|
+
}
|
|
7305
|
+
};
|
|
7306
|
+
}
|
|
7307
|
+
return null;
|
|
7308
|
+
}
|
|
7309
|
+
function flattenInputParts(parts) {
|
|
7310
|
+
return parts.map((part) => {
|
|
7311
|
+
if (part.type === "text") return part.text;
|
|
7312
|
+
if (part.type === "audio") return part.transcript || "";
|
|
7313
|
+
if (part.type === "resource") return part.text || "";
|
|
7314
|
+
return "";
|
|
7315
|
+
}).filter((value) => value.length > 0).join("\n");
|
|
7316
|
+
}
|
|
8370
7317
|
|
|
8371
|
-
// src/providers/
|
|
8372
|
-
|
|
7318
|
+
// src/providers/contracts.ts
|
|
7319
|
+
function flattenContent(content) {
|
|
7320
|
+
if (typeof content === "string") return content;
|
|
7321
|
+
return flattenMessageParts(normalizeMessageParts(content));
|
|
7322
|
+
}
|
|
8373
7323
|
|
|
8374
7324
|
// src/providers/status-monitor.ts
|
|
8375
7325
|
var DEFAULT_MONITOR_CONFIG = {
|
|
@@ -8483,9 +7433,151 @@ var StatusMonitor = class {
|
|
|
8483
7433
|
}
|
|
8484
7434
|
};
|
|
8485
7435
|
|
|
7436
|
+
// src/providers/chat-message-normalization.ts
|
|
7437
|
+
var BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
|
|
7438
|
+
var KNOWN_CHAT_MESSAGE_KINDS = new Set(BUILTIN_CHAT_MESSAGE_KINDS);
|
|
7439
|
+
var CHAT_MESSAGE_KIND_ALIASES = {
|
|
7440
|
+
text: "standard",
|
|
7441
|
+
message: "standard",
|
|
7442
|
+
assistant: "standard",
|
|
7443
|
+
thinking: "thought",
|
|
7444
|
+
think: "thought",
|
|
7445
|
+
reasoning: "thought",
|
|
7446
|
+
reason: "thought",
|
|
7447
|
+
toolcall: "tool",
|
|
7448
|
+
tool_call: "tool",
|
|
7449
|
+
tooluse: "tool",
|
|
7450
|
+
tool_use: "tool",
|
|
7451
|
+
action: "tool",
|
|
7452
|
+
command: "terminal",
|
|
7453
|
+
cmd: "terminal",
|
|
7454
|
+
shell: "terminal",
|
|
7455
|
+
console: "terminal"
|
|
7456
|
+
};
|
|
7457
|
+
function canonicalizeKindHint(value) {
|
|
7458
|
+
return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
7459
|
+
}
|
|
7460
|
+
function resolveBuiltinOrAliasKind(kind) {
|
|
7461
|
+
if (typeof kind !== "string") return null;
|
|
7462
|
+
const normalizedKind = canonicalizeKindHint(kind);
|
|
7463
|
+
if (!normalizedKind) return null;
|
|
7464
|
+
if (KNOWN_CHAT_MESSAGE_KINDS.has(normalizedKind)) return normalizedKind;
|
|
7465
|
+
return CHAT_MESSAGE_KIND_ALIASES[normalizedKind] || null;
|
|
7466
|
+
}
|
|
7467
|
+
function inferHintKind(value) {
|
|
7468
|
+
const direct = resolveBuiltinOrAliasKind(value);
|
|
7469
|
+
if (direct) return direct;
|
|
7470
|
+
if (typeof value !== "string") return null;
|
|
7471
|
+
const normalized = canonicalizeKindHint(value);
|
|
7472
|
+
if (!normalized) return null;
|
|
7473
|
+
if (/thought|thinking|reasoning/.test(normalized)) return "thought";
|
|
7474
|
+
if (/tool/.test(normalized)) return "tool";
|
|
7475
|
+
if (/terminal|command|shell|console/.test(normalized)) return "terminal";
|
|
7476
|
+
return null;
|
|
7477
|
+
}
|
|
7478
|
+
function inferKindFromToolCalls(message) {
|
|
7479
|
+
const toolCalls = Array.isArray(message?.toolCalls) ? message.toolCalls : [];
|
|
7480
|
+
if (toolCalls.length === 0) return null;
|
|
7481
|
+
if (toolCalls.some((toolCall) => toolCall?.kind === "think")) return "thought";
|
|
7482
|
+
if (toolCalls.some((toolCall) => toolCall?.kind === "execute")) return "terminal";
|
|
7483
|
+
if (toolCalls.some((toolCall) => Array.isArray(toolCall?.content) && toolCall.content.some((entry) => entry?.type === "terminal"))) {
|
|
7484
|
+
return "terminal";
|
|
7485
|
+
}
|
|
7486
|
+
return "tool";
|
|
7487
|
+
}
|
|
7488
|
+
function inferMissingChatMessageKind(message) {
|
|
7489
|
+
const role = typeof message?.role === "string" ? message.role.trim().toLowerCase() : "";
|
|
7490
|
+
if (role === "system") return "system";
|
|
7491
|
+
const meta = message?.meta && typeof message.meta === "object" ? message.meta : void 0;
|
|
7492
|
+
const hintCandidates = [
|
|
7493
|
+
message?._sub,
|
|
7494
|
+
message?._type,
|
|
7495
|
+
meta?.label,
|
|
7496
|
+
typeof message?.senderName === "string" ? message.senderName : void 0
|
|
7497
|
+
];
|
|
7498
|
+
for (const candidate of hintCandidates) {
|
|
7499
|
+
const inferred = inferHintKind(candidate);
|
|
7500
|
+
if (inferred) return inferred;
|
|
7501
|
+
}
|
|
7502
|
+
const inferredFromToolCalls = inferKindFromToolCalls(message);
|
|
7503
|
+
if (inferredFromToolCalls) return inferredFromToolCalls;
|
|
7504
|
+
return null;
|
|
7505
|
+
}
|
|
7506
|
+
function isBuiltinChatMessageKind(kind) {
|
|
7507
|
+
return resolveBuiltinOrAliasKind(kind) !== null;
|
|
7508
|
+
}
|
|
7509
|
+
function normalizeChatMessageKind(kind, role) {
|
|
7510
|
+
const resolvedKind = resolveBuiltinOrAliasKind(kind);
|
|
7511
|
+
if (resolvedKind) return resolvedKind;
|
|
7512
|
+
const normalizedRole = typeof role === "string" ? role.trim().toLowerCase() : "";
|
|
7513
|
+
return normalizedRole === "system" ? "system" : "standard";
|
|
7514
|
+
}
|
|
7515
|
+
function resolveChatMessageKind(message) {
|
|
7516
|
+
const explicitKind = resolveBuiltinOrAliasKind(message?.kind);
|
|
7517
|
+
if (explicitKind) return explicitKind;
|
|
7518
|
+
const inferredKind = inferMissingChatMessageKind(message);
|
|
7519
|
+
if (inferredKind) return inferredKind;
|
|
7520
|
+
return normalizeChatMessageKind(message?.kind, message?.role);
|
|
7521
|
+
}
|
|
7522
|
+
function buildChatMessage(message) {
|
|
7523
|
+
return {
|
|
7524
|
+
...message,
|
|
7525
|
+
kind: resolveChatMessageKind(message)
|
|
7526
|
+
};
|
|
7527
|
+
}
|
|
7528
|
+
function buildSystemChatMessage(message) {
|
|
7529
|
+
return buildChatMessage({
|
|
7530
|
+
...message,
|
|
7531
|
+
role: "system",
|
|
7532
|
+
kind: message?.kind || "system"
|
|
7533
|
+
});
|
|
7534
|
+
}
|
|
7535
|
+
function buildRuntimeSystemChatMessage(message) {
|
|
7536
|
+
return buildSystemChatMessage({
|
|
7537
|
+
...message,
|
|
7538
|
+
senderName: typeof message?.senderName === "string" && message.senderName.trim() ? message.senderName : "System"
|
|
7539
|
+
});
|
|
7540
|
+
}
|
|
7541
|
+
function buildAssistantChatMessage(message) {
|
|
7542
|
+
return buildChatMessage({
|
|
7543
|
+
...message,
|
|
7544
|
+
role: "assistant",
|
|
7545
|
+
kind: message?.kind || "standard"
|
|
7546
|
+
});
|
|
7547
|
+
}
|
|
7548
|
+
function buildThoughtChatMessage(message) {
|
|
7549
|
+
return buildAssistantChatMessage({
|
|
7550
|
+
...message,
|
|
7551
|
+
kind: message?.kind || "thought"
|
|
7552
|
+
});
|
|
7553
|
+
}
|
|
7554
|
+
function buildToolChatMessage(message) {
|
|
7555
|
+
return buildAssistantChatMessage({
|
|
7556
|
+
...message,
|
|
7557
|
+
kind: message?.kind || "tool"
|
|
7558
|
+
});
|
|
7559
|
+
}
|
|
7560
|
+
function buildTerminalChatMessage(message) {
|
|
7561
|
+
return buildAssistantChatMessage({
|
|
7562
|
+
...message,
|
|
7563
|
+
kind: message?.kind || "terminal"
|
|
7564
|
+
});
|
|
7565
|
+
}
|
|
7566
|
+
function buildUserChatMessage(message) {
|
|
7567
|
+
return buildChatMessage({
|
|
7568
|
+
...message,
|
|
7569
|
+
role: "user",
|
|
7570
|
+
kind: message?.kind || "standard"
|
|
7571
|
+
});
|
|
7572
|
+
}
|
|
7573
|
+
function normalizeChatMessage(message) {
|
|
7574
|
+
return buildChatMessage(message);
|
|
7575
|
+
}
|
|
7576
|
+
function normalizeChatMessages(messages) {
|
|
7577
|
+
return (Array.isArray(messages) ? messages : []).map((message) => normalizeChatMessage(message));
|
|
7578
|
+
}
|
|
7579
|
+
|
|
8486
7580
|
// src/providers/control-effects.ts
|
|
8487
|
-
init_contracts();
|
|
8488
|
-
init_chat_message_normalization();
|
|
8489
7581
|
function extractProviderControlValues(controls, data) {
|
|
8490
7582
|
if (!data || typeof data !== "object") return void 0;
|
|
8491
7583
|
const values = {};
|
|
@@ -8682,7 +7774,6 @@ ${cleanBody}`;
|
|
|
8682
7774
|
var fs3 = __toESM(require("fs"));
|
|
8683
7775
|
var path10 = __toESM(require("path"));
|
|
8684
7776
|
var os5 = __toESM(require("os"));
|
|
8685
|
-
init_chat_message_normalization();
|
|
8686
7777
|
var HISTORY_DIR = path10.join(os5.homedir(), ".adhdev", "history");
|
|
8687
7778
|
var RETAIN_DAYS = 30;
|
|
8688
7779
|
var SAVED_HISTORY_INDEX_VERSION = 1;
|
|
@@ -9961,9 +9052,6 @@ function resolveProviderStateSurface(params) {
|
|
|
9961
9052
|
};
|
|
9962
9053
|
}
|
|
9963
9054
|
|
|
9964
|
-
// src/providers/extension-provider-instance.ts
|
|
9965
|
-
init_chat_message_normalization();
|
|
9966
|
-
|
|
9967
9055
|
// src/providers/open-panel-support.ts
|
|
9968
9056
|
var IDE_PROVIDER_SESSION_CAPABILITIES_BASE = [
|
|
9969
9057
|
"read_chat",
|
|
@@ -10397,7 +9485,143 @@ ${effect.notification.body || ""}`.trim();
|
|
|
10397
9485
|
|
|
10398
9486
|
// src/providers/ide-provider-instance.ts
|
|
10399
9487
|
init_logger();
|
|
10400
|
-
|
|
9488
|
+
|
|
9489
|
+
// src/providers/read-chat-contract.ts
|
|
9490
|
+
var VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "streaming", "long_generating"];
|
|
9491
|
+
var VALID_ROLES = ["user", "assistant", "system", "human"];
|
|
9492
|
+
var VALID_BUBBLE_STATES = ["draft", "streaming", "final", "removed"];
|
|
9493
|
+
var VALID_TURN_STATUSES = ["open", "waiting_approval", "complete", "error"];
|
|
9494
|
+
function isPlainObject3(value) {
|
|
9495
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
9496
|
+
}
|
|
9497
|
+
function isFiniteNumber(value) {
|
|
9498
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
9499
|
+
}
|
|
9500
|
+
function validateStatus(status, source) {
|
|
9501
|
+
if (typeof status !== "string" || !VALID_STATUSES.includes(status)) {
|
|
9502
|
+
throw new Error(`${source}: status must be one of ${VALID_STATUSES.join(", ")}`);
|
|
9503
|
+
}
|
|
9504
|
+
return status;
|
|
9505
|
+
}
|
|
9506
|
+
function validateRole(role, source, index) {
|
|
9507
|
+
if (typeof role !== "string" || !VALID_ROLES.includes(role)) {
|
|
9508
|
+
throw new Error(`${source}: messages[${index}].role must be one of ${VALID_ROLES.join(", ")}`);
|
|
9509
|
+
}
|
|
9510
|
+
return role;
|
|
9511
|
+
}
|
|
9512
|
+
function validateBubbleState(state, source, index) {
|
|
9513
|
+
if (typeof state !== "string" || !VALID_BUBBLE_STATES.includes(state)) {
|
|
9514
|
+
throw new Error(`${source}: messages[${index}].bubbleState must be one of ${VALID_BUBBLE_STATES.join(", ")}`);
|
|
9515
|
+
}
|
|
9516
|
+
return state;
|
|
9517
|
+
}
|
|
9518
|
+
function validateTurnStatus(turnStatus, source) {
|
|
9519
|
+
if (typeof turnStatus !== "string" || !VALID_TURN_STATUSES.includes(turnStatus)) {
|
|
9520
|
+
throw new Error(`${source}: turnStatus must be one of ${VALID_TURN_STATUSES.join(", ")}`);
|
|
9521
|
+
}
|
|
9522
|
+
return turnStatus;
|
|
9523
|
+
}
|
|
9524
|
+
function validateMessageContent(content, source, index) {
|
|
9525
|
+
if (typeof content === "string") return content;
|
|
9526
|
+
if (Array.isArray(content)) return normalizeMessageParts(content);
|
|
9527
|
+
throw new Error(`${source}: messages[${index}].content must be a string or structured content array`);
|
|
9528
|
+
}
|
|
9529
|
+
function validateMessage(message, source, index) {
|
|
9530
|
+
if (!isPlainObject3(message)) {
|
|
9531
|
+
throw new Error(`${source}: messages[${index}] must be an object`);
|
|
9532
|
+
}
|
|
9533
|
+
const normalized = {
|
|
9534
|
+
role: validateRole(message.role, source, index),
|
|
9535
|
+
content: validateMessageContent(message.content, source, index)
|
|
9536
|
+
};
|
|
9537
|
+
if (typeof message.kind === "string") normalized.kind = message.kind;
|
|
9538
|
+
if (typeof message.id === "string") normalized.id = message.id;
|
|
9539
|
+
if (typeof message.bubbleId === "string") normalized.bubbleId = message.bubbleId;
|
|
9540
|
+
if (typeof message.providerUnitKey === "string") normalized.providerUnitKey = message.providerUnitKey;
|
|
9541
|
+
if (message.bubbleState !== void 0) normalized.bubbleState = validateBubbleState(message.bubbleState, source, index);
|
|
9542
|
+
if (isFiniteNumber(message.index)) normalized.index = message.index;
|
|
9543
|
+
if (isFiniteNumber(message.timestamp)) normalized.timestamp = message.timestamp;
|
|
9544
|
+
if (isFiniteNumber(message.receivedAt)) normalized.receivedAt = message.receivedAt;
|
|
9545
|
+
if (typeof message._turnKey === "string") normalized._turnKey = message._turnKey;
|
|
9546
|
+
if (Array.isArray(message.toolCalls)) normalized.toolCalls = message.toolCalls;
|
|
9547
|
+
if (isPlainObject3(message.meta)) normalized.meta = message.meta;
|
|
9548
|
+
if (typeof message.senderName === "string") normalized.senderName = message.senderName;
|
|
9549
|
+
if (typeof message._type === "string") normalized._type = message._type;
|
|
9550
|
+
if (typeof message._sub === "string") normalized._sub = message._sub;
|
|
9551
|
+
return normalized;
|
|
9552
|
+
}
|
|
9553
|
+
function validateModal(activeModal, status, source) {
|
|
9554
|
+
if (activeModal == null) {
|
|
9555
|
+
if (status === "waiting_approval") {
|
|
9556
|
+
throw new Error(`${source}: waiting_approval status requires activeModal with buttons`);
|
|
9557
|
+
}
|
|
9558
|
+
return activeModal === null ? null : void 0;
|
|
9559
|
+
}
|
|
9560
|
+
if (!isPlainObject3(activeModal)) {
|
|
9561
|
+
throw new Error(`${source}: activeModal must be an object when provided`);
|
|
9562
|
+
}
|
|
9563
|
+
if (typeof activeModal.message !== "string") {
|
|
9564
|
+
throw new Error(`${source}: activeModal.message must be a string`);
|
|
9565
|
+
}
|
|
9566
|
+
if (!Array.isArray(activeModal.buttons) || activeModal.buttons.some((button) => typeof button !== "string" || !button.trim())) {
|
|
9567
|
+
throw new Error(`${source}: activeModal.buttons must be a non-empty string array`);
|
|
9568
|
+
}
|
|
9569
|
+
const normalized = {
|
|
9570
|
+
message: activeModal.message,
|
|
9571
|
+
buttons: activeModal.buttons.map((button) => button.trim())
|
|
9572
|
+
};
|
|
9573
|
+
if (isFiniteNumber(activeModal.width)) normalized.width = activeModal.width;
|
|
9574
|
+
if (isFiniteNumber(activeModal.height)) normalized.height = activeModal.height;
|
|
9575
|
+
return normalized;
|
|
9576
|
+
}
|
|
9577
|
+
function validateControlValues(controlValues, source) {
|
|
9578
|
+
if (controlValues === void 0) return void 0;
|
|
9579
|
+
if (!isPlainObject3(controlValues)) {
|
|
9580
|
+
throw new Error(`${source}: controlValues must be an object when provided`);
|
|
9581
|
+
}
|
|
9582
|
+
const normalized = {};
|
|
9583
|
+
for (const [key, value] of Object.entries(controlValues)) {
|
|
9584
|
+
if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") {
|
|
9585
|
+
throw new Error(`${source}: controlValues.${key} must be string, number, or boolean`);
|
|
9586
|
+
}
|
|
9587
|
+
normalized[key] = value;
|
|
9588
|
+
}
|
|
9589
|
+
return normalized;
|
|
9590
|
+
}
|
|
9591
|
+
function validateReadChatResultPayload(raw, source = "read_chat") {
|
|
9592
|
+
if (!isPlainObject3(raw)) {
|
|
9593
|
+
throw new Error(`${source}: payload must be an object`);
|
|
9594
|
+
}
|
|
9595
|
+
const status = validateStatus(raw.status, source);
|
|
9596
|
+
if (!Array.isArray(raw.messages)) {
|
|
9597
|
+
throw new Error(`${source}: messages must be an array`);
|
|
9598
|
+
}
|
|
9599
|
+
const messages = raw.messages.map((message, index) => validateMessage(message, source, index));
|
|
9600
|
+
const activeModal = validateModal(raw.activeModal, status, source);
|
|
9601
|
+
const controlValues = validateControlValues(raw.controlValues, source);
|
|
9602
|
+
const normalized = {
|
|
9603
|
+
status,
|
|
9604
|
+
messages
|
|
9605
|
+
};
|
|
9606
|
+
if (activeModal !== void 0) normalized.activeModal = activeModal;
|
|
9607
|
+
if (typeof raw.id === "string") normalized.id = raw.id;
|
|
9608
|
+
if (typeof raw.title === "string") normalized.title = raw.title;
|
|
9609
|
+
if (typeof raw.currentTurnId === "string") normalized.currentTurnId = raw.currentTurnId;
|
|
9610
|
+
if (raw.turnStatus !== void 0) normalized.turnStatus = validateTurnStatus(raw.turnStatus, source);
|
|
9611
|
+
if (typeof raw.agentType === "string") normalized.agentType = raw.agentType;
|
|
9612
|
+
if (typeof raw.agentName === "string") normalized.agentName = raw.agentName;
|
|
9613
|
+
if (typeof raw.extensionId === "string") normalized.extensionId = raw.extensionId;
|
|
9614
|
+
if (typeof raw.inputContent === "string") normalized.inputContent = raw.inputContent;
|
|
9615
|
+
if (typeof raw.isVisible === "boolean") normalized.isVisible = raw.isVisible;
|
|
9616
|
+
if (typeof raw.isWelcomeScreen === "boolean") normalized.isWelcomeScreen = raw.isWelcomeScreen;
|
|
9617
|
+
if (controlValues) normalized.controlValues = controlValues;
|
|
9618
|
+
if (raw.summaryMetadata !== void 0) normalized.summaryMetadata = raw.summaryMetadata;
|
|
9619
|
+
if (Array.isArray(raw.effects)) normalized.effects = raw.effects;
|
|
9620
|
+
if (typeof raw.providerSessionId === "string") normalized.providerSessionId = raw.providerSessionId;
|
|
9621
|
+
if (raw.transcriptAuthority === "provider" || raw.transcriptAuthority === "daemon") normalized.transcriptAuthority = raw.transcriptAuthority;
|
|
9622
|
+
if (raw.coverage === "full" || raw.coverage === "tail" || raw.coverage === "current-turn") normalized.coverage = raw.coverage;
|
|
9623
|
+
return normalized;
|
|
9624
|
+
}
|
|
10401
9625
|
|
|
10402
9626
|
// src/providers/approval-utils.ts
|
|
10403
9627
|
var DEFAULT_APPROVAL_POSITIVE_HINTS = [
|
|
@@ -10447,7 +9671,6 @@ function formatAutoApprovalMessage(modalMessage, buttonLabel) {
|
|
|
10447
9671
|
}
|
|
10448
9672
|
|
|
10449
9673
|
// src/providers/ide-provider-instance.ts
|
|
10450
|
-
init_chat_message_normalization();
|
|
10451
9674
|
var IdeProviderInstance = class {
|
|
10452
9675
|
type;
|
|
10453
9676
|
category = "ide";
|
|
@@ -11910,7 +11133,6 @@ var fs4 = __toESM(require("fs"));
|
|
|
11910
11133
|
var os6 = __toESM(require("os"));
|
|
11911
11134
|
var path11 = __toESM(require("path"));
|
|
11912
11135
|
var import_node_crypto = require("crypto");
|
|
11913
|
-
init_contracts();
|
|
11914
11136
|
|
|
11915
11137
|
// src/providers/provider-input-support.ts
|
|
11916
11138
|
var VALID_INPUT_MEDIA_TYPES = /* @__PURE__ */ new Set(["text", "image", "audio", "video", "resource"]);
|
|
@@ -11968,7 +11190,6 @@ function assertProviderSupportsDeclaredInput(provider, input) {
|
|
|
11968
11190
|
}
|
|
11969
11191
|
|
|
11970
11192
|
// src/commands/chat-commands.ts
|
|
11971
|
-
init_read_chat_contract();
|
|
11972
11193
|
init_logger();
|
|
11973
11194
|
|
|
11974
11195
|
// src/logging/debug-trace.ts
|
|
@@ -12096,10 +11317,6 @@ function buildChatTailDeliverySignature(payload) {
|
|
|
12096
11317
|
payload.historySessionId || "",
|
|
12097
11318
|
payload.status,
|
|
12098
11319
|
payload.title || "",
|
|
12099
|
-
payload.syncMode,
|
|
12100
|
-
String(payload.replaceFrom),
|
|
12101
|
-
String(payload.totalMessages),
|
|
12102
|
-
payload.lastMessageSignature,
|
|
12103
11320
|
payload.activeModal ? `${payload.activeModal.message}|${payload.activeModal.buttons.join("")}` : "",
|
|
12104
11321
|
stringifySignatureMessages(payload.messages)
|
|
12105
11322
|
]);
|
|
@@ -12115,7 +11332,6 @@ function buildSessionModalDeliverySignature(payload) {
|
|
|
12115
11332
|
}
|
|
12116
11333
|
|
|
12117
11334
|
// src/commands/chat-commands.ts
|
|
12118
|
-
init_chat_message_normalization();
|
|
12119
11335
|
var RECENT_SEND_WINDOW_MS = 1200;
|
|
12120
11336
|
var READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS = 25e3;
|
|
12121
11337
|
var recentSendByTarget = /* @__PURE__ */ new Map();
|
|
@@ -12216,99 +11432,13 @@ function parseMaybeJson(value) {
|
|
|
12216
11432
|
return value;
|
|
12217
11433
|
}
|
|
12218
11434
|
}
|
|
12219
|
-
function
|
|
12220
|
-
|
|
12221
|
-
|
|
12222
|
-
function normalizeReadChatCursor(args) {
|
|
12223
|
-
const knownMessageCount = Math.max(0, Number(args?.knownMessageCount || 0));
|
|
12224
|
-
const lastMessageSignature = typeof args?.lastMessageSignature === "string" ? args.lastMessageSignature : "";
|
|
12225
|
-
const tailLimit = Math.max(0, Number(args?.tailLimit || 0));
|
|
12226
|
-
return { knownMessageCount, lastMessageSignature, tailLimit };
|
|
11435
|
+
function normalizeReadChatTailLimit(args) {
|
|
11436
|
+
const value = Number(args?.tailLimit || 0);
|
|
11437
|
+
return Number.isFinite(value) ? Math.max(0, value) : 0;
|
|
12227
11438
|
}
|
|
12228
11439
|
function normalizeReadChatMessages(payload) {
|
|
12229
11440
|
const messages = Array.isArray(payload.messages) ? payload.messages : [];
|
|
12230
|
-
return
|
|
12231
|
-
}
|
|
12232
|
-
function normalizeReadChatReplayTextContent(content) {
|
|
12233
|
-
return flattenContent(content || "").replace(/\s+/g, " ").trim();
|
|
12234
|
-
}
|
|
12235
|
-
function getReadChatReplayCollapseInfo(message) {
|
|
12236
|
-
if (!message) return null;
|
|
12237
|
-
const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
|
|
12238
|
-
const kind = typeof message.kind === "string" ? message.kind.trim().toLowerCase() : "standard";
|
|
12239
|
-
const senderName = typeof message.senderName === "string" ? message.senderName.trim().toLowerCase() : "";
|
|
12240
|
-
const collapsible = role === "assistant" || role === "system";
|
|
12241
|
-
if (!collapsible) return { role, kind, senderName, content: "", signature: "", collapsible };
|
|
12242
|
-
const content = normalizeReadChatReplayTextContent(message.content);
|
|
12243
|
-
return {
|
|
12244
|
-
role,
|
|
12245
|
-
kind,
|
|
12246
|
-
senderName,
|
|
12247
|
-
content,
|
|
12248
|
-
signature: `${role}:${kind}:${senderName}:${content}`,
|
|
12249
|
-
collapsible
|
|
12250
|
-
};
|
|
12251
|
-
}
|
|
12252
|
-
function isStableReadChatAssistantAnswerInfo(info) {
|
|
12253
|
-
if (!info) return false;
|
|
12254
|
-
if (info.role !== "assistant") return false;
|
|
12255
|
-
if (info.kind && info.kind !== "standard") return false;
|
|
12256
|
-
if (info.content.length < 160) return false;
|
|
12257
|
-
if (/^(bash|shell|terminal) command\b/i.test(info.content)) return false;
|
|
12258
|
-
return true;
|
|
12259
|
-
}
|
|
12260
|
-
function isReplayedAssistantAnswerAfterStableAnswerInfo(info, stableContent) {
|
|
12261
|
-
if (!info || !stableContent) return false;
|
|
12262
|
-
if (info.role !== "assistant") return false;
|
|
12263
|
-
if (info.kind && info.kind !== "standard") return false;
|
|
12264
|
-
const content = info.content;
|
|
12265
|
-
if (content.length < 80 || stableContent.length < 80) return false;
|
|
12266
|
-
return content === stableContent || content.startsWith(stableContent) || stableContent.startsWith(content);
|
|
12267
|
-
}
|
|
12268
|
-
function collapseReplayDuplicatesFromReadChat(messages) {
|
|
12269
|
-
const collapsed = [];
|
|
12270
|
-
const replaySignaturesInCurrentTurn = /* @__PURE__ */ new Set();
|
|
12271
|
-
let stableAssistantAnswerContentInCurrentTurn = "";
|
|
12272
|
-
let stableAssistantAnswerCollapsedIndex = -1;
|
|
12273
|
-
let stableAssistantAnswerHadInterveningActivity = false;
|
|
12274
|
-
let previousReplaySignature = "";
|
|
12275
|
-
for (const message of messages) {
|
|
12276
|
-
const info = getReadChatReplayCollapseInfo(message);
|
|
12277
|
-
if (info?.role === "user") {
|
|
12278
|
-
replaySignaturesInCurrentTurn.clear();
|
|
12279
|
-
stableAssistantAnswerContentInCurrentTurn = "";
|
|
12280
|
-
stableAssistantAnswerCollapsedIndex = -1;
|
|
12281
|
-
stableAssistantAnswerHadInterveningActivity = false;
|
|
12282
|
-
previousReplaySignature = "";
|
|
12283
|
-
}
|
|
12284
|
-
if (info?.collapsible && info.signature) {
|
|
12285
|
-
if (previousReplaySignature === info.signature) continue;
|
|
12286
|
-
if (replaySignaturesInCurrentTurn.has(info.signature)) continue;
|
|
12287
|
-
if (isReplayedAssistantAnswerAfterStableAnswerInfo(info, stableAssistantAnswerContentInCurrentTurn)) {
|
|
12288
|
-
const isAdjacentFullerAssistantAnswer = info.role === "assistant" && (!info.kind || info.kind === "standard") && stableAssistantAnswerCollapsedIndex >= 0 && stableAssistantAnswerCollapsedIndex === collapsed.length - 1 && !stableAssistantAnswerHadInterveningActivity && info.content.length > stableAssistantAnswerContentInCurrentTurn.length && info.content.startsWith(stableAssistantAnswerContentInCurrentTurn);
|
|
12289
|
-
if (isAdjacentFullerAssistantAnswer) {
|
|
12290
|
-
collapsed[stableAssistantAnswerCollapsedIndex] = message;
|
|
12291
|
-
replaySignaturesInCurrentTurn.add(info.signature);
|
|
12292
|
-
stableAssistantAnswerContentInCurrentTurn = info.content;
|
|
12293
|
-
previousReplaySignature = info.signature;
|
|
12294
|
-
}
|
|
12295
|
-
continue;
|
|
12296
|
-
}
|
|
12297
|
-
}
|
|
12298
|
-
collapsed.push(message);
|
|
12299
|
-
previousReplaySignature = info?.collapsible ? info.signature : "";
|
|
12300
|
-
if (info?.collapsible && info.signature) {
|
|
12301
|
-
replaySignaturesInCurrentTurn.add(info.signature);
|
|
12302
|
-
}
|
|
12303
|
-
if (isStableReadChatAssistantAnswerInfo(info)) {
|
|
12304
|
-
stableAssistantAnswerContentInCurrentTurn = info?.content || "";
|
|
12305
|
-
stableAssistantAnswerCollapsedIndex = collapsed.length - 1;
|
|
12306
|
-
stableAssistantAnswerHadInterveningActivity = false;
|
|
12307
|
-
} else if (stableAssistantAnswerContentInCurrentTurn && info?.role === "assistant" && (!info.kind || info.kind !== "standard")) {
|
|
12308
|
-
stableAssistantAnswerHadInterveningActivity = true;
|
|
12309
|
-
}
|
|
12310
|
-
}
|
|
12311
|
-
return collapsed;
|
|
11441
|
+
return messages;
|
|
12312
11442
|
}
|
|
12313
11443
|
function deriveHistoryDedupKey(message) {
|
|
12314
11444
|
const unitKey = typeof message._unitKey === "string" ? message._unitKey.trim() : "";
|
|
@@ -12333,127 +11463,12 @@ function toHistoryPersistedMessages(messages) {
|
|
|
12333
11463
|
historyDedupKey: deriveHistoryDedupKey(message)
|
|
12334
11464
|
}));
|
|
12335
11465
|
}
|
|
12336
|
-
function
|
|
12337
|
-
if (!signature) return -1;
|
|
12338
|
-
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
12339
|
-
if (getChatMessageSignature(messages[index]) === signature) {
|
|
12340
|
-
return index;
|
|
12341
|
-
}
|
|
12342
|
-
}
|
|
12343
|
-
return -1;
|
|
12344
|
-
}
|
|
12345
|
-
function isReadChatConversationAnchorMessage(message) {
|
|
12346
|
-
if (!message) return false;
|
|
12347
|
-
const role = String(message.role || "").trim().toLowerCase();
|
|
12348
|
-
if (role !== "user" && role !== "assistant") return false;
|
|
12349
|
-
const kind = String(message.kind || "standard").trim().toLowerCase();
|
|
12350
|
-
return !kind || kind === "standard";
|
|
12351
|
-
}
|
|
12352
|
-
function buildVisibleReadChatTailMessages(messages, tailLimit) {
|
|
11466
|
+
function buildFullTail(messages, tailLimit) {
|
|
12353
11467
|
const totalMessages = messages.length;
|
|
12354
|
-
|
|
12355
|
-
const tailMessages = messages.slice(-tailLimit);
|
|
12356
|
-
if (tailMessages.some(isReadChatConversationAnchorMessage)) return tailMessages;
|
|
12357
|
-
const hiddenMessages = messages.slice(0, totalMessages - tailLimit);
|
|
12358
|
-
const anchors = [];
|
|
12359
|
-
const seenRoles = /* @__PURE__ */ new Set();
|
|
12360
|
-
for (let index = hiddenMessages.length - 1; index >= 0 && anchors.length < 2; index -= 1) {
|
|
12361
|
-
const message = hiddenMessages[index];
|
|
12362
|
-
if (!isReadChatConversationAnchorMessage(message)) continue;
|
|
12363
|
-
const role = String(message.role || "").trim().toLowerCase();
|
|
12364
|
-
if (seenRoles.has(role)) continue;
|
|
12365
|
-
seenRoles.add(role);
|
|
12366
|
-
anchors.unshift(message);
|
|
12367
|
-
}
|
|
12368
|
-
return anchors.length > 0 ? [...anchors, ...tailMessages] : tailMessages;
|
|
12369
|
-
}
|
|
12370
|
-
function buildBoundedTailSync(messages, cursor) {
|
|
12371
|
-
const totalMessages = messages.length;
|
|
12372
|
-
const tailMessages = buildVisibleReadChatTailMessages(messages, cursor.tailLimit);
|
|
11468
|
+
const tailMessages = tailLimit > 0 ? messages.slice(-tailLimit) : messages;
|
|
12373
11469
|
return {
|
|
12374
|
-
syncMode: "full",
|
|
12375
|
-
replaceFrom: 0,
|
|
12376
11470
|
messages: tailMessages,
|
|
12377
|
-
totalMessages
|
|
12378
|
-
lastMessageSignature: getChatMessageSignature(messages[totalMessages - 1])
|
|
12379
|
-
};
|
|
12380
|
-
}
|
|
12381
|
-
function computeReadChatSync(messages, cursor) {
|
|
12382
|
-
const totalMessages = messages.length;
|
|
12383
|
-
const lastMessageSignature = getChatMessageSignature(messages[totalMessages - 1]);
|
|
12384
|
-
const { knownMessageCount, lastMessageSignature: knownSignature } = cursor;
|
|
12385
|
-
if (!knownMessageCount || !knownSignature) {
|
|
12386
|
-
return {
|
|
12387
|
-
syncMode: "full",
|
|
12388
|
-
replaceFrom: 0,
|
|
12389
|
-
messages,
|
|
12390
|
-
totalMessages,
|
|
12391
|
-
lastMessageSignature
|
|
12392
|
-
};
|
|
12393
|
-
}
|
|
12394
|
-
if (knownMessageCount > totalMessages) {
|
|
12395
|
-
return {
|
|
12396
|
-
syncMode: "full",
|
|
12397
|
-
replaceFrom: 0,
|
|
12398
|
-
messages,
|
|
12399
|
-
totalMessages,
|
|
12400
|
-
lastMessageSignature
|
|
12401
|
-
};
|
|
12402
|
-
}
|
|
12403
|
-
if (knownMessageCount === totalMessages && knownSignature === lastMessageSignature) {
|
|
12404
|
-
return {
|
|
12405
|
-
syncMode: "noop",
|
|
12406
|
-
replaceFrom: totalMessages,
|
|
12407
|
-
messages: [],
|
|
12408
|
-
totalMessages,
|
|
12409
|
-
lastMessageSignature
|
|
12410
|
-
};
|
|
12411
|
-
}
|
|
12412
|
-
if (cursor.tailLimit > 0 && knownSignature === lastMessageSignature) {
|
|
12413
|
-
const requestedTailCount = Math.min(totalMessages, cursor.tailLimit);
|
|
12414
|
-
if (knownMessageCount >= requestedTailCount) {
|
|
12415
|
-
return {
|
|
12416
|
-
syncMode: "noop",
|
|
12417
|
-
replaceFrom: totalMessages,
|
|
12418
|
-
messages: [],
|
|
12419
|
-
totalMessages,
|
|
12420
|
-
lastMessageSignature
|
|
12421
|
-
};
|
|
12422
|
-
}
|
|
12423
|
-
return buildBoundedTailSync(messages, cursor);
|
|
12424
|
-
}
|
|
12425
|
-
if (knownMessageCount < totalMessages) {
|
|
12426
|
-
const anchorSignature = getChatMessageSignature(messages[knownMessageCount - 1]);
|
|
12427
|
-
if (anchorSignature === knownSignature) {
|
|
12428
|
-
return {
|
|
12429
|
-
syncMode: "append",
|
|
12430
|
-
replaceFrom: knownMessageCount,
|
|
12431
|
-
messages: messages.slice(knownMessageCount),
|
|
12432
|
-
totalMessages,
|
|
12433
|
-
lastMessageSignature
|
|
12434
|
-
};
|
|
12435
|
-
}
|
|
12436
|
-
if (cursor.tailLimit > 0) {
|
|
12437
|
-
const signatureIndex = findLastMessageIndexBySignature(messages, knownSignature);
|
|
12438
|
-
if (signatureIndex >= 0) {
|
|
12439
|
-
return {
|
|
12440
|
-
syncMode: "append",
|
|
12441
|
-
replaceFrom: knownMessageCount,
|
|
12442
|
-
messages: messages.slice(signatureIndex + 1),
|
|
12443
|
-
totalMessages,
|
|
12444
|
-
lastMessageSignature
|
|
12445
|
-
};
|
|
12446
|
-
}
|
|
12447
|
-
return buildBoundedTailSync(messages, cursor);
|
|
12448
|
-
}
|
|
12449
|
-
}
|
|
12450
|
-
const replaceFrom = Math.max(0, Math.min(knownMessageCount - 1, totalMessages));
|
|
12451
|
-
return {
|
|
12452
|
-
syncMode: replaceFrom === 0 ? "full" : "replace_tail",
|
|
12453
|
-
replaceFrom,
|
|
12454
|
-
messages: replaceFrom === 0 ? messages : messages.slice(replaceFrom),
|
|
12455
|
-
totalMessages,
|
|
12456
|
-
lastMessageSignature
|
|
11471
|
+
totalMessages
|
|
12457
11472
|
};
|
|
12458
11473
|
}
|
|
12459
11474
|
function hasNonEmptyModalButtons(activeModal) {
|
|
@@ -12488,31 +11503,13 @@ function buildReadChatCommandResult(payload, args) {
|
|
|
12488
11503
|
} catch (error) {
|
|
12489
11504
|
return { success: false, error: error?.message || String(error) };
|
|
12490
11505
|
}
|
|
12491
|
-
const messages =
|
|
12492
|
-
const
|
|
12493
|
-
if (!cursor.knownMessageCount && !cursor.lastMessageSignature && cursor.tailLimit > 0 && messages.length > cursor.tailLimit) {
|
|
12494
|
-
const tailMessages = buildVisibleReadChatTailMessages(messages, cursor.tailLimit);
|
|
12495
|
-
const lastMessageSignature = getChatMessageSignature(messages[messages.length - 1]);
|
|
12496
|
-
return {
|
|
12497
|
-
success: true,
|
|
12498
|
-
...validatedPayload,
|
|
12499
|
-
messages: tailMessages,
|
|
12500
|
-
syncMode: "full",
|
|
12501
|
-
replaceFrom: 0,
|
|
12502
|
-
totalMessages: messages.length,
|
|
12503
|
-
lastMessageSignature,
|
|
12504
|
-
...debugReadChat ? { debugReadChat } : {}
|
|
12505
|
-
};
|
|
12506
|
-
}
|
|
12507
|
-
const sync = computeReadChatSync(messages, cursor);
|
|
11506
|
+
const messages = normalizeReadChatMessages(validatedPayload);
|
|
11507
|
+
const sync = buildFullTail(messages, normalizeReadChatTailLimit(args));
|
|
12508
11508
|
return {
|
|
12509
11509
|
success: true,
|
|
12510
11510
|
...validatedPayload,
|
|
12511
11511
|
messages: sync.messages,
|
|
12512
|
-
syncMode: sync.syncMode,
|
|
12513
|
-
replaceFrom: sync.replaceFrom,
|
|
12514
11512
|
totalMessages: sync.totalMessages,
|
|
12515
|
-
lastMessageSignature: sync.lastMessageSignature,
|
|
12516
11513
|
...debugReadChat ? { debugReadChat } : {}
|
|
12517
11514
|
};
|
|
12518
11515
|
}
|
|
@@ -12737,10 +11734,6 @@ async function handleGetChatDebugBundle(h, args) {
|
|
|
12737
11734
|
status: readResult.status,
|
|
12738
11735
|
title: readResult.title,
|
|
12739
11736
|
totalMessages: readResult.totalMessages,
|
|
12740
|
-
returnedMessages: Array.isArray(readResult.messages) ? readResult.messages.length : void 0,
|
|
12741
|
-
syncMode: readResult.syncMode,
|
|
12742
|
-
replaceFrom: readResult.replaceFrom,
|
|
12743
|
-
lastMessageSignature: readResult.lastMessageSignature,
|
|
12744
11737
|
providerSessionId: readResult.providerSessionId,
|
|
12745
11738
|
transcriptAuthority: readResult.transcriptAuthority,
|
|
12746
11739
|
coverage: readResult.coverage,
|
|
@@ -12850,22 +11843,13 @@ function toNonNegativeNumber(value) {
|
|
|
12850
11843
|
return Number.isFinite(numeric) ? Math.max(0, numeric) : 0;
|
|
12851
11844
|
}
|
|
12852
11845
|
function getCliVisibleTranscriptCount(adapter) {
|
|
12853
|
-
|
|
12854
|
-
|
|
12855
|
-
|
|
12856
|
-
|
|
12857
|
-
|
|
12858
|
-
|
|
12859
|
-
parsedRecord = parsed && typeof parsed === "object" ? parsed : null;
|
|
12860
|
-
} catch {
|
|
12861
|
-
parsedRecord = null;
|
|
12862
|
-
}
|
|
11846
|
+
if (typeof adapter?.getScriptParsedStatus !== "function") return 0;
|
|
11847
|
+
try {
|
|
11848
|
+
const parsed = parseMaybeJson(adapter.getScriptParsedStatus());
|
|
11849
|
+
return Array.isArray(parsed?.messages) ? parsed.messages.length : 0;
|
|
11850
|
+
} catch {
|
|
11851
|
+
return 0;
|
|
12863
11852
|
}
|
|
12864
|
-
const parsedMessages = Array.isArray(parsedRecord?.messages) ? parsedRecord.messages : [];
|
|
12865
|
-
if (!parsedRecord) return adapterMessages.length;
|
|
12866
|
-
const parsedIsProviderAuthoritative = parsedRecord.transcriptAuthority === "provider" || parsedRecord.coverage === "full";
|
|
12867
|
-
const shouldPreferAdapterMessages = !parsedIsProviderAuthoritative && adapterMessages.length > 0 && adapterMessages.length > parsedMessages.length;
|
|
12868
|
-
return shouldPreferAdapterMessages ? adapterMessages.length : parsedMessages.length;
|
|
12869
11853
|
}
|
|
12870
11854
|
async function getStableExtensionBaseline(h) {
|
|
12871
11855
|
const first = await readExtensionChatState(h);
|
|
@@ -12927,52 +11911,46 @@ async function handleReadChat(h, args) {
|
|
|
12927
11911
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
12928
11912
|
if (adapter) {
|
|
12929
11913
|
_log(`${transport} adapter: ${adapter.cliType}`);
|
|
11914
|
+
if (typeof adapter.getScriptParsedStatus !== "function") {
|
|
11915
|
+
return { success: false, error: `${transport} adapter parseSession unavailable` };
|
|
11916
|
+
}
|
|
12930
11917
|
let parsedStatus = null;
|
|
12931
|
-
|
|
12932
|
-
|
|
12933
|
-
|
|
12934
|
-
|
|
12935
|
-
return { success: false, error: error?.message || String(error) };
|
|
12936
|
-
}
|
|
11918
|
+
try {
|
|
11919
|
+
parsedStatus = parseMaybeJson(adapter.getScriptParsedStatus());
|
|
11920
|
+
} catch (error) {
|
|
11921
|
+
return { success: false, error: error?.message || String(error) };
|
|
12937
11922
|
}
|
|
12938
11923
|
const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
const
|
|
12943
|
-
const
|
|
12944
|
-
|
|
12945
|
-
|
|
12946
|
-
|
|
12947
|
-
|
|
12948
|
-
|
|
12949
|
-
|
|
12950
|
-
|
|
12951
|
-
|
|
12952
|
-
|
|
12953
|
-
|
|
12954
|
-
|
|
12955
|
-
|
|
12956
|
-
|
|
12957
|
-
|
|
12958
|
-
|
|
12959
|
-
|
|
12960
|
-
|
|
12961
|
-
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
|
|
12965
|
-
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
12969
|
-
},
|
|
12970
|
-
...title ? { title } : {},
|
|
12971
|
-
...providerSessionId ? { providerSessionId } : {},
|
|
12972
|
-
...transcriptAuthority ? { transcriptAuthority } : {},
|
|
12973
|
-
...coverage ? { coverage } : {}
|
|
12974
|
-
}, args);
|
|
12975
|
-
}
|
|
11924
|
+
if (!parsedRecord || !Array.isArray(parsedRecord.messages)) {
|
|
11925
|
+
return { success: false, error: `${transport} parser did not return messages` };
|
|
11926
|
+
}
|
|
11927
|
+
const adapterStatus = typeof adapter.getStatus === "function" ? adapter.getStatus() : {};
|
|
11928
|
+
const title = typeof parsedRecord.title === "string" ? parsedRecord.title : void 0;
|
|
11929
|
+
const providerSessionId = typeof parsedRecord.providerSessionId === "string" ? parsedRecord.providerSessionId : void 0;
|
|
11930
|
+
const transcriptAuthority = parsedRecord.transcriptAuthority === "provider" || parsedRecord.transcriptAuthority === "daemon" ? parsedRecord.transcriptAuthority : void 0;
|
|
11931
|
+
const coverage = parsedRecord.coverage === "full" || parsedRecord.coverage === "tail" || parsedRecord.coverage === "current-turn" ? parsedRecord.coverage : void 0;
|
|
11932
|
+
const activeModal = parsedRecord.activeModal ?? parsedRecord.modal ?? null;
|
|
11933
|
+
const returnedStatus = parsedRecord.status || "idle";
|
|
11934
|
+
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}`);
|
|
11935
|
+
return buildReadChatCommandResult({
|
|
11936
|
+
messages: parsedRecord.messages,
|
|
11937
|
+
status: returnedStatus,
|
|
11938
|
+
activeModal,
|
|
11939
|
+
debugReadChat: {
|
|
11940
|
+
provider: adapter.cliType,
|
|
11941
|
+
targetSessionId: String(args?.targetSessionId || ""),
|
|
11942
|
+
adapterStatus: String(adapterStatus.status || ""),
|
|
11943
|
+
parsedStatus: String(parsedRecord.status || ""),
|
|
11944
|
+
returnedStatus: String(returnedStatus || ""),
|
|
11945
|
+
shouldPreferAdapterMessages: false,
|
|
11946
|
+
parsedMsgCount: parsedRecord.messages.length,
|
|
11947
|
+
returnedMsgCount: parsedRecord.messages.length
|
|
11948
|
+
},
|
|
11949
|
+
...title ? { title } : {},
|
|
11950
|
+
...providerSessionId ? { providerSessionId } : {},
|
|
11951
|
+
...transcriptAuthority ? { transcriptAuthority } : {},
|
|
11952
|
+
...coverage ? { coverage } : {}
|
|
11953
|
+
}, args);
|
|
12976
11954
|
}
|
|
12977
11955
|
return { success: false, error: `${transport} adapter not found` };
|
|
12978
11956
|
}
|
|
@@ -15276,7 +14254,6 @@ var path15 = __toESM(require("path"));
|
|
|
15276
14254
|
var crypto3 = __toESM(require("crypto"));
|
|
15277
14255
|
var fs6 = __toESM(require("fs"));
|
|
15278
14256
|
var import_node_module = require("module");
|
|
15279
|
-
init_contracts();
|
|
15280
14257
|
init_provider_cli_adapter();
|
|
15281
14258
|
init_logger();
|
|
15282
14259
|
|
|
@@ -15298,7 +14275,6 @@ function normalizeProviderSessionId(provider, providerSessionId) {
|
|
|
15298
14275
|
}
|
|
15299
14276
|
|
|
15300
14277
|
// src/providers/cli-provider-instance.ts
|
|
15301
|
-
init_chat_message_normalization();
|
|
15302
14278
|
function normalizePersistableCliHistoryContent(content) {
|
|
15303
14279
|
return flattenContent(content).replace(/\s+/g, " ").trim();
|
|
15304
14280
|
}
|
|
@@ -15538,17 +14514,11 @@ var CliProviderInstance = class {
|
|
|
15538
14514
|
}
|
|
15539
14515
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
15540
14516
|
this.maybeAppendRuntimeRecoveryMessage(runtime);
|
|
15541
|
-
let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages :
|
|
14517
|
+
let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
|
|
15542
14518
|
const historyMessageCount = Number.isFinite(parsedStatus?.historyMessageCount) ? Math.max(0, Number(parsedStatus.historyMessageCount)) : null;
|
|
15543
14519
|
if (historyMessageCount !== null) {
|
|
15544
14520
|
parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
|
|
15545
14521
|
}
|
|
15546
|
-
const committedMessages = Array.isArray(adapterStatus.messages) ? adapterStatus.messages : [];
|
|
15547
|
-
const isActiveNonIdle = adapterStatus.status !== "idle";
|
|
15548
|
-
const shouldApplyCommittedFloor = parsedMessages.length < committedMessages.length && (adapterStatus.status === "waiting_approval" || isActiveNonIdle && historyMessageCount === null);
|
|
15549
|
-
if (shouldApplyCommittedFloor) {
|
|
15550
|
-
parsedMessages = normalizeChatMessages(committedMessages);
|
|
15551
|
-
}
|
|
15552
14522
|
const mergedMessages = this.mergeConversationMessages(parsedMessages);
|
|
15553
14523
|
const canonicalBackedHistory = this.syncCanonicalSavedHistoryIfNeeded();
|
|
15554
14524
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
@@ -15641,11 +14611,9 @@ var CliProviderInstance = class {
|
|
|
15641
14611
|
const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
15642
14612
|
const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
|
|
15643
14613
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
15644
|
-
const lastCommittedMessageActivityAt = typeof this.adapter.getLastCommittedMessageActivityAt === "function" ? this.adapter.getLastCommittedMessageActivityAt() : 0;
|
|
15645
14614
|
return {
|
|
15646
14615
|
id: this.instanceId,
|
|
15647
14616
|
status: visibleStatus,
|
|
15648
|
-
lastMessageAt: lastCommittedMessageActivityAt || void 0,
|
|
15649
14617
|
runtimeLifecycle: runtime?.lifecycle ?? null,
|
|
15650
14618
|
runtimeSurfaceKind: runtime?.surfaceKind,
|
|
15651
14619
|
runtimeRestoredFromStorage: runtime?.restoredFromStorage === true,
|
|
@@ -15751,7 +14719,7 @@ var CliProviderInstance = class {
|
|
|
15751
14719
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
15752
14720
|
const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
|
|
15753
14721
|
const partial = this.adapter.getPartialResponse();
|
|
15754
|
-
const progressFingerprint = newStatus === "generating" ? `${partial || ""}
|
|
14722
|
+
const progressFingerprint = newStatus === "generating" ? `${partial || ""}`.slice(-2e3) : void 0;
|
|
15755
14723
|
const previousStatus = this.lastStatus;
|
|
15756
14724
|
if (newStatus !== this.lastStatus) {
|
|
15757
14725
|
LOG.info("CLI", `[${this.type}] status: ${this.lastStatus} \u2192 ${newStatus}`);
|
|
@@ -16197,18 +15165,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
16197
15165
|
receivedAt: message.receivedAt
|
|
16198
15166
|
}));
|
|
16199
15167
|
this.suppressIdleHistoryReplay = restoredHistory.messages.length > 0;
|
|
16200
|
-
if (restoredHistory.messages.length > 0) {
|
|
16201
|
-
this.adapter.seedCommittedMessages(
|
|
16202
|
-
restoredHistory.messages.map((message) => ({
|
|
16203
|
-
role: message.role,
|
|
16204
|
-
content: message.content,
|
|
16205
|
-
timestamp: message.receivedAt,
|
|
16206
|
-
receivedAt: message.receivedAt,
|
|
16207
|
-
kind: message.kind,
|
|
16208
|
-
senderName: message.senderName
|
|
16209
|
-
}))
|
|
16210
|
-
);
|
|
16211
|
-
}
|
|
16212
15168
|
}
|
|
16213
15169
|
getProbeDirectories() {
|
|
16214
15170
|
const dirs = /* @__PURE__ */ new Set();
|
|
@@ -16258,8 +15214,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
16258
15214
|
var import_stream = require("stream");
|
|
16259
15215
|
var import_child_process5 = require("child_process");
|
|
16260
15216
|
var import_sdk = require("@agentclientprotocol/sdk");
|
|
16261
|
-
init_contracts();
|
|
16262
|
-
init_chat_message_normalization();
|
|
16263
15217
|
init_logger();
|
|
16264
15218
|
function getPromptCapabilityFlags(agentCapabilities) {
|
|
16265
15219
|
const prompt = agentCapabilities?.promptCapabilities || {};
|
|
@@ -17403,7 +16357,6 @@ ${rawInput}` : rawInput;
|
|
|
17403
16357
|
};
|
|
17404
16358
|
|
|
17405
16359
|
// src/commands/cli-manager.ts
|
|
17406
|
-
init_contracts();
|
|
17407
16360
|
init_logger();
|
|
17408
16361
|
|
|
17409
16362
|
// src/commands/hosted-runtime-restore.ts
|
|
@@ -20337,13 +19290,24 @@ async function launchWithCdp(options = {}) {
|
|
|
20337
19290
|
break;
|
|
20338
19291
|
}
|
|
20339
19292
|
}
|
|
19293
|
+
if (!cdpReady) {
|
|
19294
|
+
return {
|
|
19295
|
+
success: false,
|
|
19296
|
+
ideId: targetIde.id,
|
|
19297
|
+
ideName: targetIde.displayName,
|
|
19298
|
+
port,
|
|
19299
|
+
action: "failed",
|
|
19300
|
+
message: "",
|
|
19301
|
+
error: `${targetIde.displayName} launched but CDP did not become available on port ${port}`
|
|
19302
|
+
};
|
|
19303
|
+
}
|
|
20340
19304
|
return {
|
|
20341
19305
|
success: true,
|
|
20342
19306
|
ideId: targetIde.id,
|
|
20343
19307
|
ideName: targetIde.displayName,
|
|
20344
19308
|
port,
|
|
20345
19309
|
action: alreadyRunning ? "restarted" : "started",
|
|
20346
|
-
message:
|
|
19310
|
+
message: `${targetIde.displayName} launched with CDP on port ${port}`
|
|
20347
19311
|
};
|
|
20348
19312
|
} catch (e) {
|
|
20349
19313
|
return {
|
|
@@ -22271,9 +21235,6 @@ var DEFAULT_DAEMON_PORT = 19222;
|
|
|
22271
21235
|
var DAEMON_WS_PATH = "/ipc";
|
|
22272
21236
|
|
|
22273
21237
|
// src/chat/subscription-updates.ts
|
|
22274
|
-
function normalizeSyncMode(syncMode) {
|
|
22275
|
-
return syncMode === "append" || syncMode === "replace_tail" || syncMode === "noop" || syncMode === "full" ? syncMode : "full";
|
|
22276
|
-
}
|
|
22277
21238
|
function normalizeModalButtons(value) {
|
|
22278
21239
|
return Array.isArray(value) ? value.filter((button) => typeof button === "string") : [];
|
|
22279
21240
|
}
|
|
@@ -22300,55 +21261,39 @@ function normalizeSessionModalFields(activeModal) {
|
|
|
22300
21261
|
modalButtons: normalizeModalButtons(activeModal.buttons)
|
|
22301
21262
|
};
|
|
22302
21263
|
}
|
|
22303
|
-
function buildNextChatCursor(cursor, result) {
|
|
22304
|
-
return {
|
|
22305
|
-
knownMessageCount: Math.max(0, Number(result.totalMessages || cursor.knownMessageCount)),
|
|
22306
|
-
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : cursor.lastMessageSignature,
|
|
22307
|
-
tailLimit: cursor.tailLimit
|
|
22308
|
-
};
|
|
22309
|
-
}
|
|
22310
21264
|
function prepareSessionChatTailUpdate(input) {
|
|
22311
21265
|
const result = input.result;
|
|
22312
|
-
if (!result?.success
|
|
21266
|
+
if (!result?.success) {
|
|
22313
21267
|
return {
|
|
22314
|
-
cursor:
|
|
21268
|
+
cursor: input.cursor,
|
|
22315
21269
|
seq: input.seq,
|
|
22316
21270
|
lastDeliveredSignature: input.lastDeliveredSignature,
|
|
22317
21271
|
update: null
|
|
22318
21272
|
};
|
|
22319
21273
|
}
|
|
22320
|
-
const
|
|
22321
|
-
const cursor = {
|
|
22322
|
-
knownMessageCount: Math.max(0, Number(result.totalMessages || 0)),
|
|
22323
|
-
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : "",
|
|
22324
|
-
tailLimit: input.cursor.tailLimit
|
|
22325
|
-
};
|
|
21274
|
+
const messages = Array.isArray(result.messages) ? result.messages : [];
|
|
22326
21275
|
const title = typeof result.title === "string" ? result.title : void 0;
|
|
22327
21276
|
const activeModal = normalizeChatTailActiveModal(result.activeModal);
|
|
22328
21277
|
const status = typeof result.status === "string" ? result.status : "idle";
|
|
22329
21278
|
const deliverySignature = buildChatTailDeliverySignature({
|
|
22330
21279
|
sessionId: input.sessionId,
|
|
22331
21280
|
...input.historySessionId ? { historySessionId: input.historySessionId } : {},
|
|
22332
|
-
messages
|
|
21281
|
+
messages,
|
|
22333
21282
|
status,
|
|
22334
21283
|
...title ? { title } : {},
|
|
22335
|
-
...activeModal ? { activeModal } : {}
|
|
22336
|
-
syncMode,
|
|
22337
|
-
replaceFrom: Number(result.replaceFrom || 0),
|
|
22338
|
-
totalMessages: Number(result.totalMessages || 0),
|
|
22339
|
-
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
|
|
21284
|
+
...activeModal ? { activeModal } : {}
|
|
22340
21285
|
});
|
|
22341
21286
|
const seq = input.seq + 1;
|
|
22342
21287
|
if (deliverySignature === input.lastDeliveredSignature) {
|
|
22343
21288
|
return {
|
|
22344
|
-
cursor,
|
|
21289
|
+
cursor: input.cursor,
|
|
22345
21290
|
seq,
|
|
22346
21291
|
lastDeliveredSignature: input.lastDeliveredSignature,
|
|
22347
21292
|
update: null
|
|
22348
21293
|
};
|
|
22349
21294
|
}
|
|
22350
21295
|
return {
|
|
22351
|
-
cursor,
|
|
21296
|
+
cursor: input.cursor,
|
|
22352
21297
|
seq,
|
|
22353
21298
|
lastDeliveredSignature: deliverySignature,
|
|
22354
21299
|
update: {
|
|
@@ -22359,14 +21304,10 @@ function prepareSessionChatTailUpdate(input) {
|
|
|
22359
21304
|
...input.interactionId ? { interactionId: input.interactionId } : {},
|
|
22360
21305
|
seq,
|
|
22361
21306
|
timestamp: input.timestamp,
|
|
22362
|
-
messages
|
|
21307
|
+
messages,
|
|
22363
21308
|
status,
|
|
22364
21309
|
...title ? { title } : {},
|
|
22365
|
-
...activeModal ? { activeModal } : {}
|
|
22366
|
-
syncMode,
|
|
22367
|
-
replaceFrom: Number(result.replaceFrom || 0),
|
|
22368
|
-
totalMessages: Number(result.totalMessages || 0),
|
|
22369
|
-
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
|
|
21310
|
+
...activeModal ? { activeModal } : {}
|
|
22370
21311
|
}
|
|
22371
21312
|
};
|
|
22372
21313
|
}
|
|
@@ -22426,8 +21367,6 @@ async function runAsyncBatch(items, worker, options = {}) {
|
|
|
22426
21367
|
}
|
|
22427
21368
|
|
|
22428
21369
|
// src/agent-stream/provider-adapter.ts
|
|
22429
|
-
init_read_chat_contract();
|
|
22430
|
-
init_chat_message_normalization();
|
|
22431
21370
|
var ProviderStreamAdapter = class {
|
|
22432
21371
|
agentType;
|
|
22433
21372
|
agentName;
|
|
@@ -23112,7 +22051,6 @@ var DaemonAgentStreamManager = class {
|
|
|
23112
22051
|
|
|
23113
22052
|
// src/agent-stream/poller.ts
|
|
23114
22053
|
init_logger();
|
|
23115
|
-
init_chat_message_normalization();
|
|
23116
22054
|
var AgentStreamPoller = class {
|
|
23117
22055
|
deps;
|
|
23118
22056
|
timer = null;
|
|
@@ -23591,10 +22529,6 @@ var ProviderInstanceManager = class {
|
|
|
23591
22529
|
}
|
|
23592
22530
|
};
|
|
23593
22531
|
|
|
23594
|
-
// src/index.ts
|
|
23595
|
-
init_io_contracts();
|
|
23596
|
-
init_chat_message_normalization();
|
|
23597
|
-
|
|
23598
22532
|
// src/providers/version-archive.ts
|
|
23599
22533
|
var fs11 = __toESM(require("fs"));
|
|
23600
22534
|
var path21 = __toESM(require("path"));
|
|
@@ -27032,7 +25966,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
27032
25966
|
lines.push("Provider category: `cli`");
|
|
27033
25967
|
lines.push("");
|
|
27034
25968
|
const funcToFile = {
|
|
27035
|
-
|
|
25969
|
+
parseSession: "parse_session.js",
|
|
27036
25970
|
detectStatus: "detect_status.js",
|
|
27037
25971
|
parseApproval: "parse_approval.js"
|
|
27038
25972
|
};
|
|
@@ -27121,7 +26055,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
27121
26055
|
lines.push("");
|
|
27122
26056
|
lines.push("| Function | Input | Return |");
|
|
27123
26057
|
lines.push("|---|---|---|");
|
|
27124
|
-
lines.push("| `
|
|
26058
|
+
lines.push("| `parseSession` | `{ buffer, rawBuffer, recentBuffer, screenText, messages, partialResponse }` | `{ id, status, title, messages, activeModal }` |");
|
|
27125
26059
|
lines.push("| `detectStatus` | `{ tail, screenText, rawBuffer }` | `idle`, `generating`, `waiting_approval`, or `error` |");
|
|
27126
26060
|
lines.push("| `parseApproval` | `{ buffer, rawBuffer, tail }` | `{ message, buttons }` or `null` |");
|
|
27127
26061
|
lines.push("");
|
|
@@ -27341,7 +26275,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
27341
26275
|
lines.push("");
|
|
27342
26276
|
lines.push("## Required Validation");
|
|
27343
26277
|
lines.push("1. Confirm `detectStatus` changes sensibly between startup, generating, approval, and idle.");
|
|
27344
|
-
lines.push("2. Confirm `
|
|
26278
|
+
lines.push("2. Confirm `parseSession` produces a stable transcript without duplicating past turns when the PTY redraws.");
|
|
27345
26279
|
lines.push("3. Confirm the latest assistant message streams through `partialResponse` while generation is in progress.");
|
|
27346
26280
|
lines.push("4. Confirm approval parsing returns meaningful button labels when the CLI requests permission.");
|
|
27347
26281
|
lines.push("5. Confirm the Python file was actually created and executed, not just described in chat text.");
|
|
@@ -28611,7 +27545,7 @@ var DevServer = class _DevServer {
|
|
|
28611
27545
|
lines.push("Provider category: `cli`");
|
|
28612
27546
|
lines.push("");
|
|
28613
27547
|
const funcToFile = {
|
|
28614
|
-
|
|
27548
|
+
parseSession: "parse_session.js",
|
|
28615
27549
|
detectStatus: "detect_status.js",
|
|
28616
27550
|
parseApproval: "parse_approval.js"
|
|
28617
27551
|
};
|
|
@@ -28700,7 +27634,7 @@ var DevServer = class _DevServer {
|
|
|
28700
27634
|
lines.push("");
|
|
28701
27635
|
lines.push("| Function | Input | Return |");
|
|
28702
27636
|
lines.push("|---|---|---|");
|
|
28703
|
-
lines.push("| `
|
|
27637
|
+
lines.push("| `parseSession` | `{ buffer, rawBuffer, recentBuffer, screenText, messages, partialResponse }` | `{ id, status, title, messages, activeModal }` |");
|
|
28704
27638
|
lines.push("| `detectStatus` | `{ tail, screenText, rawBuffer }` | `idle`, `generating`, `waiting_approval`, or `error` |");
|
|
28705
27639
|
lines.push("| `parseApproval` | `{ buffer, rawBuffer, tail }` | `{ message, buttons }` or `null` |");
|
|
28706
27640
|
lines.push("");
|
|
@@ -28795,7 +27729,7 @@ var DevServer = class _DevServer {
|
|
|
28795
27729
|
lines.push("");
|
|
28796
27730
|
lines.push("## Required Validation");
|
|
28797
27731
|
lines.push("1. Confirm `detectStatus` changes sensibly between startup, generating, approval, and idle.");
|
|
28798
|
-
lines.push("2. Confirm `
|
|
27732
|
+
lines.push("2. Confirm `parseSession` produces a stable transcript without duplicating past turns when the PTY redraws.");
|
|
28799
27733
|
lines.push("3. Confirm the latest assistant message streams through `partialResponse` while generation is in progress.");
|
|
28800
27734
|
lines.push("4. Confirm approval parsing returns meaningful button labels when the CLI requests permission.");
|
|
28801
27735
|
lines.push("5. Confirm the Python file was actually created and executed, not just described in chat text.");
|