@adhdev/daemon-core 0.9.63 → 0.9.65
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 -1687
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +646 -1687
- 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 -338
- 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,102 +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 buildBoundedTailSync(messages, cursor) {
|
|
11466
|
+
function buildFullTail(messages, tailLimit) {
|
|
12346
11467
|
const totalMessages = messages.length;
|
|
12347
|
-
const tailMessages =
|
|
11468
|
+
const tailMessages = tailLimit > 0 ? messages.slice(-tailLimit) : messages;
|
|
12348
11469
|
return {
|
|
12349
|
-
syncMode: "full",
|
|
12350
|
-
replaceFrom: 0,
|
|
12351
11470
|
messages: tailMessages,
|
|
12352
|
-
totalMessages
|
|
12353
|
-
lastMessageSignature: getChatMessageSignature(messages[totalMessages - 1])
|
|
12354
|
-
};
|
|
12355
|
-
}
|
|
12356
|
-
function computeReadChatSync(messages, cursor) {
|
|
12357
|
-
const totalMessages = messages.length;
|
|
12358
|
-
const lastMessageSignature = getChatMessageSignature(messages[totalMessages - 1]);
|
|
12359
|
-
const { knownMessageCount, lastMessageSignature: knownSignature } = cursor;
|
|
12360
|
-
if (!knownMessageCount || !knownSignature) {
|
|
12361
|
-
return {
|
|
12362
|
-
syncMode: "full",
|
|
12363
|
-
replaceFrom: 0,
|
|
12364
|
-
messages,
|
|
12365
|
-
totalMessages,
|
|
12366
|
-
lastMessageSignature
|
|
12367
|
-
};
|
|
12368
|
-
}
|
|
12369
|
-
if (knownMessageCount > totalMessages) {
|
|
12370
|
-
return {
|
|
12371
|
-
syncMode: "full",
|
|
12372
|
-
replaceFrom: 0,
|
|
12373
|
-
messages,
|
|
12374
|
-
totalMessages,
|
|
12375
|
-
lastMessageSignature
|
|
12376
|
-
};
|
|
12377
|
-
}
|
|
12378
|
-
if (knownMessageCount === totalMessages && knownSignature === lastMessageSignature) {
|
|
12379
|
-
return {
|
|
12380
|
-
syncMode: "noop",
|
|
12381
|
-
replaceFrom: totalMessages,
|
|
12382
|
-
messages: [],
|
|
12383
|
-
totalMessages,
|
|
12384
|
-
lastMessageSignature
|
|
12385
|
-
};
|
|
12386
|
-
}
|
|
12387
|
-
if (cursor.tailLimit > 0 && knownSignature === lastMessageSignature) {
|
|
12388
|
-
const requestedTailCount = Math.min(totalMessages, cursor.tailLimit);
|
|
12389
|
-
if (knownMessageCount >= requestedTailCount) {
|
|
12390
|
-
return {
|
|
12391
|
-
syncMode: "noop",
|
|
12392
|
-
replaceFrom: totalMessages,
|
|
12393
|
-
messages: [],
|
|
12394
|
-
totalMessages,
|
|
12395
|
-
lastMessageSignature
|
|
12396
|
-
};
|
|
12397
|
-
}
|
|
12398
|
-
return buildBoundedTailSync(messages, cursor);
|
|
12399
|
-
}
|
|
12400
|
-
if (knownMessageCount < totalMessages) {
|
|
12401
|
-
const anchorSignature = getChatMessageSignature(messages[knownMessageCount - 1]);
|
|
12402
|
-
if (anchorSignature === knownSignature) {
|
|
12403
|
-
return {
|
|
12404
|
-
syncMode: "append",
|
|
12405
|
-
replaceFrom: knownMessageCount,
|
|
12406
|
-
messages: messages.slice(knownMessageCount),
|
|
12407
|
-
totalMessages,
|
|
12408
|
-
lastMessageSignature
|
|
12409
|
-
};
|
|
12410
|
-
}
|
|
12411
|
-
if (cursor.tailLimit > 0) {
|
|
12412
|
-
const signatureIndex = findLastMessageIndexBySignature(messages, knownSignature);
|
|
12413
|
-
if (signatureIndex >= 0) {
|
|
12414
|
-
return {
|
|
12415
|
-
syncMode: "append",
|
|
12416
|
-
replaceFrom: knownMessageCount,
|
|
12417
|
-
messages: messages.slice(signatureIndex + 1),
|
|
12418
|
-
totalMessages,
|
|
12419
|
-
lastMessageSignature
|
|
12420
|
-
};
|
|
12421
|
-
}
|
|
12422
|
-
return buildBoundedTailSync(messages, cursor);
|
|
12423
|
-
}
|
|
12424
|
-
}
|
|
12425
|
-
const replaceFrom = Math.max(0, Math.min(knownMessageCount - 1, totalMessages));
|
|
12426
|
-
return {
|
|
12427
|
-
syncMode: replaceFrom === 0 ? "full" : "replace_tail",
|
|
12428
|
-
replaceFrom,
|
|
12429
|
-
messages: replaceFrom === 0 ? messages : messages.slice(replaceFrom),
|
|
12430
|
-
totalMessages,
|
|
12431
|
-
lastMessageSignature
|
|
11471
|
+
totalMessages
|
|
12432
11472
|
};
|
|
12433
11473
|
}
|
|
12434
11474
|
function hasNonEmptyModalButtons(activeModal) {
|
|
@@ -12463,31 +11503,13 @@ function buildReadChatCommandResult(payload, args) {
|
|
|
12463
11503
|
} catch (error) {
|
|
12464
11504
|
return { success: false, error: error?.message || String(error) };
|
|
12465
11505
|
}
|
|
12466
|
-
const messages =
|
|
12467
|
-
const
|
|
12468
|
-
if (!cursor.knownMessageCount && !cursor.lastMessageSignature && cursor.tailLimit > 0 && messages.length > cursor.tailLimit) {
|
|
12469
|
-
const tailMessages = messages.slice(-cursor.tailLimit);
|
|
12470
|
-
const lastMessageSignature = getChatMessageSignature(tailMessages[tailMessages.length - 1]);
|
|
12471
|
-
return {
|
|
12472
|
-
success: true,
|
|
12473
|
-
...validatedPayload,
|
|
12474
|
-
messages: tailMessages,
|
|
12475
|
-
syncMode: "full",
|
|
12476
|
-
replaceFrom: 0,
|
|
12477
|
-
totalMessages: messages.length,
|
|
12478
|
-
lastMessageSignature,
|
|
12479
|
-
...debugReadChat ? { debugReadChat } : {}
|
|
12480
|
-
};
|
|
12481
|
-
}
|
|
12482
|
-
const sync = computeReadChatSync(messages, cursor);
|
|
11506
|
+
const messages = normalizeReadChatMessages(validatedPayload);
|
|
11507
|
+
const sync = buildFullTail(messages, normalizeReadChatTailLimit(args));
|
|
12483
11508
|
return {
|
|
12484
11509
|
success: true,
|
|
12485
11510
|
...validatedPayload,
|
|
12486
11511
|
messages: sync.messages,
|
|
12487
|
-
syncMode: sync.syncMode,
|
|
12488
|
-
replaceFrom: sync.replaceFrom,
|
|
12489
11512
|
totalMessages: sync.totalMessages,
|
|
12490
|
-
lastMessageSignature: sync.lastMessageSignature,
|
|
12491
11513
|
...debugReadChat ? { debugReadChat } : {}
|
|
12492
11514
|
};
|
|
12493
11515
|
}
|
|
@@ -12712,10 +11734,6 @@ async function handleGetChatDebugBundle(h, args) {
|
|
|
12712
11734
|
status: readResult.status,
|
|
12713
11735
|
title: readResult.title,
|
|
12714
11736
|
totalMessages: readResult.totalMessages,
|
|
12715
|
-
returnedMessages: Array.isArray(readResult.messages) ? readResult.messages.length : void 0,
|
|
12716
|
-
syncMode: readResult.syncMode,
|
|
12717
|
-
replaceFrom: readResult.replaceFrom,
|
|
12718
|
-
lastMessageSignature: readResult.lastMessageSignature,
|
|
12719
11737
|
providerSessionId: readResult.providerSessionId,
|
|
12720
11738
|
transcriptAuthority: readResult.transcriptAuthority,
|
|
12721
11739
|
coverage: readResult.coverage,
|
|
@@ -12825,22 +11843,13 @@ function toNonNegativeNumber(value) {
|
|
|
12825
11843
|
return Number.isFinite(numeric) ? Math.max(0, numeric) : 0;
|
|
12826
11844
|
}
|
|
12827
11845
|
function getCliVisibleTranscriptCount(adapter) {
|
|
12828
|
-
|
|
12829
|
-
|
|
12830
|
-
|
|
12831
|
-
|
|
12832
|
-
|
|
12833
|
-
|
|
12834
|
-
parsedRecord = parsed && typeof parsed === "object" ? parsed : null;
|
|
12835
|
-
} catch {
|
|
12836
|
-
parsedRecord = null;
|
|
12837
|
-
}
|
|
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;
|
|
12838
11852
|
}
|
|
12839
|
-
const parsedMessages = Array.isArray(parsedRecord?.messages) ? parsedRecord.messages : [];
|
|
12840
|
-
if (!parsedRecord) return adapterMessages.length;
|
|
12841
|
-
const parsedIsProviderAuthoritative = parsedRecord.transcriptAuthority === "provider" || parsedRecord.coverage === "full";
|
|
12842
|
-
const shouldPreferAdapterMessages = !parsedIsProviderAuthoritative && adapterMessages.length > 0 && adapterMessages.length > parsedMessages.length;
|
|
12843
|
-
return shouldPreferAdapterMessages ? adapterMessages.length : parsedMessages.length;
|
|
12844
11853
|
}
|
|
12845
11854
|
async function getStableExtensionBaseline(h) {
|
|
12846
11855
|
const first = await readExtensionChatState(h);
|
|
@@ -12902,52 +11911,46 @@ async function handleReadChat(h, args) {
|
|
|
12902
11911
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
12903
11912
|
if (adapter) {
|
|
12904
11913
|
_log(`${transport} adapter: ${adapter.cliType}`);
|
|
11914
|
+
if (typeof adapter.getScriptParsedStatus !== "function") {
|
|
11915
|
+
return { success: false, error: `${transport} adapter parseSession unavailable` };
|
|
11916
|
+
}
|
|
12905
11917
|
let parsedStatus = null;
|
|
12906
|
-
|
|
12907
|
-
|
|
12908
|
-
|
|
12909
|
-
|
|
12910
|
-
return { success: false, error: error?.message || String(error) };
|
|
12911
|
-
}
|
|
11918
|
+
try {
|
|
11919
|
+
parsedStatus = parseMaybeJson(adapter.getScriptParsedStatus());
|
|
11920
|
+
} catch (error) {
|
|
11921
|
+
return { success: false, error: error?.message || String(error) };
|
|
12912
11922
|
}
|
|
12913
11923
|
const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
|
|
12914
|
-
|
|
12915
|
-
|
|
12916
|
-
|
|
12917
|
-
const
|
|
12918
|
-
const
|
|
12919
|
-
|
|
12920
|
-
|
|
12921
|
-
|
|
12922
|
-
|
|
12923
|
-
|
|
12924
|
-
|
|
12925
|
-
|
|
12926
|
-
|
|
12927
|
-
|
|
12928
|
-
|
|
12929
|
-
|
|
12930
|
-
|
|
12931
|
-
|
|
12932
|
-
|
|
12933
|
-
|
|
12934
|
-
|
|
12935
|
-
|
|
12936
|
-
|
|
12937
|
-
|
|
12938
|
-
|
|
12939
|
-
|
|
12940
|
-
|
|
12941
|
-
|
|
12942
|
-
|
|
12943
|
-
|
|
12944
|
-
},
|
|
12945
|
-
...title ? { title } : {},
|
|
12946
|
-
...providerSessionId ? { providerSessionId } : {},
|
|
12947
|
-
...transcriptAuthority ? { transcriptAuthority } : {},
|
|
12948
|
-
...coverage ? { coverage } : {}
|
|
12949
|
-
}, args);
|
|
12950
|
-
}
|
|
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);
|
|
12951
11954
|
}
|
|
12952
11955
|
return { success: false, error: `${transport} adapter not found` };
|
|
12953
11956
|
}
|
|
@@ -15251,7 +14254,6 @@ var path15 = __toESM(require("path"));
|
|
|
15251
14254
|
var crypto3 = __toESM(require("crypto"));
|
|
15252
14255
|
var fs6 = __toESM(require("fs"));
|
|
15253
14256
|
var import_node_module = require("module");
|
|
15254
|
-
init_contracts();
|
|
15255
14257
|
init_provider_cli_adapter();
|
|
15256
14258
|
init_logger();
|
|
15257
14259
|
|
|
@@ -15273,7 +14275,6 @@ function normalizeProviderSessionId(provider, providerSessionId) {
|
|
|
15273
14275
|
}
|
|
15274
14276
|
|
|
15275
14277
|
// src/providers/cli-provider-instance.ts
|
|
15276
|
-
init_chat_message_normalization();
|
|
15277
14278
|
function normalizePersistableCliHistoryContent(content) {
|
|
15278
14279
|
return flattenContent(content).replace(/\s+/g, " ").trim();
|
|
15279
14280
|
}
|
|
@@ -15513,17 +14514,11 @@ var CliProviderInstance = class {
|
|
|
15513
14514
|
}
|
|
15514
14515
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
15515
14516
|
this.maybeAppendRuntimeRecoveryMessage(runtime);
|
|
15516
|
-
let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages :
|
|
14517
|
+
let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
|
|
15517
14518
|
const historyMessageCount = Number.isFinite(parsedStatus?.historyMessageCount) ? Math.max(0, Number(parsedStatus.historyMessageCount)) : null;
|
|
15518
14519
|
if (historyMessageCount !== null) {
|
|
15519
14520
|
parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
|
|
15520
14521
|
}
|
|
15521
|
-
const committedMessages = Array.isArray(adapterStatus.messages) ? adapterStatus.messages : [];
|
|
15522
|
-
const isActiveNonIdle = adapterStatus.status !== "idle";
|
|
15523
|
-
const shouldApplyCommittedFloor = parsedMessages.length < committedMessages.length && (adapterStatus.status === "waiting_approval" || isActiveNonIdle && historyMessageCount === null);
|
|
15524
|
-
if (shouldApplyCommittedFloor) {
|
|
15525
|
-
parsedMessages = normalizeChatMessages(committedMessages);
|
|
15526
|
-
}
|
|
15527
14522
|
const mergedMessages = this.mergeConversationMessages(parsedMessages);
|
|
15528
14523
|
const canonicalBackedHistory = this.syncCanonicalSavedHistoryIfNeeded();
|
|
15529
14524
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
@@ -15616,11 +14611,9 @@ var CliProviderInstance = class {
|
|
|
15616
14611
|
const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
15617
14612
|
const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
|
|
15618
14613
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
15619
|
-
const lastCommittedMessageActivityAt = typeof this.adapter.getLastCommittedMessageActivityAt === "function" ? this.adapter.getLastCommittedMessageActivityAt() : 0;
|
|
15620
14614
|
return {
|
|
15621
14615
|
id: this.instanceId,
|
|
15622
14616
|
status: visibleStatus,
|
|
15623
|
-
lastMessageAt: lastCommittedMessageActivityAt || void 0,
|
|
15624
14617
|
runtimeLifecycle: runtime?.lifecycle ?? null,
|
|
15625
14618
|
runtimeSurfaceKind: runtime?.surfaceKind,
|
|
15626
14619
|
runtimeRestoredFromStorage: runtime?.restoredFromStorage === true,
|
|
@@ -15726,7 +14719,7 @@ var CliProviderInstance = class {
|
|
|
15726
14719
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
15727
14720
|
const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
|
|
15728
14721
|
const partial = this.adapter.getPartialResponse();
|
|
15729
|
-
const progressFingerprint = newStatus === "generating" ? `${partial || ""}
|
|
14722
|
+
const progressFingerprint = newStatus === "generating" ? `${partial || ""}`.slice(-2e3) : void 0;
|
|
15730
14723
|
const previousStatus = this.lastStatus;
|
|
15731
14724
|
if (newStatus !== this.lastStatus) {
|
|
15732
14725
|
LOG.info("CLI", `[${this.type}] status: ${this.lastStatus} \u2192 ${newStatus}`);
|
|
@@ -16172,18 +15165,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
16172
15165
|
receivedAt: message.receivedAt
|
|
16173
15166
|
}));
|
|
16174
15167
|
this.suppressIdleHistoryReplay = restoredHistory.messages.length > 0;
|
|
16175
|
-
if (restoredHistory.messages.length > 0) {
|
|
16176
|
-
this.adapter.seedCommittedMessages(
|
|
16177
|
-
restoredHistory.messages.map((message) => ({
|
|
16178
|
-
role: message.role,
|
|
16179
|
-
content: message.content,
|
|
16180
|
-
timestamp: message.receivedAt,
|
|
16181
|
-
receivedAt: message.receivedAt,
|
|
16182
|
-
kind: message.kind,
|
|
16183
|
-
senderName: message.senderName
|
|
16184
|
-
}))
|
|
16185
|
-
);
|
|
16186
|
-
}
|
|
16187
15168
|
}
|
|
16188
15169
|
getProbeDirectories() {
|
|
16189
15170
|
const dirs = /* @__PURE__ */ new Set();
|
|
@@ -16233,8 +15214,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
16233
15214
|
var import_stream = require("stream");
|
|
16234
15215
|
var import_child_process5 = require("child_process");
|
|
16235
15216
|
var import_sdk = require("@agentclientprotocol/sdk");
|
|
16236
|
-
init_contracts();
|
|
16237
|
-
init_chat_message_normalization();
|
|
16238
15217
|
init_logger();
|
|
16239
15218
|
function getPromptCapabilityFlags(agentCapabilities) {
|
|
16240
15219
|
const prompt = agentCapabilities?.promptCapabilities || {};
|
|
@@ -17378,7 +16357,6 @@ ${rawInput}` : rawInput;
|
|
|
17378
16357
|
};
|
|
17379
16358
|
|
|
17380
16359
|
// src/commands/cli-manager.ts
|
|
17381
|
-
init_contracts();
|
|
17382
16360
|
init_logger();
|
|
17383
16361
|
|
|
17384
16362
|
// src/commands/hosted-runtime-restore.ts
|
|
@@ -20312,13 +19290,24 @@ async function launchWithCdp(options = {}) {
|
|
|
20312
19290
|
break;
|
|
20313
19291
|
}
|
|
20314
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
|
+
}
|
|
20315
19304
|
return {
|
|
20316
19305
|
success: true,
|
|
20317
19306
|
ideId: targetIde.id,
|
|
20318
19307
|
ideName: targetIde.displayName,
|
|
20319
19308
|
port,
|
|
20320
19309
|
action: alreadyRunning ? "restarted" : "started",
|
|
20321
|
-
message:
|
|
19310
|
+
message: `${targetIde.displayName} launched with CDP on port ${port}`
|
|
20322
19311
|
};
|
|
20323
19312
|
} catch (e) {
|
|
20324
19313
|
return {
|
|
@@ -22246,9 +21235,6 @@ var DEFAULT_DAEMON_PORT = 19222;
|
|
|
22246
21235
|
var DAEMON_WS_PATH = "/ipc";
|
|
22247
21236
|
|
|
22248
21237
|
// src/chat/subscription-updates.ts
|
|
22249
|
-
function normalizeSyncMode(syncMode) {
|
|
22250
|
-
return syncMode === "append" || syncMode === "replace_tail" || syncMode === "noop" || syncMode === "full" ? syncMode : "full";
|
|
22251
|
-
}
|
|
22252
21238
|
function normalizeModalButtons(value) {
|
|
22253
21239
|
return Array.isArray(value) ? value.filter((button) => typeof button === "string") : [];
|
|
22254
21240
|
}
|
|
@@ -22275,55 +21261,39 @@ function normalizeSessionModalFields(activeModal) {
|
|
|
22275
21261
|
modalButtons: normalizeModalButtons(activeModal.buttons)
|
|
22276
21262
|
};
|
|
22277
21263
|
}
|
|
22278
|
-
function buildNextChatCursor(cursor, result) {
|
|
22279
|
-
return {
|
|
22280
|
-
knownMessageCount: Math.max(0, Number(result.totalMessages || cursor.knownMessageCount)),
|
|
22281
|
-
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : cursor.lastMessageSignature,
|
|
22282
|
-
tailLimit: cursor.tailLimit
|
|
22283
|
-
};
|
|
22284
|
-
}
|
|
22285
21264
|
function prepareSessionChatTailUpdate(input) {
|
|
22286
21265
|
const result = input.result;
|
|
22287
|
-
if (!result?.success
|
|
21266
|
+
if (!result?.success) {
|
|
22288
21267
|
return {
|
|
22289
|
-
cursor:
|
|
21268
|
+
cursor: input.cursor,
|
|
22290
21269
|
seq: input.seq,
|
|
22291
21270
|
lastDeliveredSignature: input.lastDeliveredSignature,
|
|
22292
21271
|
update: null
|
|
22293
21272
|
};
|
|
22294
21273
|
}
|
|
22295
|
-
const
|
|
22296
|
-
const cursor = {
|
|
22297
|
-
knownMessageCount: Math.max(0, Number(result.totalMessages || 0)),
|
|
22298
|
-
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : "",
|
|
22299
|
-
tailLimit: input.cursor.tailLimit
|
|
22300
|
-
};
|
|
21274
|
+
const messages = Array.isArray(result.messages) ? result.messages : [];
|
|
22301
21275
|
const title = typeof result.title === "string" ? result.title : void 0;
|
|
22302
21276
|
const activeModal = normalizeChatTailActiveModal(result.activeModal);
|
|
22303
21277
|
const status = typeof result.status === "string" ? result.status : "idle";
|
|
22304
21278
|
const deliverySignature = buildChatTailDeliverySignature({
|
|
22305
21279
|
sessionId: input.sessionId,
|
|
22306
21280
|
...input.historySessionId ? { historySessionId: input.historySessionId } : {},
|
|
22307
|
-
messages
|
|
21281
|
+
messages,
|
|
22308
21282
|
status,
|
|
22309
21283
|
...title ? { title } : {},
|
|
22310
|
-
...activeModal ? { activeModal } : {}
|
|
22311
|
-
syncMode,
|
|
22312
|
-
replaceFrom: Number(result.replaceFrom || 0),
|
|
22313
|
-
totalMessages: Number(result.totalMessages || 0),
|
|
22314
|
-
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
|
|
21284
|
+
...activeModal ? { activeModal } : {}
|
|
22315
21285
|
});
|
|
22316
21286
|
const seq = input.seq + 1;
|
|
22317
21287
|
if (deliverySignature === input.lastDeliveredSignature) {
|
|
22318
21288
|
return {
|
|
22319
|
-
cursor,
|
|
21289
|
+
cursor: input.cursor,
|
|
22320
21290
|
seq,
|
|
22321
21291
|
lastDeliveredSignature: input.lastDeliveredSignature,
|
|
22322
21292
|
update: null
|
|
22323
21293
|
};
|
|
22324
21294
|
}
|
|
22325
21295
|
return {
|
|
22326
|
-
cursor,
|
|
21296
|
+
cursor: input.cursor,
|
|
22327
21297
|
seq,
|
|
22328
21298
|
lastDeliveredSignature: deliverySignature,
|
|
22329
21299
|
update: {
|
|
@@ -22334,14 +21304,10 @@ function prepareSessionChatTailUpdate(input) {
|
|
|
22334
21304
|
...input.interactionId ? { interactionId: input.interactionId } : {},
|
|
22335
21305
|
seq,
|
|
22336
21306
|
timestamp: input.timestamp,
|
|
22337
|
-
messages
|
|
21307
|
+
messages,
|
|
22338
21308
|
status,
|
|
22339
21309
|
...title ? { title } : {},
|
|
22340
|
-
...activeModal ? { activeModal } : {}
|
|
22341
|
-
syncMode,
|
|
22342
|
-
replaceFrom: Number(result.replaceFrom || 0),
|
|
22343
|
-
totalMessages: Number(result.totalMessages || 0),
|
|
22344
|
-
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
|
|
21310
|
+
...activeModal ? { activeModal } : {}
|
|
22345
21311
|
}
|
|
22346
21312
|
};
|
|
22347
21313
|
}
|
|
@@ -22401,8 +21367,6 @@ async function runAsyncBatch(items, worker, options = {}) {
|
|
|
22401
21367
|
}
|
|
22402
21368
|
|
|
22403
21369
|
// src/agent-stream/provider-adapter.ts
|
|
22404
|
-
init_read_chat_contract();
|
|
22405
|
-
init_chat_message_normalization();
|
|
22406
21370
|
var ProviderStreamAdapter = class {
|
|
22407
21371
|
agentType;
|
|
22408
21372
|
agentName;
|
|
@@ -23087,7 +22051,6 @@ var DaemonAgentStreamManager = class {
|
|
|
23087
22051
|
|
|
23088
22052
|
// src/agent-stream/poller.ts
|
|
23089
22053
|
init_logger();
|
|
23090
|
-
init_chat_message_normalization();
|
|
23091
22054
|
var AgentStreamPoller = class {
|
|
23092
22055
|
deps;
|
|
23093
22056
|
timer = null;
|
|
@@ -23566,10 +22529,6 @@ var ProviderInstanceManager = class {
|
|
|
23566
22529
|
}
|
|
23567
22530
|
};
|
|
23568
22531
|
|
|
23569
|
-
// src/index.ts
|
|
23570
|
-
init_io_contracts();
|
|
23571
|
-
init_chat_message_normalization();
|
|
23572
|
-
|
|
23573
22532
|
// src/providers/version-archive.ts
|
|
23574
22533
|
var fs11 = __toESM(require("fs"));
|
|
23575
22534
|
var path21 = __toESM(require("path"));
|
|
@@ -27007,7 +25966,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
27007
25966
|
lines.push("Provider category: `cli`");
|
|
27008
25967
|
lines.push("");
|
|
27009
25968
|
const funcToFile = {
|
|
27010
|
-
|
|
25969
|
+
parseSession: "parse_session.js",
|
|
27011
25970
|
detectStatus: "detect_status.js",
|
|
27012
25971
|
parseApproval: "parse_approval.js"
|
|
27013
25972
|
};
|
|
@@ -27096,7 +26055,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
27096
26055
|
lines.push("");
|
|
27097
26056
|
lines.push("| Function | Input | Return |");
|
|
27098
26057
|
lines.push("|---|---|---|");
|
|
27099
|
-
lines.push("| `
|
|
26058
|
+
lines.push("| `parseSession` | `{ buffer, rawBuffer, recentBuffer, screenText, messages, partialResponse }` | `{ id, status, title, messages, activeModal }` |");
|
|
27100
26059
|
lines.push("| `detectStatus` | `{ tail, screenText, rawBuffer }` | `idle`, `generating`, `waiting_approval`, or `error` |");
|
|
27101
26060
|
lines.push("| `parseApproval` | `{ buffer, rawBuffer, tail }` | `{ message, buttons }` or `null` |");
|
|
27102
26061
|
lines.push("");
|
|
@@ -27316,7 +26275,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
27316
26275
|
lines.push("");
|
|
27317
26276
|
lines.push("## Required Validation");
|
|
27318
26277
|
lines.push("1. Confirm `detectStatus` changes sensibly between startup, generating, approval, and idle.");
|
|
27319
|
-
lines.push("2. Confirm `
|
|
26278
|
+
lines.push("2. Confirm `parseSession` produces a stable transcript without duplicating past turns when the PTY redraws.");
|
|
27320
26279
|
lines.push("3. Confirm the latest assistant message streams through `partialResponse` while generation is in progress.");
|
|
27321
26280
|
lines.push("4. Confirm approval parsing returns meaningful button labels when the CLI requests permission.");
|
|
27322
26281
|
lines.push("5. Confirm the Python file was actually created and executed, not just described in chat text.");
|
|
@@ -28586,7 +27545,7 @@ var DevServer = class _DevServer {
|
|
|
28586
27545
|
lines.push("Provider category: `cli`");
|
|
28587
27546
|
lines.push("");
|
|
28588
27547
|
const funcToFile = {
|
|
28589
|
-
|
|
27548
|
+
parseSession: "parse_session.js",
|
|
28590
27549
|
detectStatus: "detect_status.js",
|
|
28591
27550
|
parseApproval: "parse_approval.js"
|
|
28592
27551
|
};
|
|
@@ -28675,7 +27634,7 @@ var DevServer = class _DevServer {
|
|
|
28675
27634
|
lines.push("");
|
|
28676
27635
|
lines.push("| Function | Input | Return |");
|
|
28677
27636
|
lines.push("|---|---|---|");
|
|
28678
|
-
lines.push("| `
|
|
27637
|
+
lines.push("| `parseSession` | `{ buffer, rawBuffer, recentBuffer, screenText, messages, partialResponse }` | `{ id, status, title, messages, activeModal }` |");
|
|
28679
27638
|
lines.push("| `detectStatus` | `{ tail, screenText, rawBuffer }` | `idle`, `generating`, `waiting_approval`, or `error` |");
|
|
28680
27639
|
lines.push("| `parseApproval` | `{ buffer, rawBuffer, tail }` | `{ message, buttons }` or `null` |");
|
|
28681
27640
|
lines.push("");
|
|
@@ -28770,7 +27729,7 @@ var DevServer = class _DevServer {
|
|
|
28770
27729
|
lines.push("");
|
|
28771
27730
|
lines.push("## Required Validation");
|
|
28772
27731
|
lines.push("1. Confirm `detectStatus` changes sensibly between startup, generating, approval, and idle.");
|
|
28773
|
-
lines.push("2. Confirm `
|
|
27732
|
+
lines.push("2. Confirm `parseSession` produces a stable transcript without duplicating past turns when the PTY redraws.");
|
|
28774
27733
|
lines.push("3. Confirm the latest assistant message streams through `partialResponse` while generation is in progress.");
|
|
28775
27734
|
lines.push("4. Confirm approval parsing returns meaningful button labels when the CLI requests permission.");
|
|
28776
27735
|
lines.push("5. Confirm the Python file was actually created and executed, not just described in chat text.");
|