@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.mjs
CHANGED
|
@@ -477,525 +477,6 @@ var init_logger = __esm({
|
|
|
477
477
|
}
|
|
478
478
|
});
|
|
479
479
|
|
|
480
|
-
// src/providers/io-contracts.ts
|
|
481
|
-
function normalizeInputEnvelope(input) {
|
|
482
|
-
const normalized = normalizeInputEnvelopePayload(input);
|
|
483
|
-
const textFallback = normalized.textFallback ?? flattenInputParts(normalized.parts);
|
|
484
|
-
return {
|
|
485
|
-
parts: normalized.parts,
|
|
486
|
-
textFallback,
|
|
487
|
-
...normalized.metadata ? { metadata: normalized.metadata } : {}
|
|
488
|
-
};
|
|
489
|
-
}
|
|
490
|
-
function normalizeMessageParts(content) {
|
|
491
|
-
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
492
|
-
if (!Array.isArray(content)) {
|
|
493
|
-
if (content && typeof content === "object" && typeof content.text === "string") {
|
|
494
|
-
return [{ type: "text", text: String(content.text) }];
|
|
495
|
-
}
|
|
496
|
-
return [];
|
|
497
|
-
}
|
|
498
|
-
const parts = [];
|
|
499
|
-
for (const raw of content) {
|
|
500
|
-
if (typeof raw === "string") {
|
|
501
|
-
parts.push({ type: "text", text: raw });
|
|
502
|
-
continue;
|
|
503
|
-
}
|
|
504
|
-
if (!raw || typeof raw !== "object") continue;
|
|
505
|
-
const part = normalizeMessagePartObject(raw);
|
|
506
|
-
if (part) parts.push(part);
|
|
507
|
-
}
|
|
508
|
-
return parts;
|
|
509
|
-
}
|
|
510
|
-
function flattenMessageParts(parts) {
|
|
511
|
-
return parts.map((part) => {
|
|
512
|
-
if (part.type === "text") return part.text;
|
|
513
|
-
if (part.type === "resource") return part.resource.text || "";
|
|
514
|
-
return "";
|
|
515
|
-
}).filter((value) => value.length > 0).join("\n");
|
|
516
|
-
}
|
|
517
|
-
function normalizeInputEnvelopePayload(input) {
|
|
518
|
-
if (typeof input === "string") {
|
|
519
|
-
return { parts: [{ type: "text", text: input }], textFallback: input };
|
|
520
|
-
}
|
|
521
|
-
if (!input || typeof input !== "object") {
|
|
522
|
-
return { parts: [], textFallback: "" };
|
|
523
|
-
}
|
|
524
|
-
const record = input;
|
|
525
|
-
const nestedInput = record.input;
|
|
526
|
-
if (nestedInput && typeof nestedInput === "object") {
|
|
527
|
-
const nested = nestedInput;
|
|
528
|
-
return {
|
|
529
|
-
parts: normalizeInputParts(nested.parts ?? nested.prompt),
|
|
530
|
-
textFallback: typeof nested.textFallback === "string" ? nested.textFallback : void 0,
|
|
531
|
-
metadata: normalizeInputMetadata(nested.metadata)
|
|
532
|
-
};
|
|
533
|
-
}
|
|
534
|
-
const directText = typeof record.text === "string" ? record.text : typeof record.message === "string" ? record.message : void 0;
|
|
535
|
-
if (directText !== void 0) {
|
|
536
|
-
return { parts: [{ type: "text", text: directText }], textFallback: directText };
|
|
537
|
-
}
|
|
538
|
-
const directParts = normalizeInputParts(record.parts ?? record.prompt);
|
|
539
|
-
return {
|
|
540
|
-
parts: directParts,
|
|
541
|
-
textFallback: typeof record.textFallback === "string" ? record.textFallback : void 0,
|
|
542
|
-
metadata: normalizeInputMetadata(record.metadata)
|
|
543
|
-
};
|
|
544
|
-
}
|
|
545
|
-
function normalizeInputMetadata(value) {
|
|
546
|
-
if (!value || typeof value !== "object") return void 0;
|
|
547
|
-
const record = value;
|
|
548
|
-
const metadata = {};
|
|
549
|
-
if (record.source === "dashboard" || record.source === "shortcut_api" || record.source === "provider_script" || record.source === "session_replay") {
|
|
550
|
-
metadata.source = record.source;
|
|
551
|
-
}
|
|
552
|
-
if (typeof record.clientTimestamp === "number" && Number.isFinite(record.clientTimestamp)) {
|
|
553
|
-
metadata.clientTimestamp = record.clientTimestamp;
|
|
554
|
-
}
|
|
555
|
-
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
556
|
-
}
|
|
557
|
-
function normalizeInputParts(value) {
|
|
558
|
-
if (!Array.isArray(value)) return [];
|
|
559
|
-
const parts = [];
|
|
560
|
-
for (const raw of value) {
|
|
561
|
-
if (typeof raw === "string") {
|
|
562
|
-
parts.push({ type: "text", text: raw });
|
|
563
|
-
continue;
|
|
564
|
-
}
|
|
565
|
-
if (!raw || typeof raw !== "object") continue;
|
|
566
|
-
const part = normalizeInputPartObject(raw);
|
|
567
|
-
if (part) parts.push(part);
|
|
568
|
-
}
|
|
569
|
-
return parts;
|
|
570
|
-
}
|
|
571
|
-
function normalizeInputPartObject(raw) {
|
|
572
|
-
const type = raw.type;
|
|
573
|
-
if (type === "text" && typeof raw.text === "string") {
|
|
574
|
-
return { type, text: raw.text };
|
|
575
|
-
}
|
|
576
|
-
if (type === "image" && typeof raw.mimeType === "string") {
|
|
577
|
-
return {
|
|
578
|
-
type,
|
|
579
|
-
mimeType: raw.mimeType,
|
|
580
|
-
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
581
|
-
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
582
|
-
...typeof raw.alt === "string" ? { alt: raw.alt } : {}
|
|
583
|
-
};
|
|
584
|
-
}
|
|
585
|
-
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
586
|
-
return {
|
|
587
|
-
type,
|
|
588
|
-
mimeType: raw.mimeType,
|
|
589
|
-
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
590
|
-
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
591
|
-
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
|
|
592
|
-
};
|
|
593
|
-
}
|
|
594
|
-
if (type === "video" && typeof raw.mimeType === "string") {
|
|
595
|
-
return {
|
|
596
|
-
type,
|
|
597
|
-
mimeType: raw.mimeType,
|
|
598
|
-
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
599
|
-
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
600
|
-
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
601
|
-
};
|
|
602
|
-
}
|
|
603
|
-
if (type === "resource" && typeof raw.uri === "string") {
|
|
604
|
-
return {
|
|
605
|
-
type,
|
|
606
|
-
uri: raw.uri,
|
|
607
|
-
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
608
|
-
...typeof raw.name === "string" ? { name: raw.name } : {},
|
|
609
|
-
...typeof raw.text === "string" ? { text: raw.text } : {},
|
|
610
|
-
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
611
|
-
};
|
|
612
|
-
}
|
|
613
|
-
if (type === "resource_link" && typeof raw.uri === "string") {
|
|
614
|
-
return {
|
|
615
|
-
type: "resource",
|
|
616
|
-
uri: raw.uri,
|
|
617
|
-
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
618
|
-
...typeof raw.name === "string" ? { name: raw.name } : {}
|
|
619
|
-
};
|
|
620
|
-
}
|
|
621
|
-
return null;
|
|
622
|
-
}
|
|
623
|
-
function normalizeMessagePartObject(raw) {
|
|
624
|
-
const type = raw.type;
|
|
625
|
-
if (type === "text" && typeof raw.text === "string") {
|
|
626
|
-
return { type, text: raw.text };
|
|
627
|
-
}
|
|
628
|
-
if (type === "image" && typeof raw.mimeType === "string") {
|
|
629
|
-
return {
|
|
630
|
-
type,
|
|
631
|
-
mimeType: raw.mimeType,
|
|
632
|
-
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
633
|
-
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
634
|
-
};
|
|
635
|
-
}
|
|
636
|
-
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
637
|
-
return {
|
|
638
|
-
type,
|
|
639
|
-
mimeType: raw.mimeType,
|
|
640
|
-
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
641
|
-
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
642
|
-
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
|
|
643
|
-
};
|
|
644
|
-
}
|
|
645
|
-
if (type === "video" && typeof raw.mimeType === "string") {
|
|
646
|
-
return {
|
|
647
|
-
type,
|
|
648
|
-
mimeType: raw.mimeType,
|
|
649
|
-
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
650
|
-
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
651
|
-
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
if (type === "resource_link" && typeof raw.uri === "string" && typeof raw.name === "string") {
|
|
655
|
-
return {
|
|
656
|
-
type,
|
|
657
|
-
uri: raw.uri,
|
|
658
|
-
name: raw.name,
|
|
659
|
-
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
660
|
-
...typeof raw.size === "number" ? { size: raw.size } : {}
|
|
661
|
-
};
|
|
662
|
-
}
|
|
663
|
-
if (type === "resource" && raw.resource && typeof raw.resource === "object") {
|
|
664
|
-
const resource = raw.resource;
|
|
665
|
-
if (typeof resource.uri !== "string") return null;
|
|
666
|
-
return {
|
|
667
|
-
type,
|
|
668
|
-
resource: {
|
|
669
|
-
uri: resource.uri,
|
|
670
|
-
...typeof resource.mimeType === "string" || resource.mimeType === null ? { mimeType: resource.mimeType } : {},
|
|
671
|
-
...typeof resource.text === "string" ? { text: resource.text } : {},
|
|
672
|
-
...typeof resource.blob === "string" ? { blob: resource.blob } : {}
|
|
673
|
-
}
|
|
674
|
-
};
|
|
675
|
-
}
|
|
676
|
-
return null;
|
|
677
|
-
}
|
|
678
|
-
function flattenInputParts(parts) {
|
|
679
|
-
return parts.map((part) => {
|
|
680
|
-
if (part.type === "text") return part.text;
|
|
681
|
-
if (part.type === "audio") return part.transcript || "";
|
|
682
|
-
if (part.type === "resource") return part.text || "";
|
|
683
|
-
return "";
|
|
684
|
-
}).filter((value) => value.length > 0).join("\n");
|
|
685
|
-
}
|
|
686
|
-
var init_io_contracts = __esm({
|
|
687
|
-
"src/providers/io-contracts.ts"() {
|
|
688
|
-
"use strict";
|
|
689
|
-
}
|
|
690
|
-
});
|
|
691
|
-
|
|
692
|
-
// src/providers/contracts.ts
|
|
693
|
-
function flattenContent(content) {
|
|
694
|
-
if (typeof content === "string") return content;
|
|
695
|
-
return flattenMessageParts(normalizeMessageParts(content));
|
|
696
|
-
}
|
|
697
|
-
var init_contracts = __esm({
|
|
698
|
-
"src/providers/contracts.ts"() {
|
|
699
|
-
"use strict";
|
|
700
|
-
init_io_contracts();
|
|
701
|
-
init_io_contracts();
|
|
702
|
-
}
|
|
703
|
-
});
|
|
704
|
-
|
|
705
|
-
// src/providers/chat-message-normalization.ts
|
|
706
|
-
function canonicalizeKindHint(value) {
|
|
707
|
-
return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
708
|
-
}
|
|
709
|
-
function resolveBuiltinOrAliasKind(kind) {
|
|
710
|
-
if (typeof kind !== "string") return null;
|
|
711
|
-
const normalizedKind = canonicalizeKindHint(kind);
|
|
712
|
-
if (!normalizedKind) return null;
|
|
713
|
-
if (KNOWN_CHAT_MESSAGE_KINDS.has(normalizedKind)) return normalizedKind;
|
|
714
|
-
return CHAT_MESSAGE_KIND_ALIASES[normalizedKind] || null;
|
|
715
|
-
}
|
|
716
|
-
function inferHintKind(value) {
|
|
717
|
-
const direct = resolveBuiltinOrAliasKind(value);
|
|
718
|
-
if (direct) return direct;
|
|
719
|
-
if (typeof value !== "string") return null;
|
|
720
|
-
const normalized = canonicalizeKindHint(value);
|
|
721
|
-
if (!normalized) return null;
|
|
722
|
-
if (/thought|thinking|reasoning/.test(normalized)) return "thought";
|
|
723
|
-
if (/tool/.test(normalized)) return "tool";
|
|
724
|
-
if (/terminal|command|shell|console/.test(normalized)) return "terminal";
|
|
725
|
-
return null;
|
|
726
|
-
}
|
|
727
|
-
function inferKindFromToolCalls(message) {
|
|
728
|
-
const toolCalls = Array.isArray(message?.toolCalls) ? message.toolCalls : [];
|
|
729
|
-
if (toolCalls.length === 0) return null;
|
|
730
|
-
if (toolCalls.some((toolCall) => toolCall?.kind === "think")) return "thought";
|
|
731
|
-
if (toolCalls.some((toolCall) => toolCall?.kind === "execute")) return "terminal";
|
|
732
|
-
if (toolCalls.some((toolCall) => Array.isArray(toolCall?.content) && toolCall.content.some((entry) => entry?.type === "terminal"))) {
|
|
733
|
-
return "terminal";
|
|
734
|
-
}
|
|
735
|
-
return "tool";
|
|
736
|
-
}
|
|
737
|
-
function inferMissingChatMessageKind(message) {
|
|
738
|
-
const role = typeof message?.role === "string" ? message.role.trim().toLowerCase() : "";
|
|
739
|
-
if (role === "system") return "system";
|
|
740
|
-
const meta = message?.meta && typeof message.meta === "object" ? message.meta : void 0;
|
|
741
|
-
const hintCandidates = [
|
|
742
|
-
message?._sub,
|
|
743
|
-
message?._type,
|
|
744
|
-
meta?.label,
|
|
745
|
-
typeof message?.senderName === "string" ? message.senderName : void 0
|
|
746
|
-
];
|
|
747
|
-
for (const candidate of hintCandidates) {
|
|
748
|
-
const inferred = inferHintKind(candidate);
|
|
749
|
-
if (inferred) return inferred;
|
|
750
|
-
}
|
|
751
|
-
const inferredFromToolCalls = inferKindFromToolCalls(message);
|
|
752
|
-
if (inferredFromToolCalls) return inferredFromToolCalls;
|
|
753
|
-
return null;
|
|
754
|
-
}
|
|
755
|
-
function isBuiltinChatMessageKind(kind) {
|
|
756
|
-
return resolveBuiltinOrAliasKind(kind) !== null;
|
|
757
|
-
}
|
|
758
|
-
function normalizeChatMessageKind(kind, role) {
|
|
759
|
-
const resolvedKind = resolveBuiltinOrAliasKind(kind);
|
|
760
|
-
if (resolvedKind) return resolvedKind;
|
|
761
|
-
const normalizedRole = typeof role === "string" ? role.trim().toLowerCase() : "";
|
|
762
|
-
return normalizedRole === "system" ? "system" : "standard";
|
|
763
|
-
}
|
|
764
|
-
function resolveChatMessageKind(message) {
|
|
765
|
-
const explicitKind = resolveBuiltinOrAliasKind(message?.kind);
|
|
766
|
-
if (explicitKind) return explicitKind;
|
|
767
|
-
const inferredKind = inferMissingChatMessageKind(message);
|
|
768
|
-
if (inferredKind) return inferredKind;
|
|
769
|
-
return normalizeChatMessageKind(message?.kind, message?.role);
|
|
770
|
-
}
|
|
771
|
-
function buildChatMessage(message) {
|
|
772
|
-
return {
|
|
773
|
-
...message,
|
|
774
|
-
kind: resolveChatMessageKind(message)
|
|
775
|
-
};
|
|
776
|
-
}
|
|
777
|
-
function buildSystemChatMessage(message) {
|
|
778
|
-
return buildChatMessage({
|
|
779
|
-
...message,
|
|
780
|
-
role: "system",
|
|
781
|
-
kind: message?.kind || "system"
|
|
782
|
-
});
|
|
783
|
-
}
|
|
784
|
-
function buildRuntimeSystemChatMessage(message) {
|
|
785
|
-
return buildSystemChatMessage({
|
|
786
|
-
...message,
|
|
787
|
-
senderName: typeof message?.senderName === "string" && message.senderName.trim() ? message.senderName : "System"
|
|
788
|
-
});
|
|
789
|
-
}
|
|
790
|
-
function buildAssistantChatMessage(message) {
|
|
791
|
-
return buildChatMessage({
|
|
792
|
-
...message,
|
|
793
|
-
role: "assistant",
|
|
794
|
-
kind: message?.kind || "standard"
|
|
795
|
-
});
|
|
796
|
-
}
|
|
797
|
-
function buildThoughtChatMessage(message) {
|
|
798
|
-
return buildAssistantChatMessage({
|
|
799
|
-
...message,
|
|
800
|
-
kind: message?.kind || "thought"
|
|
801
|
-
});
|
|
802
|
-
}
|
|
803
|
-
function buildToolChatMessage(message) {
|
|
804
|
-
return buildAssistantChatMessage({
|
|
805
|
-
...message,
|
|
806
|
-
kind: message?.kind || "tool"
|
|
807
|
-
});
|
|
808
|
-
}
|
|
809
|
-
function buildTerminalChatMessage(message) {
|
|
810
|
-
return buildAssistantChatMessage({
|
|
811
|
-
...message,
|
|
812
|
-
kind: message?.kind || "terminal"
|
|
813
|
-
});
|
|
814
|
-
}
|
|
815
|
-
function buildUserChatMessage(message) {
|
|
816
|
-
return buildChatMessage({
|
|
817
|
-
...message,
|
|
818
|
-
role: "user",
|
|
819
|
-
kind: message?.kind || "standard"
|
|
820
|
-
});
|
|
821
|
-
}
|
|
822
|
-
function normalizeChatMessage(message) {
|
|
823
|
-
return buildChatMessage(message);
|
|
824
|
-
}
|
|
825
|
-
function normalizeChatMessages(messages) {
|
|
826
|
-
return (Array.isArray(messages) ? messages : []).map((message) => normalizeChatMessage(message));
|
|
827
|
-
}
|
|
828
|
-
var BUILTIN_CHAT_MESSAGE_KINDS, KNOWN_CHAT_MESSAGE_KINDS, CHAT_MESSAGE_KIND_ALIASES;
|
|
829
|
-
var init_chat_message_normalization = __esm({
|
|
830
|
-
"src/providers/chat-message-normalization.ts"() {
|
|
831
|
-
"use strict";
|
|
832
|
-
BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
|
|
833
|
-
KNOWN_CHAT_MESSAGE_KINDS = new Set(BUILTIN_CHAT_MESSAGE_KINDS);
|
|
834
|
-
CHAT_MESSAGE_KIND_ALIASES = {
|
|
835
|
-
text: "standard",
|
|
836
|
-
message: "standard",
|
|
837
|
-
assistant: "standard",
|
|
838
|
-
thinking: "thought",
|
|
839
|
-
think: "thought",
|
|
840
|
-
reasoning: "thought",
|
|
841
|
-
reason: "thought",
|
|
842
|
-
toolcall: "tool",
|
|
843
|
-
tool_call: "tool",
|
|
844
|
-
tooluse: "tool",
|
|
845
|
-
tool_use: "tool",
|
|
846
|
-
action: "tool",
|
|
847
|
-
command: "terminal",
|
|
848
|
-
cmd: "terminal",
|
|
849
|
-
shell: "terminal",
|
|
850
|
-
console: "terminal"
|
|
851
|
-
};
|
|
852
|
-
}
|
|
853
|
-
});
|
|
854
|
-
|
|
855
|
-
// src/providers/read-chat-contract.ts
|
|
856
|
-
function isPlainObject3(value) {
|
|
857
|
-
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
858
|
-
}
|
|
859
|
-
function isFiniteNumber(value) {
|
|
860
|
-
return typeof value === "number" && Number.isFinite(value);
|
|
861
|
-
}
|
|
862
|
-
function validateStatus(status, source) {
|
|
863
|
-
if (typeof status !== "string" || !VALID_STATUSES.includes(status)) {
|
|
864
|
-
throw new Error(`${source}: status must be one of ${VALID_STATUSES.join(", ")}`);
|
|
865
|
-
}
|
|
866
|
-
return status;
|
|
867
|
-
}
|
|
868
|
-
function validateRole(role, source, index) {
|
|
869
|
-
if (typeof role !== "string" || !VALID_ROLES.includes(role)) {
|
|
870
|
-
throw new Error(`${source}: messages[${index}].role must be one of ${VALID_ROLES.join(", ")}`);
|
|
871
|
-
}
|
|
872
|
-
return role;
|
|
873
|
-
}
|
|
874
|
-
function validateBubbleState(state, source, index) {
|
|
875
|
-
if (typeof state !== "string" || !VALID_BUBBLE_STATES.includes(state)) {
|
|
876
|
-
throw new Error(`${source}: messages[${index}].bubbleState must be one of ${VALID_BUBBLE_STATES.join(", ")}`);
|
|
877
|
-
}
|
|
878
|
-
return state;
|
|
879
|
-
}
|
|
880
|
-
function validateTurnStatus(turnStatus, source) {
|
|
881
|
-
if (typeof turnStatus !== "string" || !VALID_TURN_STATUSES.includes(turnStatus)) {
|
|
882
|
-
throw new Error(`${source}: turnStatus must be one of ${VALID_TURN_STATUSES.join(", ")}`);
|
|
883
|
-
}
|
|
884
|
-
return turnStatus;
|
|
885
|
-
}
|
|
886
|
-
function validateMessageContent(content, source, index) {
|
|
887
|
-
if (typeof content === "string") return content;
|
|
888
|
-
if (Array.isArray(content)) return normalizeMessageParts(content);
|
|
889
|
-
throw new Error(`${source}: messages[${index}].content must be a string or structured content array`);
|
|
890
|
-
}
|
|
891
|
-
function validateMessage(message, source, index) {
|
|
892
|
-
if (!isPlainObject3(message)) {
|
|
893
|
-
throw new Error(`${source}: messages[${index}] must be an object`);
|
|
894
|
-
}
|
|
895
|
-
const normalized = {
|
|
896
|
-
role: validateRole(message.role, source, index),
|
|
897
|
-
content: validateMessageContent(message.content, source, index)
|
|
898
|
-
};
|
|
899
|
-
if (typeof message.kind === "string") normalized.kind = message.kind;
|
|
900
|
-
if (typeof message.id === "string") normalized.id = message.id;
|
|
901
|
-
if (typeof message.bubbleId === "string") normalized.bubbleId = message.bubbleId;
|
|
902
|
-
if (typeof message.providerUnitKey === "string") normalized.providerUnitKey = message.providerUnitKey;
|
|
903
|
-
if (message.bubbleState !== void 0) normalized.bubbleState = validateBubbleState(message.bubbleState, source, index);
|
|
904
|
-
if (isFiniteNumber(message.index)) normalized.index = message.index;
|
|
905
|
-
if (isFiniteNumber(message.timestamp)) normalized.timestamp = message.timestamp;
|
|
906
|
-
if (isFiniteNumber(message.receivedAt)) normalized.receivedAt = message.receivedAt;
|
|
907
|
-
if (typeof message._turnKey === "string") normalized._turnKey = message._turnKey;
|
|
908
|
-
if (Array.isArray(message.toolCalls)) normalized.toolCalls = message.toolCalls;
|
|
909
|
-
if (isPlainObject3(message.meta)) normalized.meta = message.meta;
|
|
910
|
-
if (typeof message.senderName === "string") normalized.senderName = message.senderName;
|
|
911
|
-
if (typeof message._type === "string") normalized._type = message._type;
|
|
912
|
-
if (typeof message._sub === "string") normalized._sub = message._sub;
|
|
913
|
-
return normalized;
|
|
914
|
-
}
|
|
915
|
-
function validateModal(activeModal, status, source) {
|
|
916
|
-
if (activeModal == null) {
|
|
917
|
-
if (status === "waiting_approval") {
|
|
918
|
-
throw new Error(`${source}: waiting_approval status requires activeModal with buttons`);
|
|
919
|
-
}
|
|
920
|
-
return activeModal === null ? null : void 0;
|
|
921
|
-
}
|
|
922
|
-
if (!isPlainObject3(activeModal)) {
|
|
923
|
-
throw new Error(`${source}: activeModal must be an object when provided`);
|
|
924
|
-
}
|
|
925
|
-
if (typeof activeModal.message !== "string") {
|
|
926
|
-
throw new Error(`${source}: activeModal.message must be a string`);
|
|
927
|
-
}
|
|
928
|
-
if (!Array.isArray(activeModal.buttons) || activeModal.buttons.some((button) => typeof button !== "string" || !button.trim())) {
|
|
929
|
-
throw new Error(`${source}: activeModal.buttons must be a non-empty string array`);
|
|
930
|
-
}
|
|
931
|
-
const normalized = {
|
|
932
|
-
message: activeModal.message,
|
|
933
|
-
buttons: activeModal.buttons.map((button) => button.trim())
|
|
934
|
-
};
|
|
935
|
-
if (isFiniteNumber(activeModal.width)) normalized.width = activeModal.width;
|
|
936
|
-
if (isFiniteNumber(activeModal.height)) normalized.height = activeModal.height;
|
|
937
|
-
return normalized;
|
|
938
|
-
}
|
|
939
|
-
function validateControlValues(controlValues, source) {
|
|
940
|
-
if (controlValues === void 0) return void 0;
|
|
941
|
-
if (!isPlainObject3(controlValues)) {
|
|
942
|
-
throw new Error(`${source}: controlValues must be an object when provided`);
|
|
943
|
-
}
|
|
944
|
-
const normalized = {};
|
|
945
|
-
for (const [key, value] of Object.entries(controlValues)) {
|
|
946
|
-
if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") {
|
|
947
|
-
throw new Error(`${source}: controlValues.${key} must be string, number, or boolean`);
|
|
948
|
-
}
|
|
949
|
-
normalized[key] = value;
|
|
950
|
-
}
|
|
951
|
-
return normalized;
|
|
952
|
-
}
|
|
953
|
-
function validateReadChatResultPayload(raw, source = "read_chat") {
|
|
954
|
-
if (!isPlainObject3(raw)) {
|
|
955
|
-
throw new Error(`${source}: payload must be an object`);
|
|
956
|
-
}
|
|
957
|
-
const status = validateStatus(raw.status, source);
|
|
958
|
-
if (!Array.isArray(raw.messages)) {
|
|
959
|
-
throw new Error(`${source}: messages must be an array`);
|
|
960
|
-
}
|
|
961
|
-
const messages = raw.messages.map((message, index) => validateMessage(message, source, index));
|
|
962
|
-
const activeModal = validateModal(raw.activeModal, status, source);
|
|
963
|
-
const controlValues = validateControlValues(raw.controlValues, source);
|
|
964
|
-
const normalized = {
|
|
965
|
-
status,
|
|
966
|
-
messages
|
|
967
|
-
};
|
|
968
|
-
if (activeModal !== void 0) normalized.activeModal = activeModal;
|
|
969
|
-
if (typeof raw.id === "string") normalized.id = raw.id;
|
|
970
|
-
if (typeof raw.title === "string") normalized.title = raw.title;
|
|
971
|
-
if (typeof raw.currentTurnId === "string") normalized.currentTurnId = raw.currentTurnId;
|
|
972
|
-
if (raw.turnStatus !== void 0) normalized.turnStatus = validateTurnStatus(raw.turnStatus, source);
|
|
973
|
-
if (typeof raw.agentType === "string") normalized.agentType = raw.agentType;
|
|
974
|
-
if (typeof raw.agentName === "string") normalized.agentName = raw.agentName;
|
|
975
|
-
if (typeof raw.extensionId === "string") normalized.extensionId = raw.extensionId;
|
|
976
|
-
if (typeof raw.inputContent === "string") normalized.inputContent = raw.inputContent;
|
|
977
|
-
if (typeof raw.isVisible === "boolean") normalized.isVisible = raw.isVisible;
|
|
978
|
-
if (typeof raw.isWelcomeScreen === "boolean") normalized.isWelcomeScreen = raw.isWelcomeScreen;
|
|
979
|
-
if (controlValues) normalized.controlValues = controlValues;
|
|
980
|
-
if (raw.summaryMetadata !== void 0) normalized.summaryMetadata = raw.summaryMetadata;
|
|
981
|
-
if (Array.isArray(raw.effects)) normalized.effects = raw.effects;
|
|
982
|
-
if (typeof raw.providerSessionId === "string") normalized.providerSessionId = raw.providerSessionId;
|
|
983
|
-
if (raw.transcriptAuthority === "provider" || raw.transcriptAuthority === "daemon") normalized.transcriptAuthority = raw.transcriptAuthority;
|
|
984
|
-
if (raw.coverage === "full" || raw.coverage === "tail" || raw.coverage === "current-turn") normalized.coverage = raw.coverage;
|
|
985
|
-
return normalized;
|
|
986
|
-
}
|
|
987
|
-
var VALID_STATUSES, VALID_ROLES, VALID_BUBBLE_STATES, VALID_TURN_STATUSES;
|
|
988
|
-
var init_read_chat_contract = __esm({
|
|
989
|
-
"src/providers/read-chat-contract.ts"() {
|
|
990
|
-
"use strict";
|
|
991
|
-
init_contracts();
|
|
992
|
-
VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "streaming", "long_generating"];
|
|
993
|
-
VALID_ROLES = ["user", "assistant", "system", "human"];
|
|
994
|
-
VALID_BUBBLE_STATES = ["draft", "streaming", "final", "removed"];
|
|
995
|
-
VALID_TURN_STATUSES = ["open", "waiting_approval", "complete", "error"];
|
|
996
|
-
}
|
|
997
|
-
});
|
|
998
|
-
|
|
999
480
|
// src/logging/debug-config.ts
|
|
1000
481
|
function normalizeCategories(categories) {
|
|
1001
482
|
if (!Array.isArray(categories)) return [];
|
|
@@ -1563,67 +1044,6 @@ function promptLikelyVisible(screenText, promptSnippet) {
|
|
|
1563
1044
|
function normalizeScreenSnapshot(text) {
|
|
1564
1045
|
return sanitizeTerminalText(String(text || "")).replace(/\s+/g, " ").trim();
|
|
1565
1046
|
}
|
|
1566
|
-
function shouldReflowComparableMessageLines(lines) {
|
|
1567
|
-
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));
|
|
1568
|
-
}
|
|
1569
|
-
function joinComparableMessageLines(lines) {
|
|
1570
|
-
return lines.reduce((acc, line) => {
|
|
1571
|
-
const next = String(line || "").trim();
|
|
1572
|
-
if (!next) return acc;
|
|
1573
|
-
if (!acc) return next;
|
|
1574
|
-
if (/[,\d]$/.test(acc) && /^\d/.test(next)) {
|
|
1575
|
-
return `${acc}${next}`;
|
|
1576
|
-
}
|
|
1577
|
-
if (/[A-Za-z]$/.test(acc) && /^\d/.test(next)) {
|
|
1578
|
-
return `${acc}${next}`;
|
|
1579
|
-
}
|
|
1580
|
-
const fragmentMatch = acc.match(/([A-Za-z]{1,4})$/);
|
|
1581
|
-
const fragment = fragmentMatch ? fragmentMatch[1].toLowerCase() : "";
|
|
1582
|
-
if (/^[a-z]/.test(next) && fragment && !COMMON_COMPARABLE_WRAP_WORDS.has(fragment)) {
|
|
1583
|
-
return `${acc}${next}`;
|
|
1584
|
-
}
|
|
1585
|
-
return `${acc} ${next}`;
|
|
1586
|
-
}, "").replace(/\s+([,.;:!?])/g, "$1").replace(/(\d)\s+,/g, "$1,").replace(/\s+/g, " ").trim();
|
|
1587
|
-
}
|
|
1588
|
-
function normalizeComparableMessageContent(text) {
|
|
1589
|
-
const lines = String(text || "").split(/\r\n|\n|\r/g).map((line) => line.trim()).filter(Boolean);
|
|
1590
|
-
if (lines.length === 0) return "";
|
|
1591
|
-
if (shouldReflowComparableMessageLines(lines)) {
|
|
1592
|
-
return joinComparableMessageLines(lines);
|
|
1593
|
-
}
|
|
1594
|
-
return lines.join(" ").replace(/\s+/g, " ").trim();
|
|
1595
|
-
}
|
|
1596
|
-
function trimPromptEchoPrefix(text, promptText) {
|
|
1597
|
-
const prompt = normalizeComparableMessageContent(String(promptText || ""));
|
|
1598
|
-
if (!prompt) return String(text || "");
|
|
1599
|
-
const lines = String(text || "").split(/\r\n|\n|\r/g);
|
|
1600
|
-
let dropCount = 0;
|
|
1601
|
-
for (let index = 0; index < Math.min(lines.length, 6); index += 1) {
|
|
1602
|
-
const fragment = normalizeComparableMessageContent(lines[index].replace(/^[.…]+\s*/, ""));
|
|
1603
|
-
if (!fragment) {
|
|
1604
|
-
if (dropCount === index) dropCount = index + 1;
|
|
1605
|
-
continue;
|
|
1606
|
-
}
|
|
1607
|
-
const fragmentWordCount = fragment ? fragment.split(/\s+/).filter(Boolean).length : 0;
|
|
1608
|
-
const canBePromptEcho = fragment.length >= 16 || fragmentWordCount >= 4;
|
|
1609
|
-
if (canBePromptEcho && prompt.includes(fragment)) {
|
|
1610
|
-
dropCount = index + 1;
|
|
1611
|
-
continue;
|
|
1612
|
-
}
|
|
1613
|
-
break;
|
|
1614
|
-
}
|
|
1615
|
-
return lines.slice(dropCount).join("\n").trim();
|
|
1616
|
-
}
|
|
1617
|
-
function getLastUserPromptText(messages) {
|
|
1618
|
-
const items = Array.isArray(messages) ? messages : [];
|
|
1619
|
-
for (let index = items.length - 1; index >= 0; index -= 1) {
|
|
1620
|
-
const message = items[index];
|
|
1621
|
-
if (message?.role === "user" && typeof message.content === "string" && message.content.trim()) {
|
|
1622
|
-
return message.content;
|
|
1623
|
-
}
|
|
1624
|
-
}
|
|
1625
|
-
return "";
|
|
1626
|
-
}
|
|
1627
1047
|
function parsePatternEntry(x) {
|
|
1628
1048
|
if (x instanceof RegExp) return x;
|
|
1629
1049
|
if (x && typeof x === "object" && typeof x.source === "string") {
|
|
@@ -1650,38 +1070,12 @@ function normalizeCliProviderForRuntime(raw) {
|
|
|
1650
1070
|
}
|
|
1651
1071
|
};
|
|
1652
1072
|
}
|
|
1653
|
-
var buildCliSpawnEnv
|
|
1073
|
+
var buildCliSpawnEnv;
|
|
1654
1074
|
var init_provider_cli_shared = __esm({
|
|
1655
1075
|
"src/cli-adapters/provider-cli-shared.ts"() {
|
|
1656
1076
|
"use strict";
|
|
1657
1077
|
init_spawn_env();
|
|
1658
1078
|
buildCliSpawnEnv = sanitizeSpawnEnv;
|
|
1659
|
-
COMMON_COMPARABLE_WRAP_WORDS = /* @__PURE__ */ new Set([
|
|
1660
|
-
"a",
|
|
1661
|
-
"an",
|
|
1662
|
-
"and",
|
|
1663
|
-
"as",
|
|
1664
|
-
"at",
|
|
1665
|
-
"but",
|
|
1666
|
-
"by",
|
|
1667
|
-
"for",
|
|
1668
|
-
"from",
|
|
1669
|
-
"in",
|
|
1670
|
-
"into",
|
|
1671
|
-
"is",
|
|
1672
|
-
"it",
|
|
1673
|
-
"of",
|
|
1674
|
-
"on",
|
|
1675
|
-
"or",
|
|
1676
|
-
"that",
|
|
1677
|
-
"the",
|
|
1678
|
-
"their",
|
|
1679
|
-
"then",
|
|
1680
|
-
"this",
|
|
1681
|
-
"to",
|
|
1682
|
-
"was",
|
|
1683
|
-
"with"
|
|
1684
|
-
]);
|
|
1685
1079
|
}
|
|
1686
1080
|
});
|
|
1687
1081
|
|
|
@@ -1692,169 +1086,8 @@ function sliceFromOffset(text, start) {
|
|
|
1692
1086
|
if (start >= text.length) return "";
|
|
1693
1087
|
return text.slice(start);
|
|
1694
1088
|
}
|
|
1695
|
-
function
|
|
1696
|
-
|
|
1697
|
-
const referenceMessages = [...committedMessages];
|
|
1698
|
-
const referenceComparables = new Array(referenceMessages.length);
|
|
1699
|
-
const usedReferenceIndexes = /* @__PURE__ */ new Set();
|
|
1700
|
-
const now = options.now ?? Date.now();
|
|
1701
|
-
let exactReferenceIndexesByKey = null;
|
|
1702
|
-
const exactReferenceCursorByKey = /* @__PURE__ */ new Map();
|
|
1703
|
-
const hasFiniteTimestamp = (message) => typeof message?.timestamp === "number" && Number.isFinite(message.timestamp);
|
|
1704
|
-
const getReferenceComparable = (index) => {
|
|
1705
|
-
if (typeof referenceComparables[index] === "string") return referenceComparables[index] || "";
|
|
1706
|
-
const comparable = normalizeComparableMessageContent(referenceMessages[index]?.content || "");
|
|
1707
|
-
referenceComparables[index] = comparable;
|
|
1708
|
-
return comparable;
|
|
1709
|
-
};
|
|
1710
|
-
const messagesShareStableIdentity = (parsed, reference) => {
|
|
1711
|
-
if (!parsed || !reference) return false;
|
|
1712
|
-
const parsedId = typeof parsed.id === "string" ? parsed.id.trim() : "";
|
|
1713
|
-
const referenceId = typeof reference.id === "string" ? reference.id.trim() : "";
|
|
1714
|
-
if (parsedId && referenceId && parsedId === referenceId) return true;
|
|
1715
|
-
return typeof parsed.index === "number" && Number.isFinite(parsed.index) && typeof reference.index === "number" && Number.isFinite(reference.index) && parsed.index === reference.index;
|
|
1716
|
-
};
|
|
1717
|
-
const exactReferenceKey = (role, comparable) => `${role}\0${comparable}`;
|
|
1718
|
-
const ensureExactReferenceIndex = () => {
|
|
1719
|
-
if (exactReferenceIndexesByKey) return exactReferenceIndexesByKey;
|
|
1720
|
-
const byKey = /* @__PURE__ */ new Map();
|
|
1721
|
-
for (let i = 0; i < referenceMessages.length; i++) {
|
|
1722
|
-
const candidate = referenceMessages[i];
|
|
1723
|
-
if (!candidate || candidate.role !== "user" && candidate.role !== "assistant" || !hasFiniteTimestamp(candidate)) continue;
|
|
1724
|
-
const comparable = getReferenceComparable(i);
|
|
1725
|
-
if (!comparable) continue;
|
|
1726
|
-
const key = exactReferenceKey(candidate.role, comparable);
|
|
1727
|
-
const indexes = byKey.get(key);
|
|
1728
|
-
if (indexes) {
|
|
1729
|
-
indexes.push(i);
|
|
1730
|
-
} else {
|
|
1731
|
-
byKey.set(key, [i]);
|
|
1732
|
-
}
|
|
1733
|
-
}
|
|
1734
|
-
exactReferenceIndexesByKey = byKey;
|
|
1735
|
-
return byKey;
|
|
1736
|
-
};
|
|
1737
|
-
const takeExactReferenceTimestamp = (role, normalizedContent) => {
|
|
1738
|
-
const key = exactReferenceKey(role, normalizedContent);
|
|
1739
|
-
const indexes = ensureExactReferenceIndex().get(key);
|
|
1740
|
-
if (!indexes) return void 0;
|
|
1741
|
-
let cursor = exactReferenceCursorByKey.get(key) || 0;
|
|
1742
|
-
while (cursor < indexes.length) {
|
|
1743
|
-
const candidateIndex = indexes[cursor];
|
|
1744
|
-
cursor += 1;
|
|
1745
|
-
if (usedReferenceIndexes.has(candidateIndex)) continue;
|
|
1746
|
-
const candidate = referenceMessages[candidateIndex];
|
|
1747
|
-
if (!candidate || candidate.role !== role || !hasFiniteTimestamp(candidate)) continue;
|
|
1748
|
-
usedReferenceIndexes.add(candidateIndex);
|
|
1749
|
-
exactReferenceCursorByKey.set(key, cursor);
|
|
1750
|
-
return candidate.timestamp;
|
|
1751
|
-
}
|
|
1752
|
-
exactReferenceCursorByKey.set(key, cursor);
|
|
1753
|
-
return void 0;
|
|
1754
|
-
};
|
|
1755
|
-
const findReferenceTimestamp = (message, role, content, parsedIndex) => {
|
|
1756
|
-
const sameIndex = referenceMessages[parsedIndex];
|
|
1757
|
-
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && hasFiniteTimestamp(sameIndex) && messagesShareStableIdentity(message, sameIndex)) {
|
|
1758
|
-
usedReferenceIndexes.add(parsedIndex);
|
|
1759
|
-
return sameIndex.timestamp;
|
|
1760
|
-
}
|
|
1761
|
-
const normalizedContent = normalizeComparableMessageContent(content);
|
|
1762
|
-
if (!normalizedContent) return void 0;
|
|
1763
|
-
if (sameIndex && !usedReferenceIndexes.has(parsedIndex) && sameIndex.role === role && getReferenceComparable(parsedIndex) === normalizedContent && hasFiniteTimestamp(sameIndex)) {
|
|
1764
|
-
usedReferenceIndexes.add(parsedIndex);
|
|
1765
|
-
return sameIndex.timestamp;
|
|
1766
|
-
}
|
|
1767
|
-
const exactTimestamp = takeExactReferenceTimestamp(role, normalizedContent);
|
|
1768
|
-
if (typeof exactTimestamp === "number") return exactTimestamp;
|
|
1769
|
-
for (let i = 0; i < referenceMessages.length; i++) {
|
|
1770
|
-
if (usedReferenceIndexes.has(i)) continue;
|
|
1771
|
-
const candidate = referenceMessages[i];
|
|
1772
|
-
if (!candidate || candidate.role !== role) continue;
|
|
1773
|
-
const candidateContent = getReferenceComparable(i);
|
|
1774
|
-
if (!candidateContent) continue;
|
|
1775
|
-
const fuzzyMatch = candidateContent.includes(normalizedContent) || normalizedContent.includes(candidateContent);
|
|
1776
|
-
if (!fuzzyMatch) continue;
|
|
1777
|
-
if (hasFiniteTimestamp(candidate)) {
|
|
1778
|
-
usedReferenceIndexes.add(i);
|
|
1779
|
-
return candidate.timestamp;
|
|
1780
|
-
}
|
|
1781
|
-
}
|
|
1782
|
-
return void 0;
|
|
1783
|
-
};
|
|
1784
|
-
return parsedMessages.filter((message) => message && (message.role === "user" || message.role === "assistant")).map((message, index) => {
|
|
1785
|
-
const role = message.role;
|
|
1786
|
-
const content = typeof message.content === "string" ? message.content : String(message.content || "");
|
|
1787
|
-
const parsedTimestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0;
|
|
1788
|
-
const referenceTimestamp = parsedTimestamp ?? findReferenceTimestamp(message, role, content, index);
|
|
1789
|
-
const fallbackTimestamp = role === "user" ? scope?.startedAt || now : lastOutputAt || scope?.startedAt || now;
|
|
1790
|
-
const timestamp = referenceTimestamp ?? fallbackTimestamp;
|
|
1791
|
-
return {
|
|
1792
|
-
...message,
|
|
1793
|
-
role,
|
|
1794
|
-
content,
|
|
1795
|
-
timestamp,
|
|
1796
|
-
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : timestamp
|
|
1797
|
-
};
|
|
1798
|
-
});
|
|
1799
|
-
}
|
|
1800
|
-
function chooseMoreComparableCliMessage(left, right, leftComparable = normalizeComparableMessageContent(left.content || ""), rightComparable = normalizeComparableMessageContent(right.content || "")) {
|
|
1801
|
-
if (leftComparable && leftComparable === rightComparable) {
|
|
1802
|
-
const leftNewlines = String(left.content || "").split(/\r\n|\n|\r/g).length - 1;
|
|
1803
|
-
const rightNewlines = String(right.content || "").split(/\r\n|\n|\r/g).length - 1;
|
|
1804
|
-
return rightNewlines < leftNewlines ? right : left;
|
|
1805
|
-
}
|
|
1806
|
-
return rightComparable.length > leftComparable.length ? right : left;
|
|
1807
|
-
}
|
|
1808
|
-
function dedupeConsecutiveComparableCliMessages(messages) {
|
|
1809
|
-
const deduped = [];
|
|
1810
|
-
for (const message of messages) {
|
|
1811
|
-
const current = {
|
|
1812
|
-
...message,
|
|
1813
|
-
content: typeof message.content === "string" ? message.content : String(message.content || "")
|
|
1814
|
-
};
|
|
1815
|
-
const currentComparable = normalizeComparableMessageContent(current.content || "");
|
|
1816
|
-
const previous = deduped[deduped.length - 1];
|
|
1817
|
-
if (!previous) {
|
|
1818
|
-
deduped.push({ message: current, comparable: currentComparable });
|
|
1819
|
-
continue;
|
|
1820
|
-
}
|
|
1821
|
-
const sameRole = previous.message.role === current.role;
|
|
1822
|
-
const sameKind = (previous.message.kind || "standard") === (current.kind || "standard");
|
|
1823
|
-
const sameSender = (previous.message.senderName || "") === (current.senderName || "");
|
|
1824
|
-
const comparableMatch = previous.comparable && previous.comparable === currentComparable;
|
|
1825
|
-
if (sameRole && sameKind && sameSender && comparableMatch) {
|
|
1826
|
-
const selected = chooseMoreComparableCliMessage(
|
|
1827
|
-
previous.message,
|
|
1828
|
-
current,
|
|
1829
|
-
previous.comparable,
|
|
1830
|
-
currentComparable
|
|
1831
|
-
);
|
|
1832
|
-
deduped[deduped.length - 1] = {
|
|
1833
|
-
message: selected,
|
|
1834
|
-
comparable: selected === current ? currentComparable : previous.comparable
|
|
1835
|
-
};
|
|
1836
|
-
continue;
|
|
1837
|
-
}
|
|
1838
|
-
deduped.push({ message: current, comparable: currentComparable });
|
|
1839
|
-
}
|
|
1840
|
-
return deduped.map((entry) => entry.message);
|
|
1841
|
-
}
|
|
1842
|
-
function normalizeCliParsedMessages(parsedMessages, options) {
|
|
1843
|
-
return dedupeConsecutiveComparableCliMessages(hydrateCliParsedMessages(parsedMessages, options).map((message) => ({
|
|
1844
|
-
role: message.role,
|
|
1845
|
-
content: message.content,
|
|
1846
|
-
timestamp: message.timestamp,
|
|
1847
|
-
receivedAt: message.receivedAt,
|
|
1848
|
-
kind: message.kind,
|
|
1849
|
-
id: message.id,
|
|
1850
|
-
index: message.index,
|
|
1851
|
-
providerUnitKey: message.providerUnitKey,
|
|
1852
|
-
bubbleId: message.bubbleId,
|
|
1853
|
-
bubbleState: message.bubbleState,
|
|
1854
|
-
_turnKey: message._turnKey,
|
|
1855
|
-
meta: message.meta,
|
|
1856
|
-
senderName: message.senderName
|
|
1857
|
-
})));
|
|
1089
|
+
function normalizeCliParsedMessages(parsedMessages, _options) {
|
|
1090
|
+
return Array.isArray(parsedMessages) ? parsedMessages : [];
|
|
1858
1091
|
}
|
|
1859
1092
|
function buildCliParseInput(options) {
|
|
1860
1093
|
const {
|
|
@@ -2063,41 +1296,9 @@ var provider_cli_adapter_exports = {};
|
|
|
2063
1296
|
__export(provider_cli_adapter_exports, {
|
|
2064
1297
|
ProviderCliAdapter: () => ProviderCliAdapter,
|
|
2065
1298
|
appendBoundedText: () => appendBoundedText,
|
|
2066
|
-
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
2067
|
-
sanitizeCliStandardMessageContent: () => sanitizeCliStandardMessageContent,
|
|
2068
|
-
trimLastAssistantEchoForCliMessages: () => trimLastAssistantEchoForCliMessages
|
|
1299
|
+
normalizeCliProviderForRuntime: () => normalizeCliProviderForRuntime
|
|
2069
1300
|
});
|
|
2070
1301
|
import * as os11 from "os";
|
|
2071
|
-
function normalizeComparableTranscriptText(value) {
|
|
2072
|
-
return sanitizeTerminalText(String(value || "")).replace(/\s+/g, " ").trim();
|
|
2073
|
-
}
|
|
2074
|
-
function hasVisibleInterruptPrompt(text) {
|
|
2075
|
-
const interruptCopyPattern = /\bEnter\s+to\s+interrupt\b(?:\s*,?\s*Ctrl\s*(?:\+|-)?\s*C\s+to\s+cancel)?/i;
|
|
2076
|
-
return sanitizeTerminalText(text || "").split(/\r?\n/g).some((line) => {
|
|
2077
|
-
const trimmed = line.trim();
|
|
2078
|
-
if (!interruptCopyPattern.test(trimmed)) return false;
|
|
2079
|
-
return /^(?:[^A-Za-z0-9\s]{1,8}\s+)?[❯›>]\s+/.test(trimmed);
|
|
2080
|
-
});
|
|
2081
|
-
}
|
|
2082
|
-
function parsedTranscriptIsRicherThanCommitted(parsedMessages, committedMessages) {
|
|
2083
|
-
if (!Array.isArray(parsedMessages) || !Array.isArray(committedMessages)) return false;
|
|
2084
|
-
if (parsedMessages.length > committedMessages.length) return true;
|
|
2085
|
-
if (parsedMessages.length !== committedMessages.length) return false;
|
|
2086
|
-
for (let index = 0; index < parsedMessages.length; index += 1) {
|
|
2087
|
-
const parsed = parsedMessages[index];
|
|
2088
|
-
const committed = committedMessages[index];
|
|
2089
|
-
if (!parsed || !committed) return false;
|
|
2090
|
-
if ((parsed.role || "") !== (committed.role || "")) return false;
|
|
2091
|
-
if (parsed.id && committed.id && String(parsed.id) !== String(committed.id)) return false;
|
|
2092
|
-
if (typeof parsed.index === "number" && typeof committed.index === "number" && parsed.index !== committed.index) return false;
|
|
2093
|
-
const parsedText = normalizeComparableTranscriptText(parsed.content);
|
|
2094
|
-
const committedText = normalizeComparableTranscriptText(committed.content);
|
|
2095
|
-
if (!parsedText || !committedText || parsedText === committedText) continue;
|
|
2096
|
-
if (parsedText.length > committedText.length && parsedText.startsWith(committedText)) return true;
|
|
2097
|
-
return false;
|
|
2098
|
-
}
|
|
2099
|
-
return false;
|
|
2100
|
-
}
|
|
2101
1302
|
function appendBoundedText(current, chunk, maxChars) {
|
|
2102
1303
|
if (!chunk) return current.length <= maxChars ? current : current.slice(-maxChars);
|
|
2103
1304
|
if (maxChars <= 0) return "";
|
|
@@ -2106,76 +1307,7 @@ function appendBoundedText(current, chunk, maxChars) {
|
|
|
2106
1307
|
if (current.length <= keepFromCurrent) return current + chunk;
|
|
2107
1308
|
return current.slice(-keepFromCurrent) + chunk;
|
|
2108
1309
|
}
|
|
2109
|
-
|
|
2110
|
-
const trimmed = String(line || "").trim();
|
|
2111
|
-
if (!trimmed) return false;
|
|
2112
|
-
if (COMMITTED_ACTIVITY_PREFIX_BLOCK_RE.test(trimmed)) return false;
|
|
2113
|
-
if (/\s/.test(trimmed)) return false;
|
|
2114
|
-
if (/[가-힣]/.test(trimmed)) return false;
|
|
2115
|
-
if (trimmed.length > 96) return false;
|
|
2116
|
-
return /^[A-Za-z0-9_./:@+%=-]+$/.test(trimmed);
|
|
2117
|
-
}
|
|
2118
|
-
function parseCommittedActivityPrefixBlock(lines, index) {
|
|
2119
|
-
const first = String(lines[index] || "").trim();
|
|
2120
|
-
if (!COMMITTED_ACTIVITY_PREFIX_BLOCK_RE.test(first)) return null;
|
|
2121
|
-
const parts = [first];
|
|
2122
|
-
let nextIndex = index + 1;
|
|
2123
|
-
while (nextIndex < lines.length && isLikelyCommittedActivityPrefixContinuation(lines[nextIndex])) {
|
|
2124
|
-
parts.push(String(lines[nextIndex] || "").trim());
|
|
2125
|
-
nextIndex += 1;
|
|
2126
|
-
}
|
|
2127
|
-
return { label: parts.join(""), nextIndex };
|
|
2128
|
-
}
|
|
2129
|
-
function sanitizeCliStandardMessageContent(content) {
|
|
2130
|
-
const source = String(content || "").trim();
|
|
2131
|
-
if (!source) return "";
|
|
2132
|
-
const lines = source.split(/\r?\n/);
|
|
2133
|
-
if (lines.length < 4) return source;
|
|
2134
|
-
const counts = /* @__PURE__ */ new Map();
|
|
2135
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
2136
|
-
const block = parseCommittedActivityPrefixBlock(lines, index);
|
|
2137
|
-
if (!block) continue;
|
|
2138
|
-
counts.set(block.label, (counts.get(block.label) || 0) + 1);
|
|
2139
|
-
index = block.nextIndex - 1;
|
|
2140
|
-
}
|
|
2141
|
-
const repeatedLabels = new Set(
|
|
2142
|
-
Array.from(counts.entries()).filter(([, count]) => count >= 3).map(([label]) => label)
|
|
2143
|
-
);
|
|
2144
|
-
if (repeatedLabels.size === 0) return source;
|
|
2145
|
-
const stripped = [];
|
|
2146
|
-
let removed = 0;
|
|
2147
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
2148
|
-
const block = parseCommittedActivityPrefixBlock(lines, index);
|
|
2149
|
-
if (block && repeatedLabels.has(block.label)) {
|
|
2150
|
-
removed += 1;
|
|
2151
|
-
index = block.nextIndex - 1;
|
|
2152
|
-
continue;
|
|
2153
|
-
}
|
|
2154
|
-
stripped.push(lines[index]);
|
|
2155
|
-
}
|
|
2156
|
-
const next = stripped.join("\n").replace(/\n{3,}/g, "\n\n").trim();
|
|
2157
|
-
return removed >= 3 && next.length >= 80 ? next : source;
|
|
2158
|
-
}
|
|
2159
|
-
function sanitizeCommittedMessageForDisplay(message) {
|
|
2160
|
-
if (!message || message.role !== "assistant" || (message.kind || "standard") !== "standard") return message;
|
|
2161
|
-
const content = sanitizeCliStandardMessageContent(message.content);
|
|
2162
|
-
if (content === message.content) return message;
|
|
2163
|
-
return { ...message, content };
|
|
2164
|
-
}
|
|
2165
|
-
function trimLastAssistantEchoForCliMessages(messages, prompt) {
|
|
2166
|
-
if (!prompt) return;
|
|
2167
|
-
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
2168
|
-
const message = messages[index];
|
|
2169
|
-
if (!message || message.role !== "assistant" || typeof message.content !== "string") continue;
|
|
2170
|
-
if ((message.kind || "standard") !== "standard") continue;
|
|
2171
|
-
message.content = trimPromptEchoPrefix(message.content, prompt);
|
|
2172
|
-
if (!message.content.trim()) {
|
|
2173
|
-
messages.splice(index, 1);
|
|
2174
|
-
}
|
|
2175
|
-
return;
|
|
2176
|
-
}
|
|
2177
|
-
}
|
|
2178
|
-
var COMMITTED_ACTIVITY_PREFIX_BLOCK_RE, ProviderCliAdapter;
|
|
1310
|
+
var ProviderCliAdapter;
|
|
2179
1311
|
var init_provider_cli_adapter = __esm({
|
|
2180
1312
|
"src/cli-adapters/provider-cli-adapter.ts"() {
|
|
2181
1313
|
"use strict";
|
|
@@ -2184,13 +1316,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
2184
1316
|
init_terminal_screen();
|
|
2185
1317
|
init_pty_transport();
|
|
2186
1318
|
init_provider_cli_shared();
|
|
2187
|
-
init_chat_message_normalization();
|
|
2188
|
-
init_read_chat_contract();
|
|
2189
1319
|
init_provider_cli_parse();
|
|
2190
1320
|
init_provider_cli_config();
|
|
2191
1321
|
init_provider_cli_runtime();
|
|
2192
1322
|
init_provider_cli_shared();
|
|
2193
|
-
COMMITTED_ACTIVITY_PREFIX_BLOCK_RE = /^(?:📖|💻|🔎|📚|📋|✏️|📝|🔧|🛠️|⚙️)\s+(.+)$/;
|
|
2194
1323
|
ProviderCliAdapter = class _ProviderCliAdapter {
|
|
2195
1324
|
constructor(provider, workingDir, extraArgs = [], transportFactory = new NodePtyTransportFactory()) {
|
|
2196
1325
|
this.extraArgs = extraArgs;
|
|
@@ -2233,11 +1362,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
2233
1362
|
provider;
|
|
2234
1363
|
ptyProcess = null;
|
|
2235
1364
|
transportFactory;
|
|
2236
|
-
messages = [];
|
|
2237
|
-
committedMessages = [];
|
|
2238
|
-
structuredMessages = [];
|
|
2239
|
-
committedMessagesActivitySignature = "";
|
|
2240
|
-
committedMessagesChangedAt = 0;
|
|
2241
1365
|
currentStatus = "starting";
|
|
2242
1366
|
onStatusChange = null;
|
|
2243
1367
|
responseBuffer = "";
|
|
@@ -2317,11 +1441,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
2317
1441
|
traceSeq = 0;
|
|
2318
1442
|
traceSessionId = "";
|
|
2319
1443
|
parsedStatusCache = null;
|
|
2320
|
-
lastStatusHotPathParseAt = Number.NEGATIVE_INFINITY;
|
|
2321
|
-
static STATUS_HOT_PATH_PARSE_MIN_INTERVAL_MS = 1e3;
|
|
2322
1444
|
static SCREEN_SNAPSHOT_MIN_INTERVAL_MS = 250;
|
|
2323
1445
|
static MAX_TRACE_ENTRIES = 250;
|
|
2324
|
-
static PARSE_MESSAGE_TAIL_LIMIT = 100;
|
|
2325
1446
|
providerResolutionMeta;
|
|
2326
1447
|
static FINISH_RETRY_DELAY_MS = 300;
|
|
2327
1448
|
static MAX_FINISH_RETRIES = 2;
|
|
@@ -2342,35 +1463,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
2342
1463
|
recordBoundedAppendDrop(previousLength, appendedLength, nextLength) {
|
|
2343
1464
|
return Math.max(0, previousLength + appendedLength - nextLength);
|
|
2344
1465
|
}
|
|
2345
|
-
buildCommittedMessagesActivitySignature() {
|
|
2346
|
-
const last = this.committedMessages[this.committedMessages.length - 1];
|
|
2347
|
-
return [
|
|
2348
|
-
String(this.committedMessages.length),
|
|
2349
|
-
String(last?.role || ""),
|
|
2350
|
-
String(last?.kind || ""),
|
|
2351
|
-
String(last?.senderName || ""),
|
|
2352
|
-
String(last?.timestamp || ""),
|
|
2353
|
-
String(last?.receivedAt || ""),
|
|
2354
|
-
normalizeComparableMessageContent(last?.content || "").slice(-240)
|
|
2355
|
-
].join("|");
|
|
2356
|
-
}
|
|
2357
|
-
syncMessageViews() {
|
|
2358
|
-
const signature = this.buildCommittedMessagesActivitySignature();
|
|
2359
|
-
if (signature !== this.committedMessagesActivitySignature) {
|
|
2360
|
-
this.committedMessagesActivitySignature = signature;
|
|
2361
|
-
this.committedMessagesChangedAt = Date.now();
|
|
2362
|
-
}
|
|
2363
|
-
this.messages = [...this.committedMessages];
|
|
2364
|
-
this.structuredMessages = [...this.committedMessages];
|
|
2365
|
-
}
|
|
2366
|
-
getLastCommittedMessageActivityAt() {
|
|
2367
|
-
const last = this.committedMessages[this.committedMessages.length - 1];
|
|
2368
|
-
const messageTime = Math.max(
|
|
2369
|
-
typeof last?.receivedAt === "number" && Number.isFinite(last.receivedAt) ? last.receivedAt : 0,
|
|
2370
|
-
typeof last?.timestamp === "number" && Number.isFinite(last.timestamp) ? last.timestamp : 0
|
|
2371
|
-
);
|
|
2372
|
-
return Math.max(messageTime, this.committedMessagesChangedAt || 0);
|
|
2373
|
-
}
|
|
2374
1466
|
readTerminalScreenText(now = Date.now()) {
|
|
2375
1467
|
const screenText = this.terminalScreen.getText() || "";
|
|
2376
1468
|
this.lastScreenText = screenText;
|
|
@@ -2390,7 +1482,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
2390
1482
|
}
|
|
2391
1483
|
getFreshParsedStatusCache() {
|
|
2392
1484
|
const cached = this.parsedStatusCache;
|
|
2393
|
-
if (cached && cached.
|
|
1485
|
+
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) {
|
|
2394
1486
|
return cached.result;
|
|
2395
1487
|
}
|
|
2396
1488
|
return null;
|
|
@@ -2401,45 +1493,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
2401
1493
|
shouldUseFullProviderTranscriptContext() {
|
|
2402
1494
|
return this.providerOwnsTranscript() && this.provider.transcriptContext === "full";
|
|
2403
1495
|
}
|
|
2404
|
-
selectParseBaseMessages(baseMessages) {
|
|
2405
|
-
if (this.shouldUseFullProviderTranscriptContext()) return baseMessages;
|
|
2406
|
-
if (baseMessages.length <= _ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT) return baseMessages;
|
|
2407
|
-
return baseMessages.slice(-_ProviderCliAdapter.PARSE_MESSAGE_TAIL_LIMIT);
|
|
2408
|
-
}
|
|
2409
|
-
messagesShareStableIdentity(left, right) {
|
|
2410
|
-
if (left === right) return true;
|
|
2411
|
-
if (!left || !right) return false;
|
|
2412
|
-
if ((left.role || "") !== (right.role || "")) return false;
|
|
2413
|
-
if (left.id && right.id && String(left.id) === String(right.id)) return true;
|
|
2414
|
-
if (typeof left.index === "number" && typeof right.index === "number" && left.index === right.index) return true;
|
|
2415
|
-
return false;
|
|
2416
|
-
}
|
|
2417
|
-
messagesComparable(left, right) {
|
|
2418
|
-
if (this.messagesShareStableIdentity(left, right)) return true;
|
|
2419
|
-
if (!left || !right) return false;
|
|
2420
|
-
if ((left.role || "") !== (right.role || "")) return false;
|
|
2421
|
-
const leftText = normalizeComparableTranscriptText(left.content);
|
|
2422
|
-
const rightText = normalizeComparableTranscriptText(right.content);
|
|
2423
|
-
return !!leftText && leftText === rightText;
|
|
2424
|
-
}
|
|
2425
|
-
stitchParsedMessagesWithCommittedBase(parsedMessages, fullBaseMessages, parseBaseMessages) {
|
|
2426
|
-
if (!Array.isArray(parsedMessages) || parsedMessages.length === 0) return parsedMessages;
|
|
2427
|
-
if (fullBaseMessages.length <= parseBaseMessages.length) return parsedMessages;
|
|
2428
|
-
const parsedFirst = parsedMessages[0];
|
|
2429
|
-
const fullFirst = fullBaseMessages[0];
|
|
2430
|
-
if (parsedMessages.length >= fullBaseMessages.length && this.messagesComparable(parsedFirst, fullFirst)) {
|
|
2431
|
-
return parsedMessages;
|
|
2432
|
-
}
|
|
2433
|
-
const tailFirst = parseBaseMessages[0];
|
|
2434
|
-
if (tailFirst && this.messagesComparable(parsedFirst, tailFirst)) {
|
|
2435
|
-
const prefixLength = fullBaseMessages.length - parseBaseMessages.length;
|
|
2436
|
-
const prefix = fullBaseMessages.slice(0, prefixLength);
|
|
2437
|
-
const shouldSanitizePrefix = !!this.currentTurnScope || this.currentStatus !== "idle" || !!this.activeModal;
|
|
2438
|
-
const nextPrefix = shouldSanitizePrefix ? prefix.map((message) => sanitizeCommittedMessageForDisplay(message)) : prefix;
|
|
2439
|
-
return [...nextPrefix, ...parsedMessages];
|
|
2440
|
-
}
|
|
2441
|
-
return [...fullBaseMessages, ...parsedMessages];
|
|
2442
|
-
}
|
|
2443
1496
|
getIdleFinishConfirmMs() {
|
|
2444
1497
|
return this.timeouts.idleFinishConfirm;
|
|
2445
1498
|
}
|
|
@@ -2892,9 +1945,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
2892
1945
|
`[${this.cliType}] Interactive prompt wait timed out after ${maxWaitMs}ms; proceeding with screen=${JSON.stringify(summarizeCliTraceText(finalScreenText, 240)).slice(0, 280)}`
|
|
2893
1946
|
);
|
|
2894
1947
|
}
|
|
2895
|
-
trimLastAssistantEcho(messages, prompt) {
|
|
2896
|
-
trimLastAssistantEchoForCliMessages(messages, prompt);
|
|
2897
|
-
}
|
|
2898
1948
|
clearAllTimers() {
|
|
2899
1949
|
if (this.responseTimeout) {
|
|
2900
1950
|
clearTimeout(this.responseTimeout);
|
|
@@ -2990,10 +2040,10 @@ var init_provider_cli_adapter = __esm({
|
|
|
2990
2040
|
}
|
|
2991
2041
|
const session = this.runParseSession();
|
|
2992
2042
|
if (!session) return;
|
|
2993
|
-
const { status, messages,
|
|
2043
|
+
const { status, messages, parsedStatus } = session;
|
|
2044
|
+
const modal = session.activeModal ?? session.modal ?? null;
|
|
2994
2045
|
const parsedMessages = normalizeCliParsedMessages(messages, {
|
|
2995
|
-
|
|
2996
|
-
scope: this.currentTurnScope,
|
|
2046
|
+
scope: null,
|
|
2997
2047
|
lastOutputAt: this.lastOutputAt
|
|
2998
2048
|
});
|
|
2999
2049
|
if (this.maybeCommitVisibleIdleTranscript(session, parsedMessages)) return;
|
|
@@ -3173,7 +2223,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
3173
2223
|
const effectiveScreenText = screenText || this.accumulatedBuffer;
|
|
3174
2224
|
const noActiveTurn = !this.currentTurnScope;
|
|
3175
2225
|
const looksIdleChrome = /(^|\n)\s*[❯›>]\s*(?:\n|$)/m.test(effectiveScreenText);
|
|
3176
|
-
const parsedShowsLiveAssistantProgress = parsedStatus === "generating" && !!lastParsedAssistant
|
|
2226
|
+
const parsedShowsLiveAssistantProgress = parsedStatus === "generating" && !!lastParsedAssistant;
|
|
3177
2227
|
if (prevStatus === "idle" && !this.isWaitingForResponse && noActiveTurn && !modal && looksIdleChrome && !parsedShowsLiveAssistantProgress) {
|
|
3178
2228
|
return;
|
|
3179
2229
|
}
|
|
@@ -3330,10 +2380,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
3330
2380
|
}
|
|
3331
2381
|
const visibleAssistant = [...parsedMessages].reverse().find((m) => m.role === "assistant" && m.content.trim());
|
|
3332
2382
|
if (!visibleAssistant) return false;
|
|
3333
|
-
this.committedMessages = parsedMessages;
|
|
3334
|
-
this.trimLastAssistantEcho(this.committedMessages, this.currentTurnScope?.prompt || getLastUserPromptText(this.committedMessages));
|
|
3335
2383
|
this.clearAllTimers();
|
|
3336
|
-
this.syncMessageViews();
|
|
3337
2384
|
this.responseBuffer = "";
|
|
3338
2385
|
this.isWaitingForResponse = false;
|
|
3339
2386
|
this.responseSettleIgnoreUntil = 0;
|
|
@@ -3345,37 +2392,34 @@ var init_provider_cli_adapter = __esm({
|
|
|
3345
2392
|
this.setStatus("idle", "script_idle_commit");
|
|
3346
2393
|
this.onStatusChange?.();
|
|
3347
2394
|
this.recordTrace("script_idle_commit", {
|
|
3348
|
-
messageCount:
|
|
2395
|
+
messageCount: parsedMessages.length,
|
|
3349
2396
|
lastAssistant: summarizeCliTraceText(visibleAssistant.content, 320)
|
|
3350
2397
|
});
|
|
3351
2398
|
return true;
|
|
3352
2399
|
}
|
|
3353
2400
|
commitCurrentTranscript() {
|
|
3354
2401
|
const parsed = this.parseCurrentTranscript(
|
|
3355
|
-
|
|
2402
|
+
[],
|
|
3356
2403
|
this.responseBuffer,
|
|
3357
2404
|
this.currentTurnScope
|
|
3358
2405
|
);
|
|
3359
2406
|
if (parsed && Array.isArray(parsed.messages)) {
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
scope: this.currentTurnScope,
|
|
2407
|
+
const parsedMessages = normalizeCliParsedMessages(parsed.messages, {
|
|
2408
|
+
scope: null,
|
|
3363
2409
|
lastOutputAt: this.lastOutputAt
|
|
3364
2410
|
});
|
|
3365
|
-
|
|
3366
|
-
this.syncMessageViews();
|
|
3367
|
-
const lastAssistant = [...this.committedMessages].reverse().find((message) => message.role === "assistant");
|
|
2411
|
+
const lastAssistant = [...parsedMessages].reverse().find((message) => message.role === "assistant");
|
|
3368
2412
|
if (this.currentTurnScope) {
|
|
3369
2413
|
LOG.info(
|
|
3370
2414
|
"CLI",
|
|
3371
|
-
`[${this.cliType}] commitCurrentTranscript
|
|
2415
|
+
`[${this.cliType}] commitCurrentTranscript parserMessages=${parsedMessages.length} finalLastAssistant=${JSON.stringify(summarizeCliTraceText(lastAssistant?.content || "", 220)).slice(0, 260)}`
|
|
3372
2416
|
);
|
|
3373
2417
|
}
|
|
3374
2418
|
this.recordTrace("commit_transcript", {
|
|
3375
2419
|
parsedStatus: parsed.status || null,
|
|
3376
|
-
messageCount:
|
|
2420
|
+
messageCount: parsedMessages.length,
|
|
3377
2421
|
lastAssistant: lastAssistant ? summarizeCliTraceText(lastAssistant.content, 320) : "",
|
|
3378
|
-
messages: summarizeCliTraceMessages(
|
|
2422
|
+
messages: summarizeCliTraceMessages(parsedMessages),
|
|
3379
2423
|
...buildCliTraceParseSnapshot({
|
|
3380
2424
|
accumulatedBuffer: this.accumulatedBuffer,
|
|
3381
2425
|
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
@@ -3409,63 +2453,31 @@ var init_provider_cli_adapter = __esm({
|
|
|
3409
2453
|
}
|
|
3410
2454
|
// ─── Script Execution ──────────────────────────
|
|
3411
2455
|
runParseSession() {
|
|
3412
|
-
if (typeof this.cliScripts?.parseSession
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
const tail = this.recentOutputBuffer.slice(-500);
|
|
3416
|
-
const parseBaseMessages = this.selectParseBaseMessages(this.committedMessages);
|
|
3417
|
-
const input = buildCliParseInput({
|
|
3418
|
-
accumulatedBuffer: this.accumulatedBuffer,
|
|
3419
|
-
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
3420
|
-
recentOutputBuffer: this.recentOutputBuffer,
|
|
3421
|
-
terminalScreenText: screenText,
|
|
3422
|
-
baseMessages: parseBaseMessages,
|
|
3423
|
-
partialResponse: this.responseBuffer,
|
|
3424
|
-
isWaitingForResponse: this.isWaitingForResponse,
|
|
3425
|
-
scope: this.currentTurnScope,
|
|
3426
|
-
runtimeSettings: this.runtimeSettings
|
|
3427
|
-
});
|
|
3428
|
-
const session = this.cliScripts.parseSession({ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
|
|
3429
|
-
if (session && typeof session === "object" && Array.isArray(session.messages)) {
|
|
3430
|
-
session.messages = this.stitchParsedMessagesWithCommittedBase(
|
|
3431
|
-
session.messages,
|
|
3432
|
-
this.committedMessages,
|
|
3433
|
-
parseBaseMessages
|
|
3434
|
-
);
|
|
3435
|
-
}
|
|
3436
|
-
this.parseErrorMessage = null;
|
|
3437
|
-
return session && typeof session === "object" ? session : null;
|
|
3438
|
-
} catch (e) {
|
|
3439
|
-
const message = e?.message || String(e);
|
|
3440
|
-
this.parseErrorMessage = message;
|
|
3441
|
-
LOG.warn("CLI", `[${this.cliType}] parseSession error: ${message}`);
|
|
3442
|
-
return null;
|
|
3443
|
-
}
|
|
2456
|
+
if (typeof this.cliScripts?.parseSession !== "function") {
|
|
2457
|
+
this.parseErrorMessage = `${this.cliType} parseSession unavailable`;
|
|
2458
|
+
return null;
|
|
3444
2459
|
}
|
|
3445
|
-
if (!this.cliScripts?.detectStatus && !this.cliScripts?.parseOutput) return null;
|
|
3446
2460
|
try {
|
|
3447
|
-
const
|
|
3448
|
-
const
|
|
3449
|
-
|
|
3450
|
-
this.
|
|
3451
|
-
this.
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
parsedStatus
|
|
3464
|
-
};
|
|
2461
|
+
const screenText = this.terminalScreen.getText();
|
|
2462
|
+
const tail = this.recentOutputBuffer.slice(-500);
|
|
2463
|
+
const input = buildCliParseInput({
|
|
2464
|
+
accumulatedBuffer: this.accumulatedBuffer,
|
|
2465
|
+
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
2466
|
+
recentOutputBuffer: this.recentOutputBuffer,
|
|
2467
|
+
terminalScreenText: screenText,
|
|
2468
|
+
baseMessages: [],
|
|
2469
|
+
partialResponse: this.responseBuffer,
|
|
2470
|
+
isWaitingForResponse: this.isWaitingForResponse,
|
|
2471
|
+
scope: this.currentTurnScope,
|
|
2472
|
+
runtimeSettings: this.runtimeSettings
|
|
2473
|
+
});
|
|
2474
|
+
const session = this.cliScripts.parseSession({ ...input, tail, tailScreen: buildCliScreenSnapshot(tail) });
|
|
2475
|
+
this.parseErrorMessage = null;
|
|
2476
|
+
return session && typeof session === "object" ? session : null;
|
|
3465
2477
|
} catch (e) {
|
|
3466
2478
|
const message = e?.message || String(e);
|
|
3467
2479
|
this.parseErrorMessage = message;
|
|
3468
|
-
LOG.warn("CLI", `[${this.cliType}] parseSession
|
|
2480
|
+
LOG.warn("CLI", `[${this.cliType}] parseSession error: ${message}`);
|
|
3469
2481
|
return null;
|
|
3470
2482
|
}
|
|
3471
2483
|
}
|
|
@@ -3515,45 +2527,14 @@ var init_provider_cli_adapter = __esm({
|
|
|
3515
2527
|
if (this.isWaitingForResponse && this.currentTurnScope && this.currentStatus !== "stopped") return "generating";
|
|
3516
2528
|
return this.currentStatus;
|
|
3517
2529
|
}
|
|
3518
|
-
suppressStaleParsedApproval(parsed, recentBuffer, screenText) {
|
|
3519
|
-
const actionableParsedModal = parsed?.activeModal && Array.isArray(parsed.activeModal.buttons) && parsed.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsed.activeModal : null;
|
|
3520
|
-
if (!parsed || parsed?.status !== "waiting_approval" || !actionableParsedModal) {
|
|
3521
|
-
return parsed;
|
|
3522
|
-
}
|
|
3523
|
-
const inApprovalCooldown = this.lastApprovalResolvedAt > 0 && Date.now() - this.lastApprovalResolvedAt < this.timeouts.approvalCooldown;
|
|
3524
|
-
if (!inApprovalCooldown) {
|
|
3525
|
-
return parsed;
|
|
3526
|
-
}
|
|
3527
|
-
const visibleModal = this.runParseApproval(recentBuffer);
|
|
3528
|
-
if (visibleModal) {
|
|
3529
|
-
return parsed;
|
|
3530
|
-
}
|
|
3531
|
-
const detectedStatus = this.runDetectStatus(recentBuffer);
|
|
3532
|
-
const resolvedStatus = detectedStatus && detectedStatus !== "waiting_approval" ? detectedStatus : this.isWaitingForResponse || this.currentTurnScope ? "generating" : this.currentStatus === "waiting_approval" ? "idle" : this.currentStatus;
|
|
3533
|
-
return {
|
|
3534
|
-
...parsed,
|
|
3535
|
-
status: resolvedStatus,
|
|
3536
|
-
activeModal: null
|
|
3537
|
-
};
|
|
3538
|
-
}
|
|
3539
2530
|
// ─── Public API (CliAdapter) ───────────────────
|
|
3540
2531
|
getStatus(options = {}) {
|
|
3541
2532
|
const allowParse = options.allowParse !== false;
|
|
3542
2533
|
const startupModal = allowParse && this.startupParseGate ? this.runParseApproval(this.recentOutputBuffer) : null;
|
|
3543
2534
|
let effectiveStatus = this.projectEffectiveStatus(startupModal);
|
|
3544
2535
|
let effectiveModal = startupModal || this.activeModal;
|
|
3545
|
-
if (allowParse && !startupModal && !effectiveModal
|
|
3546
|
-
|
|
3547
|
-
if (!parsed && effectiveStatus !== "idle") {
|
|
3548
|
-
const now = Date.now();
|
|
3549
|
-
if (now - this.lastStatusHotPathParseAt >= _ProviderCliAdapter.STATUS_HOT_PATH_PARSE_MIN_INTERVAL_MS) {
|
|
3550
|
-
this.lastStatusHotPathParseAt = now;
|
|
3551
|
-
try {
|
|
3552
|
-
parsed = this.getScriptParsedStatus();
|
|
3553
|
-
} catch {
|
|
3554
|
-
}
|
|
3555
|
-
}
|
|
3556
|
-
}
|
|
2536
|
+
if (allowParse && !startupModal && !effectiveModal) {
|
|
2537
|
+
const parsed = this.getFreshParsedStatusCache();
|
|
3557
2538
|
const parsedModal = parsed?.activeModal && Array.isArray(parsed.activeModal.buttons) && parsed.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsed.activeModal : null;
|
|
3558
2539
|
if (parsed?.status === "waiting_approval" && parsedModal) {
|
|
3559
2540
|
effectiveStatus = "waiting_approval";
|
|
@@ -3563,7 +2544,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
3563
2544
|
const bufferState = this.getBufferState();
|
|
3564
2545
|
return {
|
|
3565
2546
|
status: effectiveStatus,
|
|
3566
|
-
messages: [
|
|
2547
|
+
messages: [],
|
|
3567
2548
|
workingDir: this.workingDir,
|
|
3568
2549
|
activeModal: effectiveModal,
|
|
3569
2550
|
errorMessage: this.parseErrorMessage || void 0,
|
|
@@ -3571,98 +2552,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
3571
2552
|
...bufferState ? { bufferState } : {}
|
|
3572
2553
|
};
|
|
3573
2554
|
}
|
|
3574
|
-
seedCommittedMessages(messages) {
|
|
3575
|
-
const normalized = (Array.isArray(messages) ? messages : []).filter((message) => message && (message.role === "user" || message.role === "assistant")).map((message) => ({
|
|
3576
|
-
role: message.role,
|
|
3577
|
-
content: typeof message.content === "string" ? message.content : String(message.content || ""),
|
|
3578
|
-
timestamp: typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : void 0,
|
|
3579
|
-
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : void 0,
|
|
3580
|
-
kind: typeof message.kind === "string" ? message.kind : void 0,
|
|
3581
|
-
id: typeof message.id === "string" ? message.id : void 0,
|
|
3582
|
-
index: typeof message.index === "number" ? message.index : void 0,
|
|
3583
|
-
providerUnitKey: typeof message.providerUnitKey === "string" ? message.providerUnitKey : void 0,
|
|
3584
|
-
bubbleId: typeof message.bubbleId === "string" ? message.bubbleId : void 0,
|
|
3585
|
-
bubbleState: typeof message.bubbleState === "string" ? message.bubbleState : void 0,
|
|
3586
|
-
_turnKey: typeof message._turnKey === "string" ? message._turnKey : void 0,
|
|
3587
|
-
meta: message.meta && typeof message.meta === "object" ? { ...message.meta } : void 0,
|
|
3588
|
-
senderName: typeof message.senderName === "string" ? message.senderName : void 0
|
|
3589
|
-
}));
|
|
3590
|
-
this.committedMessages = normalized;
|
|
3591
|
-
this.syncMessageViews();
|
|
3592
|
-
}
|
|
3593
|
-
getSharedCommittedPrefixLength(parsedMessages) {
|
|
3594
|
-
const committedMessages = this.committedMessages;
|
|
3595
|
-
const max = Math.min(parsedMessages.length, committedMessages.length);
|
|
3596
|
-
let index = 0;
|
|
3597
|
-
while (index < max && this.messagesShareStableIdentity(parsedMessages[index], committedMessages[index])) {
|
|
3598
|
-
index += 1;
|
|
3599
|
-
}
|
|
3600
|
-
return index;
|
|
3601
|
-
}
|
|
3602
|
-
hydrateCommittedPrefixForParsedStatus(parsedMessages) {
|
|
3603
|
-
const sharedPrefixLength = this.getSharedCommittedPrefixLength(parsedMessages);
|
|
3604
|
-
if (sharedPrefixLength !== this.committedMessages.length) return null;
|
|
3605
|
-
const committedHydratedMessages = this.committedMessages.map((message, index) => {
|
|
3606
|
-
const timestamp = typeof message.timestamp === "number" && Number.isFinite(message.timestamp) ? message.timestamp : this.lastOutputAt || this.currentTurnScope?.startedAt || Date.now();
|
|
3607
|
-
const contentValue = message.content;
|
|
3608
|
-
return {
|
|
3609
|
-
role: message.role,
|
|
3610
|
-
content: typeof contentValue === "string" ? contentValue : String(contentValue || ""),
|
|
3611
|
-
timestamp,
|
|
3612
|
-
receivedAt: typeof message.receivedAt === "number" && Number.isFinite(message.receivedAt) ? message.receivedAt : timestamp,
|
|
3613
|
-
kind: message.kind,
|
|
3614
|
-
id: message.id || `msg_${index}`,
|
|
3615
|
-
index: typeof message.index === "number" ? message.index : index,
|
|
3616
|
-
providerUnitKey: message.providerUnitKey,
|
|
3617
|
-
bubbleId: message.bubbleId,
|
|
3618
|
-
bubbleState: message.bubbleState,
|
|
3619
|
-
_turnKey: message._turnKey,
|
|
3620
|
-
meta: message.meta,
|
|
3621
|
-
senderName: message.senderName
|
|
3622
|
-
};
|
|
3623
|
-
});
|
|
3624
|
-
const extraMessages = parsedMessages.slice(sharedPrefixLength);
|
|
3625
|
-
if (extraMessages.length === 0) return committedHydratedMessages;
|
|
3626
|
-
const extraHydratedMessages = hydrateCliParsedMessages(extraMessages, {
|
|
3627
|
-
committedMessages: [],
|
|
3628
|
-
scope: this.currentTurnScope,
|
|
3629
|
-
lastOutputAt: this.lastOutputAt
|
|
3630
|
-
}).map((message, offset) => ({
|
|
3631
|
-
...message,
|
|
3632
|
-
id: message.id || `msg_${sharedPrefixLength + offset}`,
|
|
3633
|
-
index: typeof message.index === "number" ? message.index : sharedPrefixLength + offset
|
|
3634
|
-
}));
|
|
3635
|
-
return [...committedHydratedMessages, ...extraHydratedMessages];
|
|
3636
|
-
}
|
|
3637
|
-
hydrateParsedMessagesForStatus(parsedMessages) {
|
|
3638
|
-
return this.hydrateCommittedPrefixForParsedStatus(parsedMessages) || hydrateCliParsedMessages(parsedMessages, {
|
|
3639
|
-
committedMessages: this.committedMessages,
|
|
3640
|
-
scope: this.currentTurnScope,
|
|
3641
|
-
lastOutputAt: this.lastOutputAt
|
|
3642
|
-
});
|
|
3643
|
-
}
|
|
3644
|
-
buildCommittedChatMessages() {
|
|
3645
|
-
return this.committedMessages.map((message, index) => {
|
|
3646
|
-
const rawContentValue = message.content;
|
|
3647
|
-
const rawContent = typeof rawContentValue === "string" ? rawContentValue : String(rawContentValue || "");
|
|
3648
|
-
const content = message.role === "assistant" && (message.kind || "standard") === "standard" ? sanitizeCliStandardMessageContent(rawContent) : rawContent;
|
|
3649
|
-
return buildChatMessage({
|
|
3650
|
-
role: message.role,
|
|
3651
|
-
content,
|
|
3652
|
-
timestamp: message.timestamp,
|
|
3653
|
-
kind: message.kind,
|
|
3654
|
-
meta: message.meta,
|
|
3655
|
-
senderName: message.senderName,
|
|
3656
|
-
id: message.id || `msg_${index}`,
|
|
3657
|
-
index: typeof message.index === "number" ? message.index : index,
|
|
3658
|
-
providerUnitKey: message.providerUnitKey,
|
|
3659
|
-
bubbleId: message.bubbleId,
|
|
3660
|
-
bubbleState: message.bubbleState,
|
|
3661
|
-
_turnKey: message._turnKey,
|
|
3662
|
-
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
3663
|
-
});
|
|
3664
|
-
});
|
|
3665
|
-
}
|
|
3666
2555
|
/**
|
|
3667
2556
|
* Script-based full parse — returns ReadChatResult.
|
|
3668
2557
|
* Called by command handler / dashboard for rich content rendering.
|
|
@@ -3670,125 +2559,30 @@ var init_provider_cli_adapter = __esm({
|
|
|
3670
2559
|
getScriptParsedStatus() {
|
|
3671
2560
|
const screenText = this.readTerminalScreenText();
|
|
3672
2561
|
const cached = this.parsedStatusCache;
|
|
3673
|
-
if (cached && cached.
|
|
2562
|
+
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) {
|
|
3674
2563
|
return cached.result;
|
|
3675
2564
|
}
|
|
3676
|
-
const parsed = this.
|
|
3677
|
-
|
|
3678
|
-
this.
|
|
3679
|
-
this.currentTurnScope,
|
|
3680
|
-
screenText
|
|
3681
|
-
);
|
|
3682
|
-
const parsedModal = parsed?.activeModal && Array.isArray(parsed.activeModal.buttons) && parsed.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsed.activeModal : null;
|
|
3683
|
-
if (parsedModal && parsed?.status === "waiting_approval") {
|
|
3684
|
-
this.activeModal = parsedModal;
|
|
3685
|
-
this.isWaitingForResponse = true;
|
|
3686
|
-
if (this.currentStatus !== "waiting_approval") {
|
|
3687
|
-
this.setStatus("waiting_approval", "parsed_waiting_approval");
|
|
3688
|
-
this.onStatusChange?.();
|
|
3689
|
-
}
|
|
2565
|
+
const parsed = this.runParseSession();
|
|
2566
|
+
if (!parsed || !Array.isArray(parsed.messages)) {
|
|
2567
|
+
throw new Error(this.parseErrorMessage || `${this.cliType} parseSession did not return messages`);
|
|
3690
2568
|
}
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
2569
|
+
const activeModal = parsed.activeModal ?? parsed.modal ?? null;
|
|
2570
|
+
const bufferState = this.getBufferState();
|
|
2571
|
+
const result = {
|
|
2572
|
+
id: parsed.id || "cli_session",
|
|
2573
|
+
status: parsed.status || this.currentStatus,
|
|
2574
|
+
title: parsed.title || this.cliName,
|
|
2575
|
+
messages: normalizeCliParsedMessages(parsed.messages, {
|
|
2576
|
+
scope: null,
|
|
3695
2577
|
lastOutputAt: this.lastOutputAt
|
|
3696
|
-
})
|
|
3697
|
-
|
|
3698
|
-
|
|
3699
|
-
|
|
3700
|
-
|
|
3701
|
-
|
|
3702
|
-
|
|
3703
|
-
if (this.maybeCommitVisibleIdleTranscript(fakeSession, hydratedForCommit)) {
|
|
3704
|
-
return this.getScriptParsedStatus();
|
|
3705
|
-
}
|
|
3706
|
-
}
|
|
3707
|
-
const shouldPreferCommittedMessages = !this.currentTurnScope && !this.activeModal && this.currentStatus === "idle";
|
|
3708
|
-
let result;
|
|
3709
|
-
if (parsed && Array.isArray(parsed.messages)) {
|
|
3710
|
-
const parsedHydratedMessages = this.hydrateParsedMessagesForStatus(parsed.messages);
|
|
3711
|
-
const parsedLastAssistant = [...parsedHydratedMessages].reverse().find((message) => message.role === "assistant" && typeof message.content === "string" && message.content.trim());
|
|
3712
|
-
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");
|
|
3713
|
-
if (shouldAdoptParsedIdleReplay) {
|
|
3714
|
-
this.committedMessages = this.getSharedCommittedPrefixLength(parsed.messages) === this.committedMessages.length ? parsedHydratedMessages.map((message) => ({
|
|
3715
|
-
role: message.role,
|
|
3716
|
-
content: typeof message.content === "string" ? message.content : String(message.content || ""),
|
|
3717
|
-
timestamp: message.timestamp,
|
|
3718
|
-
receivedAt: message.receivedAt,
|
|
3719
|
-
kind: message.kind,
|
|
3720
|
-
id: message.id,
|
|
3721
|
-
index: message.index,
|
|
3722
|
-
meta: message.meta,
|
|
3723
|
-
senderName: message.senderName
|
|
3724
|
-
})) : normalizeCliParsedMessages(parsed.messages, {
|
|
3725
|
-
committedMessages: this.committedMessages,
|
|
3726
|
-
scope: this.currentTurnScope,
|
|
3727
|
-
lastOutputAt: this.lastOutputAt
|
|
3728
|
-
});
|
|
3729
|
-
this.syncMessageViews();
|
|
3730
|
-
if (this.currentStatus !== "idle" || this.isWaitingForResponse) {
|
|
3731
|
-
this.responseBuffer = "";
|
|
3732
|
-
this.isWaitingForResponse = false;
|
|
3733
|
-
this.responseSettleIgnoreUntil = 0;
|
|
3734
|
-
this.submitRetryUsed = false;
|
|
3735
|
-
this.submitRetryPromptSnippet = "";
|
|
3736
|
-
this.finishRetryCount = 0;
|
|
3737
|
-
this.currentTurnScope = null;
|
|
3738
|
-
this.activeModal = null;
|
|
3739
|
-
this.setStatus("idle", "parsed_idle_replay_commit");
|
|
3740
|
-
this.onStatusChange?.();
|
|
3741
|
-
}
|
|
3742
|
-
}
|
|
3743
|
-
const shouldPreferCommittedHistoryReplay = !this.currentTurnScope && !this.activeModal && this.committedMessages.length > parsedHydratedMessages.length;
|
|
3744
|
-
const shouldPreferCommittedIdleReplay = shouldPreferCommittedMessages && !shouldAdoptParsedIdleReplay;
|
|
3745
|
-
const hydratedMessages = shouldPreferCommittedIdleReplay || shouldPreferCommittedHistoryReplay ? this.buildCommittedChatMessages() : parsedHydratedMessages;
|
|
3746
|
-
result = {
|
|
3747
|
-
id: parsed.id || "cli_session",
|
|
3748
|
-
status: parsed.status || this.currentStatus,
|
|
3749
|
-
title: parsed.title || this.cliName,
|
|
3750
|
-
messages: hydratedMessages,
|
|
3751
|
-
activeModal: parsed.activeModal ?? this.activeModal,
|
|
3752
|
-
providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0,
|
|
3753
|
-
...this.getBufferState() ? { bufferState: this.getBufferState() } : {},
|
|
3754
|
-
...this.providerOwnsTranscript() ? { transcriptAuthority: "provider", coverage: this.shouldUseFullProviderTranscriptContext() ? "full" : "tail" } : {}
|
|
3755
|
-
};
|
|
3756
|
-
} else {
|
|
3757
|
-
const messages = [...this.committedMessages];
|
|
3758
|
-
const bufferState = this.getBufferState();
|
|
3759
|
-
result = {
|
|
3760
|
-
id: "cli_session",
|
|
3761
|
-
status: this.currentStatus,
|
|
3762
|
-
title: this.cliName,
|
|
3763
|
-
messages: messages.map((message, index) => buildChatMessage({
|
|
3764
|
-
...message,
|
|
3765
|
-
id: message.id || `msg_${index}`,
|
|
3766
|
-
index: typeof message.index === "number" ? message.index : index,
|
|
3767
|
-
receivedAt: typeof message.receivedAt === "number" ? message.receivedAt : message.timestamp
|
|
3768
|
-
})),
|
|
3769
|
-
activeModal: this.activeModal,
|
|
3770
|
-
...bufferState ? { bufferState } : {}
|
|
3771
|
-
};
|
|
3772
|
-
}
|
|
3773
|
-
const hasVisibleAssistantMessage = Array.isArray(result?.messages) && result.messages.some((message) => message?.role === "assistant" && typeof message?.content === "string" && message.content.trim());
|
|
3774
|
-
const shouldClampStaleGeneratingToIdle = result?.status === "generating" && this.currentStatus === "idle" && !this.currentTurnScope && !result?.activeModal && hasVisibleAssistantMessage && !hasVisibleInterruptPrompt(screenText);
|
|
3775
|
-
if (shouldClampStaleGeneratingToIdle) {
|
|
3776
|
-
result = {
|
|
3777
|
-
...result,
|
|
3778
|
-
status: "idle",
|
|
3779
|
-
messages: Array.isArray(result.messages) ? result.messages.map((message) => {
|
|
3780
|
-
if (message?.role !== "assistant" || !message?.meta?.streaming) return message;
|
|
3781
|
-
const nextMeta = { ...message.meta || {} };
|
|
3782
|
-
delete nextMeta.streaming;
|
|
3783
|
-
return {
|
|
3784
|
-
...message,
|
|
3785
|
-
...Object.keys(nextMeta).length > 0 ? { meta: nextMeta } : { meta: void 0 }
|
|
3786
|
-
};
|
|
3787
|
-
}) : result.messages
|
|
3788
|
-
};
|
|
3789
|
-
}
|
|
2578
|
+
}),
|
|
2579
|
+
activeModal,
|
|
2580
|
+
providerSessionId: typeof parsed.providerSessionId === "string" ? parsed.providerSessionId : void 0,
|
|
2581
|
+
...bufferState ? { bufferState } : {},
|
|
2582
|
+
...parsed.transcriptAuthority === "provider" || parsed.transcriptAuthority === "daemon" ? { transcriptAuthority: parsed.transcriptAuthority } : this.providerOwnsTranscript() ? { transcriptAuthority: "provider" } : {},
|
|
2583
|
+
...parsed.coverage === "full" || parsed.coverage === "tail" || parsed.coverage === "current-turn" ? { coverage: parsed.coverage } : this.providerOwnsTranscript() ? { coverage: this.shouldUseFullProviderTranscriptContext() ? "full" : "tail" } : {}
|
|
2584
|
+
};
|
|
3790
2585
|
this.parsedStatusCache = {
|
|
3791
|
-
committedMessagesRef: this.committedMessages,
|
|
3792
2586
|
responseBuffer: this.responseBuffer,
|
|
3793
2587
|
currentTurnScope: this.currentTurnScope,
|
|
3794
2588
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
@@ -3811,7 +2605,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
3811
2605
|
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
3812
2606
|
recentOutputBuffer: this.recentOutputBuffer,
|
|
3813
2607
|
terminalScreenText: this.terminalScreen.getText(),
|
|
3814
|
-
baseMessages:
|
|
2608
|
+
baseMessages: [],
|
|
3815
2609
|
partialResponse: this.responseBuffer,
|
|
3816
2610
|
isWaitingForResponse: this.isWaitingForResponse,
|
|
3817
2611
|
scope: this.currentTurnScope,
|
|
@@ -3822,46 +2616,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
3822
2616
|
args: args && typeof args === "object" ? { ...args } : {}
|
|
3823
2617
|
}));
|
|
3824
2618
|
}
|
|
3825
|
-
parseCurrentTranscript(
|
|
3826
|
-
|
|
3827
|
-
this.parseErrorMessage = null;
|
|
3828
|
-
return null;
|
|
3829
|
-
}
|
|
3830
|
-
try {
|
|
3831
|
-
const screenText = typeof screenTextOverride === "string" ? screenTextOverride : this.terminalScreen.getText();
|
|
3832
|
-
const parseBaseMessages = this.selectParseBaseMessages(baseMessages);
|
|
3833
|
-
const input = buildCliParseInput({
|
|
3834
|
-
accumulatedBuffer: this.accumulatedBuffer,
|
|
3835
|
-
accumulatedRawBuffer: this.accumulatedRawBuffer,
|
|
3836
|
-
recentOutputBuffer: this.recentOutputBuffer,
|
|
3837
|
-
terminalScreenText: screenText,
|
|
3838
|
-
baseMessages: parseBaseMessages,
|
|
3839
|
-
partialResponse,
|
|
3840
|
-
isWaitingForResponse: this.isWaitingForResponse,
|
|
3841
|
-
scope,
|
|
3842
|
-
runtimeSettings: this.runtimeSettings
|
|
3843
|
-
});
|
|
3844
|
-
const parsed = this.cliScripts.parseOutput(input);
|
|
3845
|
-
if (parsed && typeof parsed === "object") {
|
|
3846
|
-
Object.assign(parsed, validateReadChatResultPayload(parsed, `${this.cliType} parseOutput`));
|
|
3847
|
-
}
|
|
3848
|
-
const normalizedParsed = this.suppressStaleParsedApproval(parsed, input.recentBuffer, input.screenText);
|
|
3849
|
-
if (normalizedParsed && Array.isArray(normalizedParsed.messages)) {
|
|
3850
|
-
normalizedParsed.messages = this.stitchParsedMessagesWithCommittedBase(
|
|
3851
|
-
normalizedParsed.messages,
|
|
3852
|
-
baseMessages,
|
|
3853
|
-
parseBaseMessages
|
|
3854
|
-
);
|
|
3855
|
-
this.trimLastAssistantEcho(normalizedParsed.messages, scope?.prompt || getLastUserPromptText(baseMessages));
|
|
3856
|
-
}
|
|
3857
|
-
this.parseErrorMessage = null;
|
|
3858
|
-
return normalizedParsed;
|
|
3859
|
-
} catch (e) {
|
|
3860
|
-
const message = e?.message || String(e);
|
|
3861
|
-
this.parseErrorMessage = message;
|
|
3862
|
-
LOG.warn("CLI", `[${this.cliType}] parseOutput error: ${message}`);
|
|
3863
|
-
throw e;
|
|
3864
|
-
}
|
|
2619
|
+
parseCurrentTranscript(_baseMessages, _partialResponse, _scope, _screenTextOverride) {
|
|
2620
|
+
return this.runParseSession();
|
|
3865
2621
|
}
|
|
3866
2622
|
/** Whether this adapter has CLI scripts loaded */
|
|
3867
2623
|
hasCliScripts() {
|
|
@@ -3923,8 +2679,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
3923
2679
|
commitSendUserTurn(state) {
|
|
3924
2680
|
if (state.didCommitUserTurn) return;
|
|
3925
2681
|
state.didCommitUserTurn = true;
|
|
3926
|
-
this.committedMessages.push({ role: "user", content: state.text, timestamp: Date.now() });
|
|
3927
|
-
this.syncMessageViews();
|
|
3928
2682
|
}
|
|
3929
2683
|
armResponseTimeout() {
|
|
3930
2684
|
if (this.responseTimeout) clearTimeout(this.responseTimeout);
|
|
@@ -4116,11 +2870,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
4116
2870
|
}
|
|
4117
2871
|
})() : null;
|
|
4118
2872
|
const parsedSessionStatus = typeof parsedStatusBeforeSend?.status === "string" ? String(parsedStatusBeforeSend.status) : "";
|
|
4119
|
-
const parsedMessagesBeforeSend = Array.isArray(parsedStatusBeforeSend?.messages) ? parsedStatusBeforeSend.messages.filter((message) => message && (message.role === "user" || message.role === "assistant")) : [];
|
|
4120
|
-
const shouldCommitParsedIdleBeforeSend = !allowInputDuringGeneration && parsedSessionStatus === "idle" && parsedMessagesBeforeSend.length > this.committedMessages.length && parsedMessagesBeforeSend.some((message) => message?.role === "assistant" && typeof message?.content === "string" && message.content.trim());
|
|
4121
|
-
if (shouldCommitParsedIdleBeforeSend) {
|
|
4122
|
-
this.commitCurrentTranscript();
|
|
4123
|
-
}
|
|
4124
2873
|
if (!allowInputDuringGeneration && (parsedSessionStatus === "generating" || parsedSessionStatus === "long_generating")) {
|
|
4125
2874
|
throw new Error(`${this.cliName} is still processing the previous prompt`);
|
|
4126
2875
|
}
|
|
@@ -4226,9 +2975,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
4226
2975
|
activeModal: this.activeModal,
|
|
4227
2976
|
parseErrorMessage: this.parseErrorMessage,
|
|
4228
2977
|
messageCounts: {
|
|
4229
|
-
committed: this.committedMessages.length,
|
|
4230
|
-
structured: this.structuredMessages.length,
|
|
4231
|
-
visible: this.messages.length,
|
|
4232
2978
|
parsedCache: Array.isArray(parsedResult?.messages) ? parsedResult.messages.length : void 0
|
|
4233
2979
|
},
|
|
4234
2980
|
buffers: {
|
|
@@ -4279,8 +3025,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
4279
3025
|
responseSettleIgnoreUntil: this.responseSettleIgnoreUntil,
|
|
4280
3026
|
responseEpoch: this.responseEpoch,
|
|
4281
3027
|
resizeSuppressUntil: this.resizeSuppressUntil,
|
|
4282
|
-
lastApprovalResolvedAt: this.lastApprovalResolvedAt
|
|
4283
|
-
committedMessagesChangedAt: this.committedMessagesChangedAt
|
|
3028
|
+
lastApprovalResolvedAt: this.lastApprovalResolvedAt
|
|
4284
3029
|
},
|
|
4285
3030
|
finish: {
|
|
4286
3031
|
idleFinishCandidate: this.idleFinishCandidate,
|
|
@@ -4405,8 +3150,6 @@ var init_provider_cli_adapter = __esm({
|
|
|
4405
3150
|
}
|
|
4406
3151
|
clearHistory() {
|
|
4407
3152
|
this.clearIdleFinishCandidate("clear_history");
|
|
4408
|
-
this.committedMessages = [];
|
|
4409
|
-
this.syncMessageViews();
|
|
4410
3153
|
this.accumulatedBuffer = "";
|
|
4411
3154
|
this.accumulatedRawBuffer = "";
|
|
4412
3155
|
this.currentTurnScope = null;
|
|
@@ -4447,7 +3190,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
4447
3190
|
}
|
|
4448
3191
|
resolveModal(buttonIndex) {
|
|
4449
3192
|
let modal = this.activeModal || this.runParseApproval(this.recentOutputBuffer);
|
|
4450
|
-
if (!modal && typeof this.cliScripts?.
|
|
3193
|
+
if (!modal && typeof this.cliScripts?.parseSession === "function") {
|
|
4451
3194
|
try {
|
|
4452
3195
|
const parsed = this.getScriptParsedStatus();
|
|
4453
3196
|
const parsedModal = parsed?.activeModal && Array.isArray(parsed.activeModal.buttons) && parsed.activeModal.buttons.some((button) => typeof button === "string" && button.trim()) ? parsed.activeModal : null;
|
|
@@ -4514,10 +3257,8 @@ var init_provider_cli_adapter = __esm({
|
|
|
4514
3257
|
startupParseGate: this.startupParseGate,
|
|
4515
3258
|
spawnAt: this.spawnAt,
|
|
4516
3259
|
workingDir: this.workingDir,
|
|
4517
|
-
messages:
|
|
4518
|
-
|
|
4519
|
-
structuredMessages: this.structuredMessages,
|
|
4520
|
-
messageCount: this.committedMessages.length,
|
|
3260
|
+
messages: [],
|
|
3261
|
+
messageCount: 0,
|
|
4521
3262
|
screenText: screenText.slice(-4e3),
|
|
4522
3263
|
currentTurnScope: this.currentTurnScope,
|
|
4523
3264
|
startupBuffer: this.startupBuffer.slice(-4e3),
|
|
@@ -4569,7 +3310,7 @@ var init_provider_cli_adapter = __esm({
|
|
|
4569
3310
|
lifecycleStatus: this.isWaitingForResponse ? "awaiting_response" : "idle",
|
|
4570
3311
|
activeModal: this.activeModal,
|
|
4571
3312
|
currentTurnScope: this.currentTurnScope,
|
|
4572
|
-
messages:
|
|
3313
|
+
messages: []
|
|
4573
3314
|
};
|
|
4574
3315
|
}
|
|
4575
3316
|
getProviderResolutionMeta() {
|
|
@@ -8182,14 +6923,223 @@ var CdpDomHandlers = class {
|
|
|
8182
6923
|
return { success: false, error: e.message };
|
|
8183
6924
|
}
|
|
8184
6925
|
}
|
|
8185
|
-
};
|
|
8186
|
-
|
|
8187
|
-
// src/providers/ide-provider-instance.ts
|
|
8188
|
-
|
|
8189
|
-
|
|
6926
|
+
};
|
|
6927
|
+
|
|
6928
|
+
// src/providers/ide-provider-instance.ts
|
|
6929
|
+
import * as crypto2 from "crypto";
|
|
6930
|
+
|
|
6931
|
+
// src/providers/io-contracts.ts
|
|
6932
|
+
function normalizeInputEnvelope(input) {
|
|
6933
|
+
const normalized = normalizeInputEnvelopePayload(input);
|
|
6934
|
+
const textFallback = normalized.textFallback ?? flattenInputParts(normalized.parts);
|
|
6935
|
+
return {
|
|
6936
|
+
parts: normalized.parts,
|
|
6937
|
+
textFallback,
|
|
6938
|
+
...normalized.metadata ? { metadata: normalized.metadata } : {}
|
|
6939
|
+
};
|
|
6940
|
+
}
|
|
6941
|
+
function normalizeMessageParts(content) {
|
|
6942
|
+
if (typeof content === "string") return [{ type: "text", text: content }];
|
|
6943
|
+
if (!Array.isArray(content)) {
|
|
6944
|
+
if (content && typeof content === "object" && typeof content.text === "string") {
|
|
6945
|
+
return [{ type: "text", text: String(content.text) }];
|
|
6946
|
+
}
|
|
6947
|
+
return [];
|
|
6948
|
+
}
|
|
6949
|
+
const parts = [];
|
|
6950
|
+
for (const raw of content) {
|
|
6951
|
+
if (typeof raw === "string") {
|
|
6952
|
+
parts.push({ type: "text", text: raw });
|
|
6953
|
+
continue;
|
|
6954
|
+
}
|
|
6955
|
+
if (!raw || typeof raw !== "object") continue;
|
|
6956
|
+
const part = normalizeMessagePartObject(raw);
|
|
6957
|
+
if (part) parts.push(part);
|
|
6958
|
+
}
|
|
6959
|
+
return parts;
|
|
6960
|
+
}
|
|
6961
|
+
function flattenMessageParts(parts) {
|
|
6962
|
+
return parts.map((part) => {
|
|
6963
|
+
if (part.type === "text") return part.text;
|
|
6964
|
+
if (part.type === "resource") return part.resource.text || "";
|
|
6965
|
+
return "";
|
|
6966
|
+
}).filter((value) => value.length > 0).join("\n");
|
|
6967
|
+
}
|
|
6968
|
+
function normalizeInputEnvelopePayload(input) {
|
|
6969
|
+
if (typeof input === "string") {
|
|
6970
|
+
return { parts: [{ type: "text", text: input }], textFallback: input };
|
|
6971
|
+
}
|
|
6972
|
+
if (!input || typeof input !== "object") {
|
|
6973
|
+
return { parts: [], textFallback: "" };
|
|
6974
|
+
}
|
|
6975
|
+
const record = input;
|
|
6976
|
+
const nestedInput = record.input;
|
|
6977
|
+
if (nestedInput && typeof nestedInput === "object") {
|
|
6978
|
+
const nested = nestedInput;
|
|
6979
|
+
return {
|
|
6980
|
+
parts: normalizeInputParts(nested.parts ?? nested.prompt),
|
|
6981
|
+
textFallback: typeof nested.textFallback === "string" ? nested.textFallback : void 0,
|
|
6982
|
+
metadata: normalizeInputMetadata(nested.metadata)
|
|
6983
|
+
};
|
|
6984
|
+
}
|
|
6985
|
+
const directText = typeof record.text === "string" ? record.text : typeof record.message === "string" ? record.message : void 0;
|
|
6986
|
+
if (directText !== void 0) {
|
|
6987
|
+
return { parts: [{ type: "text", text: directText }], textFallback: directText };
|
|
6988
|
+
}
|
|
6989
|
+
const directParts = normalizeInputParts(record.parts ?? record.prompt);
|
|
6990
|
+
return {
|
|
6991
|
+
parts: directParts,
|
|
6992
|
+
textFallback: typeof record.textFallback === "string" ? record.textFallback : void 0,
|
|
6993
|
+
metadata: normalizeInputMetadata(record.metadata)
|
|
6994
|
+
};
|
|
6995
|
+
}
|
|
6996
|
+
function normalizeInputMetadata(value) {
|
|
6997
|
+
if (!value || typeof value !== "object") return void 0;
|
|
6998
|
+
const record = value;
|
|
6999
|
+
const metadata = {};
|
|
7000
|
+
if (record.source === "dashboard" || record.source === "shortcut_api" || record.source === "provider_script" || record.source === "session_replay") {
|
|
7001
|
+
metadata.source = record.source;
|
|
7002
|
+
}
|
|
7003
|
+
if (typeof record.clientTimestamp === "number" && Number.isFinite(record.clientTimestamp)) {
|
|
7004
|
+
metadata.clientTimestamp = record.clientTimestamp;
|
|
7005
|
+
}
|
|
7006
|
+
return Object.keys(metadata).length > 0 ? metadata : void 0;
|
|
7007
|
+
}
|
|
7008
|
+
function normalizeInputParts(value) {
|
|
7009
|
+
if (!Array.isArray(value)) return [];
|
|
7010
|
+
const parts = [];
|
|
7011
|
+
for (const raw of value) {
|
|
7012
|
+
if (typeof raw === "string") {
|
|
7013
|
+
parts.push({ type: "text", text: raw });
|
|
7014
|
+
continue;
|
|
7015
|
+
}
|
|
7016
|
+
if (!raw || typeof raw !== "object") continue;
|
|
7017
|
+
const part = normalizeInputPartObject(raw);
|
|
7018
|
+
if (part) parts.push(part);
|
|
7019
|
+
}
|
|
7020
|
+
return parts;
|
|
7021
|
+
}
|
|
7022
|
+
function normalizeInputPartObject(raw) {
|
|
7023
|
+
const type = raw.type;
|
|
7024
|
+
if (type === "text" && typeof raw.text === "string") {
|
|
7025
|
+
return { type, text: raw.text };
|
|
7026
|
+
}
|
|
7027
|
+
if (type === "image" && typeof raw.mimeType === "string") {
|
|
7028
|
+
return {
|
|
7029
|
+
type,
|
|
7030
|
+
mimeType: raw.mimeType,
|
|
7031
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7032
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7033
|
+
...typeof raw.alt === "string" ? { alt: raw.alt } : {}
|
|
7034
|
+
};
|
|
7035
|
+
}
|
|
7036
|
+
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
7037
|
+
return {
|
|
7038
|
+
type,
|
|
7039
|
+
mimeType: raw.mimeType,
|
|
7040
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7041
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7042
|
+
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
|
|
7043
|
+
};
|
|
7044
|
+
}
|
|
7045
|
+
if (type === "video" && typeof raw.mimeType === "string") {
|
|
7046
|
+
return {
|
|
7047
|
+
type,
|
|
7048
|
+
mimeType: raw.mimeType,
|
|
7049
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7050
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7051
|
+
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
7052
|
+
};
|
|
7053
|
+
}
|
|
7054
|
+
if (type === "resource" && typeof raw.uri === "string") {
|
|
7055
|
+
return {
|
|
7056
|
+
type,
|
|
7057
|
+
uri: raw.uri,
|
|
7058
|
+
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7059
|
+
...typeof raw.name === "string" ? { name: raw.name } : {},
|
|
7060
|
+
...typeof raw.text === "string" ? { text: raw.text } : {},
|
|
7061
|
+
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
7062
|
+
};
|
|
7063
|
+
}
|
|
7064
|
+
if (type === "resource_link" && typeof raw.uri === "string") {
|
|
7065
|
+
return {
|
|
7066
|
+
type: "resource",
|
|
7067
|
+
uri: raw.uri,
|
|
7068
|
+
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7069
|
+
...typeof raw.name === "string" ? { name: raw.name } : {}
|
|
7070
|
+
};
|
|
7071
|
+
}
|
|
7072
|
+
return null;
|
|
7073
|
+
}
|
|
7074
|
+
function normalizeMessagePartObject(raw) {
|
|
7075
|
+
const type = raw.type;
|
|
7076
|
+
if (type === "text" && typeof raw.text === "string") {
|
|
7077
|
+
return { type, text: raw.text };
|
|
7078
|
+
}
|
|
7079
|
+
if (type === "image" && typeof raw.mimeType === "string") {
|
|
7080
|
+
return {
|
|
7081
|
+
type,
|
|
7082
|
+
mimeType: raw.mimeType,
|
|
7083
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7084
|
+
...typeof raw.data === "string" ? { data: raw.data } : {}
|
|
7085
|
+
};
|
|
7086
|
+
}
|
|
7087
|
+
if (type === "audio" && typeof raw.mimeType === "string") {
|
|
7088
|
+
return {
|
|
7089
|
+
type,
|
|
7090
|
+
mimeType: raw.mimeType,
|
|
7091
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7092
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7093
|
+
...typeof raw.transcript === "string" ? { transcript: raw.transcript } : {}
|
|
7094
|
+
};
|
|
7095
|
+
}
|
|
7096
|
+
if (type === "video" && typeof raw.mimeType === "string") {
|
|
7097
|
+
return {
|
|
7098
|
+
type,
|
|
7099
|
+
mimeType: raw.mimeType,
|
|
7100
|
+
...typeof raw.uri === "string" ? { uri: raw.uri } : {},
|
|
7101
|
+
...typeof raw.data === "string" ? { data: raw.data } : {},
|
|
7102
|
+
...typeof raw.posterUri === "string" ? { posterUri: raw.posterUri } : {}
|
|
7103
|
+
};
|
|
7104
|
+
}
|
|
7105
|
+
if (type === "resource_link" && typeof raw.uri === "string" && typeof raw.name === "string") {
|
|
7106
|
+
return {
|
|
7107
|
+
type,
|
|
7108
|
+
uri: raw.uri,
|
|
7109
|
+
name: raw.name,
|
|
7110
|
+
...typeof raw.mimeType === "string" ? { mimeType: raw.mimeType } : {},
|
|
7111
|
+
...typeof raw.size === "number" ? { size: raw.size } : {}
|
|
7112
|
+
};
|
|
7113
|
+
}
|
|
7114
|
+
if (type === "resource" && raw.resource && typeof raw.resource === "object") {
|
|
7115
|
+
const resource = raw.resource;
|
|
7116
|
+
if (typeof resource.uri !== "string") return null;
|
|
7117
|
+
return {
|
|
7118
|
+
type,
|
|
7119
|
+
resource: {
|
|
7120
|
+
uri: resource.uri,
|
|
7121
|
+
...typeof resource.mimeType === "string" || resource.mimeType === null ? { mimeType: resource.mimeType } : {},
|
|
7122
|
+
...typeof resource.text === "string" ? { text: resource.text } : {},
|
|
7123
|
+
...typeof resource.blob === "string" ? { blob: resource.blob } : {}
|
|
7124
|
+
}
|
|
7125
|
+
};
|
|
7126
|
+
}
|
|
7127
|
+
return null;
|
|
7128
|
+
}
|
|
7129
|
+
function flattenInputParts(parts) {
|
|
7130
|
+
return parts.map((part) => {
|
|
7131
|
+
if (part.type === "text") return part.text;
|
|
7132
|
+
if (part.type === "audio") return part.transcript || "";
|
|
7133
|
+
if (part.type === "resource") return part.text || "";
|
|
7134
|
+
return "";
|
|
7135
|
+
}).filter((value) => value.length > 0).join("\n");
|
|
7136
|
+
}
|
|
8190
7137
|
|
|
8191
|
-
// src/providers/
|
|
8192
|
-
|
|
7138
|
+
// src/providers/contracts.ts
|
|
7139
|
+
function flattenContent(content) {
|
|
7140
|
+
if (typeof content === "string") return content;
|
|
7141
|
+
return flattenMessageParts(normalizeMessageParts(content));
|
|
7142
|
+
}
|
|
8193
7143
|
|
|
8194
7144
|
// src/providers/status-monitor.ts
|
|
8195
7145
|
var DEFAULT_MONITOR_CONFIG = {
|
|
@@ -8303,9 +7253,151 @@ var StatusMonitor = class {
|
|
|
8303
7253
|
}
|
|
8304
7254
|
};
|
|
8305
7255
|
|
|
7256
|
+
// src/providers/chat-message-normalization.ts
|
|
7257
|
+
var BUILTIN_CHAT_MESSAGE_KINDS = ["standard", "thought", "tool", "terminal", "system"];
|
|
7258
|
+
var KNOWN_CHAT_MESSAGE_KINDS = new Set(BUILTIN_CHAT_MESSAGE_KINDS);
|
|
7259
|
+
var CHAT_MESSAGE_KIND_ALIASES = {
|
|
7260
|
+
text: "standard",
|
|
7261
|
+
message: "standard",
|
|
7262
|
+
assistant: "standard",
|
|
7263
|
+
thinking: "thought",
|
|
7264
|
+
think: "thought",
|
|
7265
|
+
reasoning: "thought",
|
|
7266
|
+
reason: "thought",
|
|
7267
|
+
toolcall: "tool",
|
|
7268
|
+
tool_call: "tool",
|
|
7269
|
+
tooluse: "tool",
|
|
7270
|
+
tool_use: "tool",
|
|
7271
|
+
action: "tool",
|
|
7272
|
+
command: "terminal",
|
|
7273
|
+
cmd: "terminal",
|
|
7274
|
+
shell: "terminal",
|
|
7275
|
+
console: "terminal"
|
|
7276
|
+
};
|
|
7277
|
+
function canonicalizeKindHint(value) {
|
|
7278
|
+
return value.trim().toLowerCase().replace(/[\s-]+/g, "_");
|
|
7279
|
+
}
|
|
7280
|
+
function resolveBuiltinOrAliasKind(kind) {
|
|
7281
|
+
if (typeof kind !== "string") return null;
|
|
7282
|
+
const normalizedKind = canonicalizeKindHint(kind);
|
|
7283
|
+
if (!normalizedKind) return null;
|
|
7284
|
+
if (KNOWN_CHAT_MESSAGE_KINDS.has(normalizedKind)) return normalizedKind;
|
|
7285
|
+
return CHAT_MESSAGE_KIND_ALIASES[normalizedKind] || null;
|
|
7286
|
+
}
|
|
7287
|
+
function inferHintKind(value) {
|
|
7288
|
+
const direct = resolveBuiltinOrAliasKind(value);
|
|
7289
|
+
if (direct) return direct;
|
|
7290
|
+
if (typeof value !== "string") return null;
|
|
7291
|
+
const normalized = canonicalizeKindHint(value);
|
|
7292
|
+
if (!normalized) return null;
|
|
7293
|
+
if (/thought|thinking|reasoning/.test(normalized)) return "thought";
|
|
7294
|
+
if (/tool/.test(normalized)) return "tool";
|
|
7295
|
+
if (/terminal|command|shell|console/.test(normalized)) return "terminal";
|
|
7296
|
+
return null;
|
|
7297
|
+
}
|
|
7298
|
+
function inferKindFromToolCalls(message) {
|
|
7299
|
+
const toolCalls = Array.isArray(message?.toolCalls) ? message.toolCalls : [];
|
|
7300
|
+
if (toolCalls.length === 0) return null;
|
|
7301
|
+
if (toolCalls.some((toolCall) => toolCall?.kind === "think")) return "thought";
|
|
7302
|
+
if (toolCalls.some((toolCall) => toolCall?.kind === "execute")) return "terminal";
|
|
7303
|
+
if (toolCalls.some((toolCall) => Array.isArray(toolCall?.content) && toolCall.content.some((entry) => entry?.type === "terminal"))) {
|
|
7304
|
+
return "terminal";
|
|
7305
|
+
}
|
|
7306
|
+
return "tool";
|
|
7307
|
+
}
|
|
7308
|
+
function inferMissingChatMessageKind(message) {
|
|
7309
|
+
const role = typeof message?.role === "string" ? message.role.trim().toLowerCase() : "";
|
|
7310
|
+
if (role === "system") return "system";
|
|
7311
|
+
const meta = message?.meta && typeof message.meta === "object" ? message.meta : void 0;
|
|
7312
|
+
const hintCandidates = [
|
|
7313
|
+
message?._sub,
|
|
7314
|
+
message?._type,
|
|
7315
|
+
meta?.label,
|
|
7316
|
+
typeof message?.senderName === "string" ? message.senderName : void 0
|
|
7317
|
+
];
|
|
7318
|
+
for (const candidate of hintCandidates) {
|
|
7319
|
+
const inferred = inferHintKind(candidate);
|
|
7320
|
+
if (inferred) return inferred;
|
|
7321
|
+
}
|
|
7322
|
+
const inferredFromToolCalls = inferKindFromToolCalls(message);
|
|
7323
|
+
if (inferredFromToolCalls) return inferredFromToolCalls;
|
|
7324
|
+
return null;
|
|
7325
|
+
}
|
|
7326
|
+
function isBuiltinChatMessageKind(kind) {
|
|
7327
|
+
return resolveBuiltinOrAliasKind(kind) !== null;
|
|
7328
|
+
}
|
|
7329
|
+
function normalizeChatMessageKind(kind, role) {
|
|
7330
|
+
const resolvedKind = resolveBuiltinOrAliasKind(kind);
|
|
7331
|
+
if (resolvedKind) return resolvedKind;
|
|
7332
|
+
const normalizedRole = typeof role === "string" ? role.trim().toLowerCase() : "";
|
|
7333
|
+
return normalizedRole === "system" ? "system" : "standard";
|
|
7334
|
+
}
|
|
7335
|
+
function resolveChatMessageKind(message) {
|
|
7336
|
+
const explicitKind = resolveBuiltinOrAliasKind(message?.kind);
|
|
7337
|
+
if (explicitKind) return explicitKind;
|
|
7338
|
+
const inferredKind = inferMissingChatMessageKind(message);
|
|
7339
|
+
if (inferredKind) return inferredKind;
|
|
7340
|
+
return normalizeChatMessageKind(message?.kind, message?.role);
|
|
7341
|
+
}
|
|
7342
|
+
function buildChatMessage(message) {
|
|
7343
|
+
return {
|
|
7344
|
+
...message,
|
|
7345
|
+
kind: resolveChatMessageKind(message)
|
|
7346
|
+
};
|
|
7347
|
+
}
|
|
7348
|
+
function buildSystemChatMessage(message) {
|
|
7349
|
+
return buildChatMessage({
|
|
7350
|
+
...message,
|
|
7351
|
+
role: "system",
|
|
7352
|
+
kind: message?.kind || "system"
|
|
7353
|
+
});
|
|
7354
|
+
}
|
|
7355
|
+
function buildRuntimeSystemChatMessage(message) {
|
|
7356
|
+
return buildSystemChatMessage({
|
|
7357
|
+
...message,
|
|
7358
|
+
senderName: typeof message?.senderName === "string" && message.senderName.trim() ? message.senderName : "System"
|
|
7359
|
+
});
|
|
7360
|
+
}
|
|
7361
|
+
function buildAssistantChatMessage(message) {
|
|
7362
|
+
return buildChatMessage({
|
|
7363
|
+
...message,
|
|
7364
|
+
role: "assistant",
|
|
7365
|
+
kind: message?.kind || "standard"
|
|
7366
|
+
});
|
|
7367
|
+
}
|
|
7368
|
+
function buildThoughtChatMessage(message) {
|
|
7369
|
+
return buildAssistantChatMessage({
|
|
7370
|
+
...message,
|
|
7371
|
+
kind: message?.kind || "thought"
|
|
7372
|
+
});
|
|
7373
|
+
}
|
|
7374
|
+
function buildToolChatMessage(message) {
|
|
7375
|
+
return buildAssistantChatMessage({
|
|
7376
|
+
...message,
|
|
7377
|
+
kind: message?.kind || "tool"
|
|
7378
|
+
});
|
|
7379
|
+
}
|
|
7380
|
+
function buildTerminalChatMessage(message) {
|
|
7381
|
+
return buildAssistantChatMessage({
|
|
7382
|
+
...message,
|
|
7383
|
+
kind: message?.kind || "terminal"
|
|
7384
|
+
});
|
|
7385
|
+
}
|
|
7386
|
+
function buildUserChatMessage(message) {
|
|
7387
|
+
return buildChatMessage({
|
|
7388
|
+
...message,
|
|
7389
|
+
role: "user",
|
|
7390
|
+
kind: message?.kind || "standard"
|
|
7391
|
+
});
|
|
7392
|
+
}
|
|
7393
|
+
function normalizeChatMessage(message) {
|
|
7394
|
+
return buildChatMessage(message);
|
|
7395
|
+
}
|
|
7396
|
+
function normalizeChatMessages(messages) {
|
|
7397
|
+
return (Array.isArray(messages) ? messages : []).map((message) => normalizeChatMessage(message));
|
|
7398
|
+
}
|
|
7399
|
+
|
|
8306
7400
|
// src/providers/control-effects.ts
|
|
8307
|
-
init_contracts();
|
|
8308
|
-
init_chat_message_normalization();
|
|
8309
7401
|
function extractProviderControlValues(controls, data) {
|
|
8310
7402
|
if (!data || typeof data !== "object") return void 0;
|
|
8311
7403
|
const values = {};
|
|
@@ -8499,7 +7591,6 @@ ${cleanBody}`;
|
|
|
8499
7591
|
}
|
|
8500
7592
|
|
|
8501
7593
|
// src/config/chat-history.ts
|
|
8502
|
-
init_chat_message_normalization();
|
|
8503
7594
|
import * as fs3 from "fs";
|
|
8504
7595
|
import * as path10 from "path";
|
|
8505
7596
|
import * as os5 from "os";
|
|
@@ -9781,9 +8872,6 @@ function resolveProviderStateSurface(params) {
|
|
|
9781
8872
|
};
|
|
9782
8873
|
}
|
|
9783
8874
|
|
|
9784
|
-
// src/providers/extension-provider-instance.ts
|
|
9785
|
-
init_chat_message_normalization();
|
|
9786
|
-
|
|
9787
8875
|
// src/providers/open-panel-support.ts
|
|
9788
8876
|
var IDE_PROVIDER_SESSION_CAPABILITIES_BASE = [
|
|
9789
8877
|
"read_chat",
|
|
@@ -10217,7 +9305,143 @@ ${effect.notification.body || ""}`.trim();
|
|
|
10217
9305
|
|
|
10218
9306
|
// src/providers/ide-provider-instance.ts
|
|
10219
9307
|
init_logger();
|
|
10220
|
-
|
|
9308
|
+
|
|
9309
|
+
// src/providers/read-chat-contract.ts
|
|
9310
|
+
var VALID_STATUSES = ["idle", "generating", "waiting_approval", "error", "panel_hidden", "streaming", "long_generating"];
|
|
9311
|
+
var VALID_ROLES = ["user", "assistant", "system", "human"];
|
|
9312
|
+
var VALID_BUBBLE_STATES = ["draft", "streaming", "final", "removed"];
|
|
9313
|
+
var VALID_TURN_STATUSES = ["open", "waiting_approval", "complete", "error"];
|
|
9314
|
+
function isPlainObject3(value) {
|
|
9315
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
9316
|
+
}
|
|
9317
|
+
function isFiniteNumber(value) {
|
|
9318
|
+
return typeof value === "number" && Number.isFinite(value);
|
|
9319
|
+
}
|
|
9320
|
+
function validateStatus(status, source) {
|
|
9321
|
+
if (typeof status !== "string" || !VALID_STATUSES.includes(status)) {
|
|
9322
|
+
throw new Error(`${source}: status must be one of ${VALID_STATUSES.join(", ")}`);
|
|
9323
|
+
}
|
|
9324
|
+
return status;
|
|
9325
|
+
}
|
|
9326
|
+
function validateRole(role, source, index) {
|
|
9327
|
+
if (typeof role !== "string" || !VALID_ROLES.includes(role)) {
|
|
9328
|
+
throw new Error(`${source}: messages[${index}].role must be one of ${VALID_ROLES.join(", ")}`);
|
|
9329
|
+
}
|
|
9330
|
+
return role;
|
|
9331
|
+
}
|
|
9332
|
+
function validateBubbleState(state, source, index) {
|
|
9333
|
+
if (typeof state !== "string" || !VALID_BUBBLE_STATES.includes(state)) {
|
|
9334
|
+
throw new Error(`${source}: messages[${index}].bubbleState must be one of ${VALID_BUBBLE_STATES.join(", ")}`);
|
|
9335
|
+
}
|
|
9336
|
+
return state;
|
|
9337
|
+
}
|
|
9338
|
+
function validateTurnStatus(turnStatus, source) {
|
|
9339
|
+
if (typeof turnStatus !== "string" || !VALID_TURN_STATUSES.includes(turnStatus)) {
|
|
9340
|
+
throw new Error(`${source}: turnStatus must be one of ${VALID_TURN_STATUSES.join(", ")}`);
|
|
9341
|
+
}
|
|
9342
|
+
return turnStatus;
|
|
9343
|
+
}
|
|
9344
|
+
function validateMessageContent(content, source, index) {
|
|
9345
|
+
if (typeof content === "string") return content;
|
|
9346
|
+
if (Array.isArray(content)) return normalizeMessageParts(content);
|
|
9347
|
+
throw new Error(`${source}: messages[${index}].content must be a string or structured content array`);
|
|
9348
|
+
}
|
|
9349
|
+
function validateMessage(message, source, index) {
|
|
9350
|
+
if (!isPlainObject3(message)) {
|
|
9351
|
+
throw new Error(`${source}: messages[${index}] must be an object`);
|
|
9352
|
+
}
|
|
9353
|
+
const normalized = {
|
|
9354
|
+
role: validateRole(message.role, source, index),
|
|
9355
|
+
content: validateMessageContent(message.content, source, index)
|
|
9356
|
+
};
|
|
9357
|
+
if (typeof message.kind === "string") normalized.kind = message.kind;
|
|
9358
|
+
if (typeof message.id === "string") normalized.id = message.id;
|
|
9359
|
+
if (typeof message.bubbleId === "string") normalized.bubbleId = message.bubbleId;
|
|
9360
|
+
if (typeof message.providerUnitKey === "string") normalized.providerUnitKey = message.providerUnitKey;
|
|
9361
|
+
if (message.bubbleState !== void 0) normalized.bubbleState = validateBubbleState(message.bubbleState, source, index);
|
|
9362
|
+
if (isFiniteNumber(message.index)) normalized.index = message.index;
|
|
9363
|
+
if (isFiniteNumber(message.timestamp)) normalized.timestamp = message.timestamp;
|
|
9364
|
+
if (isFiniteNumber(message.receivedAt)) normalized.receivedAt = message.receivedAt;
|
|
9365
|
+
if (typeof message._turnKey === "string") normalized._turnKey = message._turnKey;
|
|
9366
|
+
if (Array.isArray(message.toolCalls)) normalized.toolCalls = message.toolCalls;
|
|
9367
|
+
if (isPlainObject3(message.meta)) normalized.meta = message.meta;
|
|
9368
|
+
if (typeof message.senderName === "string") normalized.senderName = message.senderName;
|
|
9369
|
+
if (typeof message._type === "string") normalized._type = message._type;
|
|
9370
|
+
if (typeof message._sub === "string") normalized._sub = message._sub;
|
|
9371
|
+
return normalized;
|
|
9372
|
+
}
|
|
9373
|
+
function validateModal(activeModal, status, source) {
|
|
9374
|
+
if (activeModal == null) {
|
|
9375
|
+
if (status === "waiting_approval") {
|
|
9376
|
+
throw new Error(`${source}: waiting_approval status requires activeModal with buttons`);
|
|
9377
|
+
}
|
|
9378
|
+
return activeModal === null ? null : void 0;
|
|
9379
|
+
}
|
|
9380
|
+
if (!isPlainObject3(activeModal)) {
|
|
9381
|
+
throw new Error(`${source}: activeModal must be an object when provided`);
|
|
9382
|
+
}
|
|
9383
|
+
if (typeof activeModal.message !== "string") {
|
|
9384
|
+
throw new Error(`${source}: activeModal.message must be a string`);
|
|
9385
|
+
}
|
|
9386
|
+
if (!Array.isArray(activeModal.buttons) || activeModal.buttons.some((button) => typeof button !== "string" || !button.trim())) {
|
|
9387
|
+
throw new Error(`${source}: activeModal.buttons must be a non-empty string array`);
|
|
9388
|
+
}
|
|
9389
|
+
const normalized = {
|
|
9390
|
+
message: activeModal.message,
|
|
9391
|
+
buttons: activeModal.buttons.map((button) => button.trim())
|
|
9392
|
+
};
|
|
9393
|
+
if (isFiniteNumber(activeModal.width)) normalized.width = activeModal.width;
|
|
9394
|
+
if (isFiniteNumber(activeModal.height)) normalized.height = activeModal.height;
|
|
9395
|
+
return normalized;
|
|
9396
|
+
}
|
|
9397
|
+
function validateControlValues(controlValues, source) {
|
|
9398
|
+
if (controlValues === void 0) return void 0;
|
|
9399
|
+
if (!isPlainObject3(controlValues)) {
|
|
9400
|
+
throw new Error(`${source}: controlValues must be an object when provided`);
|
|
9401
|
+
}
|
|
9402
|
+
const normalized = {};
|
|
9403
|
+
for (const [key, value] of Object.entries(controlValues)) {
|
|
9404
|
+
if (typeof value !== "string" && typeof value !== "number" && typeof value !== "boolean") {
|
|
9405
|
+
throw new Error(`${source}: controlValues.${key} must be string, number, or boolean`);
|
|
9406
|
+
}
|
|
9407
|
+
normalized[key] = value;
|
|
9408
|
+
}
|
|
9409
|
+
return normalized;
|
|
9410
|
+
}
|
|
9411
|
+
function validateReadChatResultPayload(raw, source = "read_chat") {
|
|
9412
|
+
if (!isPlainObject3(raw)) {
|
|
9413
|
+
throw new Error(`${source}: payload must be an object`);
|
|
9414
|
+
}
|
|
9415
|
+
const status = validateStatus(raw.status, source);
|
|
9416
|
+
if (!Array.isArray(raw.messages)) {
|
|
9417
|
+
throw new Error(`${source}: messages must be an array`);
|
|
9418
|
+
}
|
|
9419
|
+
const messages = raw.messages.map((message, index) => validateMessage(message, source, index));
|
|
9420
|
+
const activeModal = validateModal(raw.activeModal, status, source);
|
|
9421
|
+
const controlValues = validateControlValues(raw.controlValues, source);
|
|
9422
|
+
const normalized = {
|
|
9423
|
+
status,
|
|
9424
|
+
messages
|
|
9425
|
+
};
|
|
9426
|
+
if (activeModal !== void 0) normalized.activeModal = activeModal;
|
|
9427
|
+
if (typeof raw.id === "string") normalized.id = raw.id;
|
|
9428
|
+
if (typeof raw.title === "string") normalized.title = raw.title;
|
|
9429
|
+
if (typeof raw.currentTurnId === "string") normalized.currentTurnId = raw.currentTurnId;
|
|
9430
|
+
if (raw.turnStatus !== void 0) normalized.turnStatus = validateTurnStatus(raw.turnStatus, source);
|
|
9431
|
+
if (typeof raw.agentType === "string") normalized.agentType = raw.agentType;
|
|
9432
|
+
if (typeof raw.agentName === "string") normalized.agentName = raw.agentName;
|
|
9433
|
+
if (typeof raw.extensionId === "string") normalized.extensionId = raw.extensionId;
|
|
9434
|
+
if (typeof raw.inputContent === "string") normalized.inputContent = raw.inputContent;
|
|
9435
|
+
if (typeof raw.isVisible === "boolean") normalized.isVisible = raw.isVisible;
|
|
9436
|
+
if (typeof raw.isWelcomeScreen === "boolean") normalized.isWelcomeScreen = raw.isWelcomeScreen;
|
|
9437
|
+
if (controlValues) normalized.controlValues = controlValues;
|
|
9438
|
+
if (raw.summaryMetadata !== void 0) normalized.summaryMetadata = raw.summaryMetadata;
|
|
9439
|
+
if (Array.isArray(raw.effects)) normalized.effects = raw.effects;
|
|
9440
|
+
if (typeof raw.providerSessionId === "string") normalized.providerSessionId = raw.providerSessionId;
|
|
9441
|
+
if (raw.transcriptAuthority === "provider" || raw.transcriptAuthority === "daemon") normalized.transcriptAuthority = raw.transcriptAuthority;
|
|
9442
|
+
if (raw.coverage === "full" || raw.coverage === "tail" || raw.coverage === "current-turn") normalized.coverage = raw.coverage;
|
|
9443
|
+
return normalized;
|
|
9444
|
+
}
|
|
10221
9445
|
|
|
10222
9446
|
// src/providers/approval-utils.ts
|
|
10223
9447
|
var DEFAULT_APPROVAL_POSITIVE_HINTS = [
|
|
@@ -10267,7 +9491,6 @@ function formatAutoApprovalMessage(modalMessage, buttonLabel) {
|
|
|
10267
9491
|
}
|
|
10268
9492
|
|
|
10269
9493
|
// src/providers/ide-provider-instance.ts
|
|
10270
|
-
init_chat_message_normalization();
|
|
10271
9494
|
var IdeProviderInstance = class {
|
|
10272
9495
|
type;
|
|
10273
9496
|
category = "ide";
|
|
@@ -11726,7 +10949,6 @@ function resolveLegacyProviderScript(fn, scriptName, params) {
|
|
|
11726
10949
|
}
|
|
11727
10950
|
|
|
11728
10951
|
// src/commands/chat-commands.ts
|
|
11729
|
-
init_contracts();
|
|
11730
10952
|
import * as fs4 from "fs";
|
|
11731
10953
|
import * as os6 from "os";
|
|
11732
10954
|
import * as path11 from "path";
|
|
@@ -11788,7 +11010,6 @@ function assertProviderSupportsDeclaredInput(provider, input) {
|
|
|
11788
11010
|
}
|
|
11789
11011
|
|
|
11790
11012
|
// src/commands/chat-commands.ts
|
|
11791
|
-
init_read_chat_contract();
|
|
11792
11013
|
init_logger();
|
|
11793
11014
|
|
|
11794
11015
|
// src/logging/debug-trace.ts
|
|
@@ -11916,10 +11137,6 @@ function buildChatTailDeliverySignature(payload) {
|
|
|
11916
11137
|
payload.historySessionId || "",
|
|
11917
11138
|
payload.status,
|
|
11918
11139
|
payload.title || "",
|
|
11919
|
-
payload.syncMode,
|
|
11920
|
-
String(payload.replaceFrom),
|
|
11921
|
-
String(payload.totalMessages),
|
|
11922
|
-
payload.lastMessageSignature,
|
|
11923
11140
|
payload.activeModal ? `${payload.activeModal.message}|${payload.activeModal.buttons.join("")}` : "",
|
|
11924
11141
|
stringifySignatureMessages(payload.messages)
|
|
11925
11142
|
]);
|
|
@@ -11935,7 +11152,6 @@ function buildSessionModalDeliverySignature(payload) {
|
|
|
11935
11152
|
}
|
|
11936
11153
|
|
|
11937
11154
|
// src/commands/chat-commands.ts
|
|
11938
|
-
init_chat_message_normalization();
|
|
11939
11155
|
var RECENT_SEND_WINDOW_MS = 1200;
|
|
11940
11156
|
var READ_CHAT_PROVIDER_EVAL_TIMEOUT_MS = 25e3;
|
|
11941
11157
|
var recentSendByTarget = /* @__PURE__ */ new Map();
|
|
@@ -12036,99 +11252,13 @@ function parseMaybeJson(value) {
|
|
|
12036
11252
|
return value;
|
|
12037
11253
|
}
|
|
12038
11254
|
}
|
|
12039
|
-
function
|
|
12040
|
-
|
|
12041
|
-
|
|
12042
|
-
function normalizeReadChatCursor(args) {
|
|
12043
|
-
const knownMessageCount = Math.max(0, Number(args?.knownMessageCount || 0));
|
|
12044
|
-
const lastMessageSignature = typeof args?.lastMessageSignature === "string" ? args.lastMessageSignature : "";
|
|
12045
|
-
const tailLimit = Math.max(0, Number(args?.tailLimit || 0));
|
|
12046
|
-
return { knownMessageCount, lastMessageSignature, tailLimit };
|
|
11255
|
+
function normalizeReadChatTailLimit(args) {
|
|
11256
|
+
const value = Number(args?.tailLimit || 0);
|
|
11257
|
+
return Number.isFinite(value) ? Math.max(0, value) : 0;
|
|
12047
11258
|
}
|
|
12048
11259
|
function normalizeReadChatMessages(payload) {
|
|
12049
11260
|
const messages = Array.isArray(payload.messages) ? payload.messages : [];
|
|
12050
|
-
return
|
|
12051
|
-
}
|
|
12052
|
-
function normalizeReadChatReplayTextContent(content) {
|
|
12053
|
-
return flattenContent(content || "").replace(/\s+/g, " ").trim();
|
|
12054
|
-
}
|
|
12055
|
-
function getReadChatReplayCollapseInfo(message) {
|
|
12056
|
-
if (!message) return null;
|
|
12057
|
-
const role = typeof message.role === "string" ? message.role.trim().toLowerCase() : "";
|
|
12058
|
-
const kind = typeof message.kind === "string" ? message.kind.trim().toLowerCase() : "standard";
|
|
12059
|
-
const senderName = typeof message.senderName === "string" ? message.senderName.trim().toLowerCase() : "";
|
|
12060
|
-
const collapsible = role === "assistant" || role === "system";
|
|
12061
|
-
if (!collapsible) return { role, kind, senderName, content: "", signature: "", collapsible };
|
|
12062
|
-
const content = normalizeReadChatReplayTextContent(message.content);
|
|
12063
|
-
return {
|
|
12064
|
-
role,
|
|
12065
|
-
kind,
|
|
12066
|
-
senderName,
|
|
12067
|
-
content,
|
|
12068
|
-
signature: `${role}:${kind}:${senderName}:${content}`,
|
|
12069
|
-
collapsible
|
|
12070
|
-
};
|
|
12071
|
-
}
|
|
12072
|
-
function isStableReadChatAssistantAnswerInfo(info) {
|
|
12073
|
-
if (!info) return false;
|
|
12074
|
-
if (info.role !== "assistant") return false;
|
|
12075
|
-
if (info.kind && info.kind !== "standard") return false;
|
|
12076
|
-
if (info.content.length < 160) return false;
|
|
12077
|
-
if (/^(bash|shell|terminal) command\b/i.test(info.content)) return false;
|
|
12078
|
-
return true;
|
|
12079
|
-
}
|
|
12080
|
-
function isReplayedAssistantAnswerAfterStableAnswerInfo(info, stableContent) {
|
|
12081
|
-
if (!info || !stableContent) return false;
|
|
12082
|
-
if (info.role !== "assistant") return false;
|
|
12083
|
-
if (info.kind && info.kind !== "standard") return false;
|
|
12084
|
-
const content = info.content;
|
|
12085
|
-
if (content.length < 80 || stableContent.length < 80) return false;
|
|
12086
|
-
return content === stableContent || content.startsWith(stableContent) || stableContent.startsWith(content);
|
|
12087
|
-
}
|
|
12088
|
-
function collapseReplayDuplicatesFromReadChat(messages) {
|
|
12089
|
-
const collapsed = [];
|
|
12090
|
-
const replaySignaturesInCurrentTurn = /* @__PURE__ */ new Set();
|
|
12091
|
-
let stableAssistantAnswerContentInCurrentTurn = "";
|
|
12092
|
-
let stableAssistantAnswerCollapsedIndex = -1;
|
|
12093
|
-
let stableAssistantAnswerHadInterveningActivity = false;
|
|
12094
|
-
let previousReplaySignature = "";
|
|
12095
|
-
for (const message of messages) {
|
|
12096
|
-
const info = getReadChatReplayCollapseInfo(message);
|
|
12097
|
-
if (info?.role === "user") {
|
|
12098
|
-
replaySignaturesInCurrentTurn.clear();
|
|
12099
|
-
stableAssistantAnswerContentInCurrentTurn = "";
|
|
12100
|
-
stableAssistantAnswerCollapsedIndex = -1;
|
|
12101
|
-
stableAssistantAnswerHadInterveningActivity = false;
|
|
12102
|
-
previousReplaySignature = "";
|
|
12103
|
-
}
|
|
12104
|
-
if (info?.collapsible && info.signature) {
|
|
12105
|
-
if (previousReplaySignature === info.signature) continue;
|
|
12106
|
-
if (replaySignaturesInCurrentTurn.has(info.signature)) continue;
|
|
12107
|
-
if (isReplayedAssistantAnswerAfterStableAnswerInfo(info, stableAssistantAnswerContentInCurrentTurn)) {
|
|
12108
|
-
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);
|
|
12109
|
-
if (isAdjacentFullerAssistantAnswer) {
|
|
12110
|
-
collapsed[stableAssistantAnswerCollapsedIndex] = message;
|
|
12111
|
-
replaySignaturesInCurrentTurn.add(info.signature);
|
|
12112
|
-
stableAssistantAnswerContentInCurrentTurn = info.content;
|
|
12113
|
-
previousReplaySignature = info.signature;
|
|
12114
|
-
}
|
|
12115
|
-
continue;
|
|
12116
|
-
}
|
|
12117
|
-
}
|
|
12118
|
-
collapsed.push(message);
|
|
12119
|
-
previousReplaySignature = info?.collapsible ? info.signature : "";
|
|
12120
|
-
if (info?.collapsible && info.signature) {
|
|
12121
|
-
replaySignaturesInCurrentTurn.add(info.signature);
|
|
12122
|
-
}
|
|
12123
|
-
if (isStableReadChatAssistantAnswerInfo(info)) {
|
|
12124
|
-
stableAssistantAnswerContentInCurrentTurn = info?.content || "";
|
|
12125
|
-
stableAssistantAnswerCollapsedIndex = collapsed.length - 1;
|
|
12126
|
-
stableAssistantAnswerHadInterveningActivity = false;
|
|
12127
|
-
} else if (stableAssistantAnswerContentInCurrentTurn && info?.role === "assistant" && (!info.kind || info.kind !== "standard")) {
|
|
12128
|
-
stableAssistantAnswerHadInterveningActivity = true;
|
|
12129
|
-
}
|
|
12130
|
-
}
|
|
12131
|
-
return collapsed;
|
|
11261
|
+
return messages;
|
|
12132
11262
|
}
|
|
12133
11263
|
function deriveHistoryDedupKey(message) {
|
|
12134
11264
|
const unitKey = typeof message._unitKey === "string" ? message._unitKey.trim() : "";
|
|
@@ -12153,102 +11283,12 @@ function toHistoryPersistedMessages(messages) {
|
|
|
12153
11283
|
historyDedupKey: deriveHistoryDedupKey(message)
|
|
12154
11284
|
}));
|
|
12155
11285
|
}
|
|
12156
|
-
function
|
|
12157
|
-
if (!signature) return -1;
|
|
12158
|
-
for (let index = messages.length - 1; index >= 0; index -= 1) {
|
|
12159
|
-
if (getChatMessageSignature(messages[index]) === signature) {
|
|
12160
|
-
return index;
|
|
12161
|
-
}
|
|
12162
|
-
}
|
|
12163
|
-
return -1;
|
|
12164
|
-
}
|
|
12165
|
-
function buildBoundedTailSync(messages, cursor) {
|
|
11286
|
+
function buildFullTail(messages, tailLimit) {
|
|
12166
11287
|
const totalMessages = messages.length;
|
|
12167
|
-
const tailMessages =
|
|
11288
|
+
const tailMessages = tailLimit > 0 ? messages.slice(-tailLimit) : messages;
|
|
12168
11289
|
return {
|
|
12169
|
-
syncMode: "full",
|
|
12170
|
-
replaceFrom: 0,
|
|
12171
11290
|
messages: tailMessages,
|
|
12172
|
-
totalMessages
|
|
12173
|
-
lastMessageSignature: getChatMessageSignature(messages[totalMessages - 1])
|
|
12174
|
-
};
|
|
12175
|
-
}
|
|
12176
|
-
function computeReadChatSync(messages, cursor) {
|
|
12177
|
-
const totalMessages = messages.length;
|
|
12178
|
-
const lastMessageSignature = getChatMessageSignature(messages[totalMessages - 1]);
|
|
12179
|
-
const { knownMessageCount, lastMessageSignature: knownSignature } = cursor;
|
|
12180
|
-
if (!knownMessageCount || !knownSignature) {
|
|
12181
|
-
return {
|
|
12182
|
-
syncMode: "full",
|
|
12183
|
-
replaceFrom: 0,
|
|
12184
|
-
messages,
|
|
12185
|
-
totalMessages,
|
|
12186
|
-
lastMessageSignature
|
|
12187
|
-
};
|
|
12188
|
-
}
|
|
12189
|
-
if (knownMessageCount > totalMessages) {
|
|
12190
|
-
return {
|
|
12191
|
-
syncMode: "full",
|
|
12192
|
-
replaceFrom: 0,
|
|
12193
|
-
messages,
|
|
12194
|
-
totalMessages,
|
|
12195
|
-
lastMessageSignature
|
|
12196
|
-
};
|
|
12197
|
-
}
|
|
12198
|
-
if (knownMessageCount === totalMessages && knownSignature === lastMessageSignature) {
|
|
12199
|
-
return {
|
|
12200
|
-
syncMode: "noop",
|
|
12201
|
-
replaceFrom: totalMessages,
|
|
12202
|
-
messages: [],
|
|
12203
|
-
totalMessages,
|
|
12204
|
-
lastMessageSignature
|
|
12205
|
-
};
|
|
12206
|
-
}
|
|
12207
|
-
if (cursor.tailLimit > 0 && knownSignature === lastMessageSignature) {
|
|
12208
|
-
const requestedTailCount = Math.min(totalMessages, cursor.tailLimit);
|
|
12209
|
-
if (knownMessageCount >= requestedTailCount) {
|
|
12210
|
-
return {
|
|
12211
|
-
syncMode: "noop",
|
|
12212
|
-
replaceFrom: totalMessages,
|
|
12213
|
-
messages: [],
|
|
12214
|
-
totalMessages,
|
|
12215
|
-
lastMessageSignature
|
|
12216
|
-
};
|
|
12217
|
-
}
|
|
12218
|
-
return buildBoundedTailSync(messages, cursor);
|
|
12219
|
-
}
|
|
12220
|
-
if (knownMessageCount < totalMessages) {
|
|
12221
|
-
const anchorSignature = getChatMessageSignature(messages[knownMessageCount - 1]);
|
|
12222
|
-
if (anchorSignature === knownSignature) {
|
|
12223
|
-
return {
|
|
12224
|
-
syncMode: "append",
|
|
12225
|
-
replaceFrom: knownMessageCount,
|
|
12226
|
-
messages: messages.slice(knownMessageCount),
|
|
12227
|
-
totalMessages,
|
|
12228
|
-
lastMessageSignature
|
|
12229
|
-
};
|
|
12230
|
-
}
|
|
12231
|
-
if (cursor.tailLimit > 0) {
|
|
12232
|
-
const signatureIndex = findLastMessageIndexBySignature(messages, knownSignature);
|
|
12233
|
-
if (signatureIndex >= 0) {
|
|
12234
|
-
return {
|
|
12235
|
-
syncMode: "append",
|
|
12236
|
-
replaceFrom: knownMessageCount,
|
|
12237
|
-
messages: messages.slice(signatureIndex + 1),
|
|
12238
|
-
totalMessages,
|
|
12239
|
-
lastMessageSignature
|
|
12240
|
-
};
|
|
12241
|
-
}
|
|
12242
|
-
return buildBoundedTailSync(messages, cursor);
|
|
12243
|
-
}
|
|
12244
|
-
}
|
|
12245
|
-
const replaceFrom = Math.max(0, Math.min(knownMessageCount - 1, totalMessages));
|
|
12246
|
-
return {
|
|
12247
|
-
syncMode: replaceFrom === 0 ? "full" : "replace_tail",
|
|
12248
|
-
replaceFrom,
|
|
12249
|
-
messages: replaceFrom === 0 ? messages : messages.slice(replaceFrom),
|
|
12250
|
-
totalMessages,
|
|
12251
|
-
lastMessageSignature
|
|
11291
|
+
totalMessages
|
|
12252
11292
|
};
|
|
12253
11293
|
}
|
|
12254
11294
|
function hasNonEmptyModalButtons(activeModal) {
|
|
@@ -12283,31 +11323,13 @@ function buildReadChatCommandResult(payload, args) {
|
|
|
12283
11323
|
} catch (error) {
|
|
12284
11324
|
return { success: false, error: error?.message || String(error) };
|
|
12285
11325
|
}
|
|
12286
|
-
const messages =
|
|
12287
|
-
const
|
|
12288
|
-
if (!cursor.knownMessageCount && !cursor.lastMessageSignature && cursor.tailLimit > 0 && messages.length > cursor.tailLimit) {
|
|
12289
|
-
const tailMessages = messages.slice(-cursor.tailLimit);
|
|
12290
|
-
const lastMessageSignature = getChatMessageSignature(tailMessages[tailMessages.length - 1]);
|
|
12291
|
-
return {
|
|
12292
|
-
success: true,
|
|
12293
|
-
...validatedPayload,
|
|
12294
|
-
messages: tailMessages,
|
|
12295
|
-
syncMode: "full",
|
|
12296
|
-
replaceFrom: 0,
|
|
12297
|
-
totalMessages: messages.length,
|
|
12298
|
-
lastMessageSignature,
|
|
12299
|
-
...debugReadChat ? { debugReadChat } : {}
|
|
12300
|
-
};
|
|
12301
|
-
}
|
|
12302
|
-
const sync = computeReadChatSync(messages, cursor);
|
|
11326
|
+
const messages = normalizeReadChatMessages(validatedPayload);
|
|
11327
|
+
const sync = buildFullTail(messages, normalizeReadChatTailLimit(args));
|
|
12303
11328
|
return {
|
|
12304
11329
|
success: true,
|
|
12305
11330
|
...validatedPayload,
|
|
12306
11331
|
messages: sync.messages,
|
|
12307
|
-
syncMode: sync.syncMode,
|
|
12308
|
-
replaceFrom: sync.replaceFrom,
|
|
12309
11332
|
totalMessages: sync.totalMessages,
|
|
12310
|
-
lastMessageSignature: sync.lastMessageSignature,
|
|
12311
11333
|
...debugReadChat ? { debugReadChat } : {}
|
|
12312
11334
|
};
|
|
12313
11335
|
}
|
|
@@ -12532,10 +11554,6 @@ async function handleGetChatDebugBundle(h, args) {
|
|
|
12532
11554
|
status: readResult.status,
|
|
12533
11555
|
title: readResult.title,
|
|
12534
11556
|
totalMessages: readResult.totalMessages,
|
|
12535
|
-
returnedMessages: Array.isArray(readResult.messages) ? readResult.messages.length : void 0,
|
|
12536
|
-
syncMode: readResult.syncMode,
|
|
12537
|
-
replaceFrom: readResult.replaceFrom,
|
|
12538
|
-
lastMessageSignature: readResult.lastMessageSignature,
|
|
12539
11557
|
providerSessionId: readResult.providerSessionId,
|
|
12540
11558
|
transcriptAuthority: readResult.transcriptAuthority,
|
|
12541
11559
|
coverage: readResult.coverage,
|
|
@@ -12645,22 +11663,13 @@ function toNonNegativeNumber(value) {
|
|
|
12645
11663
|
return Number.isFinite(numeric) ? Math.max(0, numeric) : 0;
|
|
12646
11664
|
}
|
|
12647
11665
|
function getCliVisibleTranscriptCount(adapter) {
|
|
12648
|
-
|
|
12649
|
-
|
|
12650
|
-
|
|
12651
|
-
|
|
12652
|
-
|
|
12653
|
-
|
|
12654
|
-
parsedRecord = parsed && typeof parsed === "object" ? parsed : null;
|
|
12655
|
-
} catch {
|
|
12656
|
-
parsedRecord = null;
|
|
12657
|
-
}
|
|
11666
|
+
if (typeof adapter?.getScriptParsedStatus !== "function") return 0;
|
|
11667
|
+
try {
|
|
11668
|
+
const parsed = parseMaybeJson(adapter.getScriptParsedStatus());
|
|
11669
|
+
return Array.isArray(parsed?.messages) ? parsed.messages.length : 0;
|
|
11670
|
+
} catch {
|
|
11671
|
+
return 0;
|
|
12658
11672
|
}
|
|
12659
|
-
const parsedMessages = Array.isArray(parsedRecord?.messages) ? parsedRecord.messages : [];
|
|
12660
|
-
if (!parsedRecord) return adapterMessages.length;
|
|
12661
|
-
const parsedIsProviderAuthoritative = parsedRecord.transcriptAuthority === "provider" || parsedRecord.coverage === "full";
|
|
12662
|
-
const shouldPreferAdapterMessages = !parsedIsProviderAuthoritative && adapterMessages.length > 0 && adapterMessages.length > parsedMessages.length;
|
|
12663
|
-
return shouldPreferAdapterMessages ? adapterMessages.length : parsedMessages.length;
|
|
12664
11673
|
}
|
|
12665
11674
|
async function getStableExtensionBaseline(h) {
|
|
12666
11675
|
const first = await readExtensionChatState(h);
|
|
@@ -12722,52 +11731,46 @@ async function handleReadChat(h, args) {
|
|
|
12722
11731
|
const adapter = getTargetedCliAdapter(h, args, provider?.type);
|
|
12723
11732
|
if (adapter) {
|
|
12724
11733
|
_log(`${transport} adapter: ${adapter.cliType}`);
|
|
11734
|
+
if (typeof adapter.getScriptParsedStatus !== "function") {
|
|
11735
|
+
return { success: false, error: `${transport} adapter parseSession unavailable` };
|
|
11736
|
+
}
|
|
12725
11737
|
let parsedStatus = null;
|
|
12726
|
-
|
|
12727
|
-
|
|
12728
|
-
|
|
12729
|
-
|
|
12730
|
-
return { success: false, error: error?.message || String(error) };
|
|
12731
|
-
}
|
|
11738
|
+
try {
|
|
11739
|
+
parsedStatus = parseMaybeJson(adapter.getScriptParsedStatus());
|
|
11740
|
+
} catch (error) {
|
|
11741
|
+
return { success: false, error: error?.message || String(error) };
|
|
12732
11742
|
}
|
|
12733
11743
|
const parsedRecord = parsedStatus && typeof parsedStatus === "object" ? parsedStatus : null;
|
|
12734
|
-
|
|
12735
|
-
|
|
12736
|
-
|
|
12737
|
-
const
|
|
12738
|
-
const
|
|
12739
|
-
|
|
12740
|
-
|
|
12741
|
-
|
|
12742
|
-
|
|
12743
|
-
|
|
12744
|
-
|
|
12745
|
-
|
|
12746
|
-
|
|
12747
|
-
|
|
12748
|
-
|
|
12749
|
-
|
|
12750
|
-
|
|
12751
|
-
|
|
12752
|
-
|
|
12753
|
-
|
|
12754
|
-
|
|
12755
|
-
|
|
12756
|
-
|
|
12757
|
-
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
},
|
|
12765
|
-
...title ? { title } : {},
|
|
12766
|
-
...providerSessionId ? { providerSessionId } : {},
|
|
12767
|
-
...transcriptAuthority ? { transcriptAuthority } : {},
|
|
12768
|
-
...coverage ? { coverage } : {}
|
|
12769
|
-
}, args);
|
|
12770
|
-
}
|
|
11744
|
+
if (!parsedRecord || !Array.isArray(parsedRecord.messages)) {
|
|
11745
|
+
return { success: false, error: `${transport} parser did not return messages` };
|
|
11746
|
+
}
|
|
11747
|
+
const adapterStatus = typeof adapter.getStatus === "function" ? adapter.getStatus() : {};
|
|
11748
|
+
const title = typeof parsedRecord.title === "string" ? parsedRecord.title : void 0;
|
|
11749
|
+
const providerSessionId = typeof parsedRecord.providerSessionId === "string" ? parsedRecord.providerSessionId : void 0;
|
|
11750
|
+
const transcriptAuthority = parsedRecord.transcriptAuthority === "provider" || parsedRecord.transcriptAuthority === "daemon" ? parsedRecord.transcriptAuthority : void 0;
|
|
11751
|
+
const coverage = parsedRecord.coverage === "full" || parsedRecord.coverage === "tail" || parsedRecord.coverage === "current-turn" ? parsedRecord.coverage : void 0;
|
|
11752
|
+
const activeModal = parsedRecord.activeModal ?? parsedRecord.modal ?? null;
|
|
11753
|
+
const returnedStatus = parsedRecord.status || "idle";
|
|
11754
|
+
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}`);
|
|
11755
|
+
return buildReadChatCommandResult({
|
|
11756
|
+
messages: parsedRecord.messages,
|
|
11757
|
+
status: returnedStatus,
|
|
11758
|
+
activeModal,
|
|
11759
|
+
debugReadChat: {
|
|
11760
|
+
provider: adapter.cliType,
|
|
11761
|
+
targetSessionId: String(args?.targetSessionId || ""),
|
|
11762
|
+
adapterStatus: String(adapterStatus.status || ""),
|
|
11763
|
+
parsedStatus: String(parsedRecord.status || ""),
|
|
11764
|
+
returnedStatus: String(returnedStatus || ""),
|
|
11765
|
+
shouldPreferAdapterMessages: false,
|
|
11766
|
+
parsedMsgCount: parsedRecord.messages.length,
|
|
11767
|
+
returnedMsgCount: parsedRecord.messages.length
|
|
11768
|
+
},
|
|
11769
|
+
...title ? { title } : {},
|
|
11770
|
+
...providerSessionId ? { providerSessionId } : {},
|
|
11771
|
+
...transcriptAuthority ? { transcriptAuthority } : {},
|
|
11772
|
+
...coverage ? { coverage } : {}
|
|
11773
|
+
}, args);
|
|
12771
11774
|
}
|
|
12772
11775
|
return { success: false, error: `${transport} adapter not found` };
|
|
12773
11776
|
}
|
|
@@ -15066,7 +14069,6 @@ import chalk from "chalk";
|
|
|
15066
14069
|
init_config();
|
|
15067
14070
|
|
|
15068
14071
|
// src/providers/cli-provider-instance.ts
|
|
15069
|
-
init_contracts();
|
|
15070
14072
|
import * as os12 from "os";
|
|
15071
14073
|
import * as path15 from "path";
|
|
15072
14074
|
import * as crypto3 from "crypto";
|
|
@@ -15093,7 +14095,6 @@ function normalizeProviderSessionId(provider, providerSessionId) {
|
|
|
15093
14095
|
}
|
|
15094
14096
|
|
|
15095
14097
|
// src/providers/cli-provider-instance.ts
|
|
15096
|
-
init_chat_message_normalization();
|
|
15097
14098
|
function normalizePersistableCliHistoryContent(content) {
|
|
15098
14099
|
return flattenContent(content).replace(/\s+/g, " ").trim();
|
|
15099
14100
|
}
|
|
@@ -15333,17 +14334,11 @@ var CliProviderInstance = class {
|
|
|
15333
14334
|
}
|
|
15334
14335
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
15335
14336
|
this.maybeAppendRuntimeRecoveryMessage(runtime);
|
|
15336
|
-
let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages :
|
|
14337
|
+
let parsedMessages = Array.isArray(parsedStatus?.messages) ? parsedStatus.messages : [];
|
|
15337
14338
|
const historyMessageCount = Number.isFinite(parsedStatus?.historyMessageCount) ? Math.max(0, Number(parsedStatus.historyMessageCount)) : null;
|
|
15338
14339
|
if (historyMessageCount !== null) {
|
|
15339
14340
|
parsedMessages = historyMessageCount > 0 ? parsedMessages.slice(-historyMessageCount) : [];
|
|
15340
14341
|
}
|
|
15341
|
-
const committedMessages = Array.isArray(adapterStatus.messages) ? adapterStatus.messages : [];
|
|
15342
|
-
const isActiveNonIdle = adapterStatus.status !== "idle";
|
|
15343
|
-
const shouldApplyCommittedFloor = parsedMessages.length < committedMessages.length && (adapterStatus.status === "waiting_approval" || isActiveNonIdle && historyMessageCount === null);
|
|
15344
|
-
if (shouldApplyCommittedFloor) {
|
|
15345
|
-
parsedMessages = normalizeChatMessages(committedMessages);
|
|
15346
|
-
}
|
|
15347
14342
|
const mergedMessages = this.mergeConversationMessages(parsedMessages);
|
|
15348
14343
|
const canonicalBackedHistory = this.syncCanonicalSavedHistoryIfNeeded();
|
|
15349
14344
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
@@ -15436,11 +14431,9 @@ var CliProviderInstance = class {
|
|
|
15436
14431
|
const autoApproveActive = adapterStatus.status === "waiting_approval" && this.shouldAutoApprove();
|
|
15437
14432
|
const visibleStatus = autoApproveActive ? "generating" : adapterStatus.status;
|
|
15438
14433
|
const runtime = this.adapter.getRuntimeMetadata();
|
|
15439
|
-
const lastCommittedMessageActivityAt = typeof this.adapter.getLastCommittedMessageActivityAt === "function" ? this.adapter.getLastCommittedMessageActivityAt() : 0;
|
|
15440
14434
|
return {
|
|
15441
14435
|
id: this.instanceId,
|
|
15442
14436
|
status: visibleStatus,
|
|
15443
|
-
lastMessageAt: lastCommittedMessageActivityAt || void 0,
|
|
15444
14437
|
runtimeLifecycle: runtime?.lifecycle ?? null,
|
|
15445
14438
|
runtimeSurfaceKind: runtime?.surfaceKind,
|
|
15446
14439
|
runtimeRestoredFromStorage: runtime?.restoredFromStorage === true,
|
|
@@ -15546,7 +14539,7 @@ var CliProviderInstance = class {
|
|
|
15546
14539
|
const dirName = this.workingDir.split("/").filter(Boolean).pop() || "session";
|
|
15547
14540
|
const chatTitle = `${this.provider.name} \xB7 ${dirName}`;
|
|
15548
14541
|
const partial = this.adapter.getPartialResponse();
|
|
15549
|
-
const progressFingerprint = newStatus === "generating" ? `${partial || ""}
|
|
14542
|
+
const progressFingerprint = newStatus === "generating" ? `${partial || ""}`.slice(-2e3) : void 0;
|
|
15550
14543
|
const previousStatus = this.lastStatus;
|
|
15551
14544
|
if (newStatus !== this.lastStatus) {
|
|
15552
14545
|
LOG.info("CLI", `[${this.type}] status: ${this.lastStatus} \u2192 ${newStatus}`);
|
|
@@ -15992,18 +14985,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
15992
14985
|
receivedAt: message.receivedAt
|
|
15993
14986
|
}));
|
|
15994
14987
|
this.suppressIdleHistoryReplay = restoredHistory.messages.length > 0;
|
|
15995
|
-
if (restoredHistory.messages.length > 0) {
|
|
15996
|
-
this.adapter.seedCommittedMessages(
|
|
15997
|
-
restoredHistory.messages.map((message) => ({
|
|
15998
|
-
role: message.role,
|
|
15999
|
-
content: message.content,
|
|
16000
|
-
timestamp: message.receivedAt,
|
|
16001
|
-
receivedAt: message.receivedAt,
|
|
16002
|
-
kind: message.kind,
|
|
16003
|
-
senderName: message.senderName
|
|
16004
|
-
}))
|
|
16005
|
-
);
|
|
16006
|
-
}
|
|
16007
14988
|
}
|
|
16008
14989
|
getProbeDirectories() {
|
|
16009
14990
|
const dirs = /* @__PURE__ */ new Set();
|
|
@@ -16050,7 +15031,6 @@ ${effect.notification.body || ""}`.trim();
|
|
|
16050
15031
|
};
|
|
16051
15032
|
|
|
16052
15033
|
// src/providers/acp-provider-instance.ts
|
|
16053
|
-
init_contracts();
|
|
16054
15034
|
import { Readable, Writable } from "stream";
|
|
16055
15035
|
import { spawn } from "child_process";
|
|
16056
15036
|
import {
|
|
@@ -16059,7 +15039,6 @@ import {
|
|
|
16059
15039
|
RequestError,
|
|
16060
15040
|
PROTOCOL_VERSION
|
|
16061
15041
|
} from "@agentclientprotocol/sdk";
|
|
16062
|
-
init_chat_message_normalization();
|
|
16063
15042
|
init_logger();
|
|
16064
15043
|
function getPromptCapabilityFlags(agentCapabilities) {
|
|
16065
15044
|
const prompt = agentCapabilities?.promptCapabilities || {};
|
|
@@ -17203,7 +16182,6 @@ ${rawInput}` : rawInput;
|
|
|
17203
16182
|
};
|
|
17204
16183
|
|
|
17205
16184
|
// src/commands/cli-manager.ts
|
|
17206
|
-
init_contracts();
|
|
17207
16185
|
init_logger();
|
|
17208
16186
|
|
|
17209
16187
|
// src/commands/hosted-runtime-restore.ts
|
|
@@ -20137,13 +19115,24 @@ async function launchWithCdp(options = {}) {
|
|
|
20137
19115
|
break;
|
|
20138
19116
|
}
|
|
20139
19117
|
}
|
|
19118
|
+
if (!cdpReady) {
|
|
19119
|
+
return {
|
|
19120
|
+
success: false,
|
|
19121
|
+
ideId: targetIde.id,
|
|
19122
|
+
ideName: targetIde.displayName,
|
|
19123
|
+
port,
|
|
19124
|
+
action: "failed",
|
|
19125
|
+
message: "",
|
|
19126
|
+
error: `${targetIde.displayName} launched but CDP did not become available on port ${port}`
|
|
19127
|
+
};
|
|
19128
|
+
}
|
|
20140
19129
|
return {
|
|
20141
19130
|
success: true,
|
|
20142
19131
|
ideId: targetIde.id,
|
|
20143
19132
|
ideName: targetIde.displayName,
|
|
20144
19133
|
port,
|
|
20145
19134
|
action: alreadyRunning ? "restarted" : "started",
|
|
20146
|
-
message:
|
|
19135
|
+
message: `${targetIde.displayName} launched with CDP on port ${port}`
|
|
20147
19136
|
};
|
|
20148
19137
|
} catch (e) {
|
|
20149
19138
|
return {
|
|
@@ -22071,9 +21060,6 @@ var DEFAULT_DAEMON_PORT = 19222;
|
|
|
22071
21060
|
var DAEMON_WS_PATH = "/ipc";
|
|
22072
21061
|
|
|
22073
21062
|
// src/chat/subscription-updates.ts
|
|
22074
|
-
function normalizeSyncMode(syncMode) {
|
|
22075
|
-
return syncMode === "append" || syncMode === "replace_tail" || syncMode === "noop" || syncMode === "full" ? syncMode : "full";
|
|
22076
|
-
}
|
|
22077
21063
|
function normalizeModalButtons(value) {
|
|
22078
21064
|
return Array.isArray(value) ? value.filter((button) => typeof button === "string") : [];
|
|
22079
21065
|
}
|
|
@@ -22100,55 +21086,39 @@ function normalizeSessionModalFields(activeModal) {
|
|
|
22100
21086
|
modalButtons: normalizeModalButtons(activeModal.buttons)
|
|
22101
21087
|
};
|
|
22102
21088
|
}
|
|
22103
|
-
function buildNextChatCursor(cursor, result) {
|
|
22104
|
-
return {
|
|
22105
|
-
knownMessageCount: Math.max(0, Number(result.totalMessages || cursor.knownMessageCount)),
|
|
22106
|
-
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : cursor.lastMessageSignature,
|
|
22107
|
-
tailLimit: cursor.tailLimit
|
|
22108
|
-
};
|
|
22109
|
-
}
|
|
22110
21089
|
function prepareSessionChatTailUpdate(input) {
|
|
22111
21090
|
const result = input.result;
|
|
22112
|
-
if (!result?.success
|
|
21091
|
+
if (!result?.success) {
|
|
22113
21092
|
return {
|
|
22114
|
-
cursor:
|
|
21093
|
+
cursor: input.cursor,
|
|
22115
21094
|
seq: input.seq,
|
|
22116
21095
|
lastDeliveredSignature: input.lastDeliveredSignature,
|
|
22117
21096
|
update: null
|
|
22118
21097
|
};
|
|
22119
21098
|
}
|
|
22120
|
-
const
|
|
22121
|
-
const cursor = {
|
|
22122
|
-
knownMessageCount: Math.max(0, Number(result.totalMessages || 0)),
|
|
22123
|
-
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : "",
|
|
22124
|
-
tailLimit: input.cursor.tailLimit
|
|
22125
|
-
};
|
|
21099
|
+
const messages = Array.isArray(result.messages) ? result.messages : [];
|
|
22126
21100
|
const title = typeof result.title === "string" ? result.title : void 0;
|
|
22127
21101
|
const activeModal = normalizeChatTailActiveModal(result.activeModal);
|
|
22128
21102
|
const status = typeof result.status === "string" ? result.status : "idle";
|
|
22129
21103
|
const deliverySignature = buildChatTailDeliverySignature({
|
|
22130
21104
|
sessionId: input.sessionId,
|
|
22131
21105
|
...input.historySessionId ? { historySessionId: input.historySessionId } : {},
|
|
22132
|
-
messages
|
|
21106
|
+
messages,
|
|
22133
21107
|
status,
|
|
22134
21108
|
...title ? { title } : {},
|
|
22135
|
-
...activeModal ? { activeModal } : {}
|
|
22136
|
-
syncMode,
|
|
22137
|
-
replaceFrom: Number(result.replaceFrom || 0),
|
|
22138
|
-
totalMessages: Number(result.totalMessages || 0),
|
|
22139
|
-
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
|
|
21109
|
+
...activeModal ? { activeModal } : {}
|
|
22140
21110
|
});
|
|
22141
21111
|
const seq = input.seq + 1;
|
|
22142
21112
|
if (deliverySignature === input.lastDeliveredSignature) {
|
|
22143
21113
|
return {
|
|
22144
|
-
cursor,
|
|
21114
|
+
cursor: input.cursor,
|
|
22145
21115
|
seq,
|
|
22146
21116
|
lastDeliveredSignature: input.lastDeliveredSignature,
|
|
22147
21117
|
update: null
|
|
22148
21118
|
};
|
|
22149
21119
|
}
|
|
22150
21120
|
return {
|
|
22151
|
-
cursor,
|
|
21121
|
+
cursor: input.cursor,
|
|
22152
21122
|
seq,
|
|
22153
21123
|
lastDeliveredSignature: deliverySignature,
|
|
22154
21124
|
update: {
|
|
@@ -22159,14 +21129,10 @@ function prepareSessionChatTailUpdate(input) {
|
|
|
22159
21129
|
...input.interactionId ? { interactionId: input.interactionId } : {},
|
|
22160
21130
|
seq,
|
|
22161
21131
|
timestamp: input.timestamp,
|
|
22162
|
-
messages
|
|
21132
|
+
messages,
|
|
22163
21133
|
status,
|
|
22164
21134
|
...title ? { title } : {},
|
|
22165
|
-
...activeModal ? { activeModal } : {}
|
|
22166
|
-
syncMode,
|
|
22167
|
-
replaceFrom: Number(result.replaceFrom || 0),
|
|
22168
|
-
totalMessages: Number(result.totalMessages || 0),
|
|
22169
|
-
lastMessageSignature: typeof result.lastMessageSignature === "string" ? result.lastMessageSignature : ""
|
|
21135
|
+
...activeModal ? { activeModal } : {}
|
|
22170
21136
|
}
|
|
22171
21137
|
};
|
|
22172
21138
|
}
|
|
@@ -22226,8 +21192,6 @@ async function runAsyncBatch(items, worker, options = {}) {
|
|
|
22226
21192
|
}
|
|
22227
21193
|
|
|
22228
21194
|
// src/agent-stream/provider-adapter.ts
|
|
22229
|
-
init_read_chat_contract();
|
|
22230
|
-
init_chat_message_normalization();
|
|
22231
21195
|
var ProviderStreamAdapter = class {
|
|
22232
21196
|
agentType;
|
|
22233
21197
|
agentName;
|
|
@@ -22912,7 +21876,6 @@ var DaemonAgentStreamManager = class {
|
|
|
22912
21876
|
|
|
22913
21877
|
// src/agent-stream/poller.ts
|
|
22914
21878
|
init_logger();
|
|
22915
|
-
init_chat_message_normalization();
|
|
22916
21879
|
var AgentStreamPoller = class {
|
|
22917
21880
|
deps;
|
|
22918
21881
|
timer = null;
|
|
@@ -23391,10 +22354,6 @@ var ProviderInstanceManager = class {
|
|
|
23391
22354
|
}
|
|
23392
22355
|
};
|
|
23393
22356
|
|
|
23394
|
-
// src/index.ts
|
|
23395
|
-
init_io_contracts();
|
|
23396
|
-
init_chat_message_normalization();
|
|
23397
|
-
|
|
23398
22357
|
// src/providers/version-archive.ts
|
|
23399
22358
|
import * as fs11 from "fs";
|
|
23400
22359
|
import * as path21 from "path";
|
|
@@ -26832,7 +25791,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26832
25791
|
lines.push("Provider category: `cli`");
|
|
26833
25792
|
lines.push("");
|
|
26834
25793
|
const funcToFile = {
|
|
26835
|
-
|
|
25794
|
+
parseSession: "parse_session.js",
|
|
26836
25795
|
detectStatus: "detect_status.js",
|
|
26837
25796
|
parseApproval: "parse_approval.js"
|
|
26838
25797
|
};
|
|
@@ -26921,7 +25880,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
26921
25880
|
lines.push("");
|
|
26922
25881
|
lines.push("| Function | Input | Return |");
|
|
26923
25882
|
lines.push("|---|---|---|");
|
|
26924
|
-
lines.push("| `
|
|
25883
|
+
lines.push("| `parseSession` | `{ buffer, rawBuffer, recentBuffer, screenText, messages, partialResponse }` | `{ id, status, title, messages, activeModal }` |");
|
|
26925
25884
|
lines.push("| `detectStatus` | `{ tail, screenText, rawBuffer }` | `idle`, `generating`, `waiting_approval`, or `error` |");
|
|
26926
25885
|
lines.push("| `parseApproval` | `{ buffer, rawBuffer, tail }` | `{ message, buttons }` or `null` |");
|
|
26927
25886
|
lines.push("");
|
|
@@ -27141,7 +26100,7 @@ function buildCliAutoImplPrompt(ctx, type, provider, providerDir, functions, ref
|
|
|
27141
26100
|
lines.push("");
|
|
27142
26101
|
lines.push("## Required Validation");
|
|
27143
26102
|
lines.push("1. Confirm `detectStatus` changes sensibly between startup, generating, approval, and idle.");
|
|
27144
|
-
lines.push("2. Confirm `
|
|
26103
|
+
lines.push("2. Confirm `parseSession` produces a stable transcript without duplicating past turns when the PTY redraws.");
|
|
27145
26104
|
lines.push("3. Confirm the latest assistant message streams through `partialResponse` while generation is in progress.");
|
|
27146
26105
|
lines.push("4. Confirm approval parsing returns meaningful button labels when the CLI requests permission.");
|
|
27147
26106
|
lines.push("5. Confirm the Python file was actually created and executed, not just described in chat text.");
|
|
@@ -28411,7 +27370,7 @@ var DevServer = class _DevServer {
|
|
|
28411
27370
|
lines.push("Provider category: `cli`");
|
|
28412
27371
|
lines.push("");
|
|
28413
27372
|
const funcToFile = {
|
|
28414
|
-
|
|
27373
|
+
parseSession: "parse_session.js",
|
|
28415
27374
|
detectStatus: "detect_status.js",
|
|
28416
27375
|
parseApproval: "parse_approval.js"
|
|
28417
27376
|
};
|
|
@@ -28500,7 +27459,7 @@ var DevServer = class _DevServer {
|
|
|
28500
27459
|
lines.push("");
|
|
28501
27460
|
lines.push("| Function | Input | Return |");
|
|
28502
27461
|
lines.push("|---|---|---|");
|
|
28503
|
-
lines.push("| `
|
|
27462
|
+
lines.push("| `parseSession` | `{ buffer, rawBuffer, recentBuffer, screenText, messages, partialResponse }` | `{ id, status, title, messages, activeModal }` |");
|
|
28504
27463
|
lines.push("| `detectStatus` | `{ tail, screenText, rawBuffer }` | `idle`, `generating`, `waiting_approval`, or `error` |");
|
|
28505
27464
|
lines.push("| `parseApproval` | `{ buffer, rawBuffer, tail }` | `{ message, buttons }` or `null` |");
|
|
28506
27465
|
lines.push("");
|
|
@@ -28595,7 +27554,7 @@ var DevServer = class _DevServer {
|
|
|
28595
27554
|
lines.push("");
|
|
28596
27555
|
lines.push("## Required Validation");
|
|
28597
27556
|
lines.push("1. Confirm `detectStatus` changes sensibly between startup, generating, approval, and idle.");
|
|
28598
|
-
lines.push("2. Confirm `
|
|
27557
|
+
lines.push("2. Confirm `parseSession` produces a stable transcript without duplicating past turns when the PTY redraws.");
|
|
28599
27558
|
lines.push("3. Confirm the latest assistant message streams through `partialResponse` while generation is in progress.");
|
|
28600
27559
|
lines.push("4. Confirm approval parsing returns meaningful button labels when the CLI requests permission.");
|
|
28601
27560
|
lines.push("5. Confirm the Python file was actually created and executed, not just described in chat text.");
|