@meistrari/chat-nuxt 4.5.1-rc.2 → 4.5.1-rc.4
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/module.json +1 -1
- package/dist/runtime/citations/citation-links.js +1 -1
- package/dist/runtime/conversations/components/chat-new-conversation-modal.d.vue.ts +1 -1
- package/dist/runtime/conversations/components/chat-new-conversation-modal.vue.d.ts +1 -1
- package/dist/runtime/embed/components/mobile/chat-mobile-header.d.vue.ts +6 -6
- package/dist/runtime/embed/components/mobile/chat-mobile-header.vue.d.ts +6 -6
- package/dist/runtime/embed/components/mobile/chat-mobile-shell.d.vue.ts +10 -10
- package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue.d.ts +10 -10
- package/dist/runtime/lightweight/messages/composables/use-direct-stream.js +2 -2
- package/dist/runtime/messages/components/chat-debug-workbench.vue +3 -3
- package/dist/runtime/messages/composables/chat.js +2 -6
- package/dist/runtime/messages/debug/chat-debug-scenarios.d.ts +15 -0
- package/dist/runtime/messages/debug/chat-debug-scenarios.js +138 -0
- package/dist/runtime/messages/stream-overlay.d.ts +9 -0
- package/dist/runtime/messages/stream-overlay.js +8 -0
- package/dist/runtime/types/schemas/integrations/lightweight.d.ts +1 -0
- package/dist/runtime/types/schemas/integrations/lightweight.js +12 -0
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -54,7 +54,7 @@ function parsePositiveInt(value) {
|
|
|
54
54
|
export function citationCacheKey(ref) {
|
|
55
55
|
return `${ref.namespace}/${ref.id}`;
|
|
56
56
|
}
|
|
57
|
-
const BARE_CITE_REWRITE_REGEX = /\[[ \t]*(cite:\/\/[^\s"'<>`\[\]()*~]+)[ \t]*\](?!\()|(?<!\]\()(?<!<)(?<!\]:[ \t]*)(cite:\/\/[^\s"'<>`\[\]()*~]+)(?!\]\()/gi;
|
|
57
|
+
const BARE_CITE_REWRITE_REGEX = /\[[ \t]*(cite:\/\/[^\s"'<>`\[\]()*~]+)[ \t]*\](?!\()|(?<!\]\()(?<!<)(?<!\]:[ \t]*)(cite:\/\/[^\s"'<>`\[\]()*~]+)(?![^\s"'<>`\[\]()*~])(?!\]\()/gi;
|
|
58
58
|
const MARKDOWN_CODE_REGEX = /(```|~~~)[\s\S]*?(?:\1|$)|``+[^`]*``+|`[^`]*`/g;
|
|
59
59
|
export function linkifyBareCitations(text) {
|
|
60
60
|
if (!text.toLowerCase().includes(CITE_SCHEME))
|
|
@@ -6,8 +6,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
6
6
|
} & {
|
|
7
7
|
create: (canvasTools: CanvasTool[]) => any;
|
|
8
8
|
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
9
|
-
onCreate?: ((canvasTools: CanvasTool[]) => any) | undefined;
|
|
10
9
|
"onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
|
|
10
|
+
onCreate?: ((canvasTools: CanvasTool[]) => any) | undefined;
|
|
11
11
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
12
|
declare const _default: typeof __VLS_export;
|
|
13
13
|
export default _default;
|
|
@@ -6,8 +6,8 @@ declare const __VLS_export: import("vue").DefineComponent<__VLS_ModelProps, {},
|
|
|
6
6
|
} & {
|
|
7
7
|
create: (canvasTools: CanvasTool[]) => any;
|
|
8
8
|
}, string, import("vue").PublicProps, Readonly<__VLS_ModelProps> & Readonly<{
|
|
9
|
-
onCreate?: ((canvasTools: CanvasTool[]) => any) | undefined;
|
|
10
9
|
"onUpdate:modelValue"?: ((value: boolean | undefined) => any) | undefined;
|
|
10
|
+
onCreate?: ((canvasTools: CanvasTool[]) => any) | undefined;
|
|
11
11
|
}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
12
12
|
declare const _default: typeof __VLS_export;
|
|
13
13
|
export default _default;
|
|
@@ -15,23 +15,23 @@ type __VLS_Props = {
|
|
|
15
15
|
};
|
|
16
16
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
17
17
|
delete: () => any;
|
|
18
|
-
openDrawer: () => any;
|
|
19
|
-
copyLink: () => any;
|
|
20
|
-
openOutdatedSettings: () => any;
|
|
21
18
|
rename: () => any;
|
|
22
19
|
duplicate: () => any;
|
|
23
20
|
export: () => any;
|
|
21
|
+
copyLink: () => any;
|
|
24
22
|
debug: () => any;
|
|
23
|
+
openDrawer: () => any;
|
|
24
|
+
openOutdatedSettings: () => any;
|
|
25
25
|
tabChange: (tab: TopbarTab) => any;
|
|
26
26
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
27
27
|
onDelete?: (() => any) | undefined;
|
|
28
|
-
onOpenDrawer?: (() => any) | undefined;
|
|
29
|
-
onCopyLink?: (() => any) | undefined;
|
|
30
|
-
onOpenOutdatedSettings?: (() => any) | undefined;
|
|
31
28
|
onRename?: (() => any) | undefined;
|
|
32
29
|
onDuplicate?: (() => any) | undefined;
|
|
33
30
|
onExport?: (() => any) | undefined;
|
|
31
|
+
onCopyLink?: (() => any) | undefined;
|
|
34
32
|
onDebug?: (() => any) | undefined;
|
|
33
|
+
onOpenDrawer?: (() => any) | undefined;
|
|
34
|
+
onOpenOutdatedSettings?: (() => any) | undefined;
|
|
35
35
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
36
36
|
}>, {
|
|
37
37
|
showDrawerButton: boolean;
|
|
@@ -15,23 +15,23 @@ type __VLS_Props = {
|
|
|
15
15
|
};
|
|
16
16
|
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {} & {
|
|
17
17
|
delete: () => any;
|
|
18
|
-
openDrawer: () => any;
|
|
19
|
-
copyLink: () => any;
|
|
20
|
-
openOutdatedSettings: () => any;
|
|
21
18
|
rename: () => any;
|
|
22
19
|
duplicate: () => any;
|
|
23
20
|
export: () => any;
|
|
21
|
+
copyLink: () => any;
|
|
24
22
|
debug: () => any;
|
|
23
|
+
openDrawer: () => any;
|
|
24
|
+
openOutdatedSettings: () => any;
|
|
25
25
|
tabChange: (tab: TopbarTab) => any;
|
|
26
26
|
}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
27
27
|
onDelete?: (() => any) | undefined;
|
|
28
|
-
onOpenDrawer?: (() => any) | undefined;
|
|
29
|
-
onCopyLink?: (() => any) | undefined;
|
|
30
|
-
onOpenOutdatedSettings?: (() => any) | undefined;
|
|
31
28
|
onRename?: (() => any) | undefined;
|
|
32
29
|
onDuplicate?: (() => any) | undefined;
|
|
33
30
|
onExport?: (() => any) | undefined;
|
|
31
|
+
onCopyLink?: (() => any) | undefined;
|
|
34
32
|
onDebug?: (() => any) | undefined;
|
|
33
|
+
onOpenDrawer?: (() => any) | undefined;
|
|
34
|
+
onOpenOutdatedSettings?: (() => any) | undefined;
|
|
35
35
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
36
36
|
}>, {
|
|
37
37
|
showDrawerButton: boolean;
|
|
@@ -61,13 +61,14 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
61
61
|
} & {
|
|
62
62
|
delete: () => any;
|
|
63
63
|
cancel: () => any;
|
|
64
|
-
settings: () => any;
|
|
65
|
-
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
66
|
-
copyLink: () => any;
|
|
67
64
|
rename: () => any;
|
|
68
65
|
duplicate: () => any;
|
|
69
66
|
export: () => any;
|
|
67
|
+
copyLink: () => any;
|
|
70
68
|
debug: () => any;
|
|
69
|
+
selectConversation: (id: string) => any;
|
|
70
|
+
settings: () => any;
|
|
71
|
+
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
71
72
|
tabChange: (tab: TopbarTab) => any;
|
|
72
73
|
newConversation: (groupId?: string | null | undefined) => any;
|
|
73
74
|
switchWorkspace: () => any;
|
|
@@ -75,22 +76,22 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
75
76
|
cancelEditing: () => any;
|
|
76
77
|
dismissOutdatedBanner: () => any;
|
|
77
78
|
saveTitle: () => any;
|
|
78
|
-
selectConversation: (id: string) => any;
|
|
79
79
|
"update:drawerOpen": (value: boolean) => any;
|
|
80
80
|
"update:editTitle": (value: string) => any;
|
|
81
81
|
"update:workspaceSheetOpen": (value: boolean) => any;
|
|
82
82
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
83
83
|
onDelete?: (() => any) | undefined;
|
|
84
84
|
onCancel?: (() => any) | undefined;
|
|
85
|
-
onSettings?: (() => any) | undefined;
|
|
86
|
-
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
87
|
-
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
88
|
-
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
89
|
-
onCopyLink?: (() => any) | undefined;
|
|
90
85
|
onRename?: (() => any) | undefined;
|
|
91
86
|
onDuplicate?: (() => any) | undefined;
|
|
92
87
|
onExport?: (() => any) | undefined;
|
|
88
|
+
onCopyLink?: (() => any) | undefined;
|
|
93
89
|
onDebug?: (() => any) | undefined;
|
|
90
|
+
onSelectConversation?: ((id: string) => any) | undefined;
|
|
91
|
+
onSettings?: (() => any) | undefined;
|
|
92
|
+
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
93
|
+
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
94
|
+
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
94
95
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
95
96
|
onNewConversation?: ((groupId?: string | null | undefined) => any) | undefined;
|
|
96
97
|
onSwitchWorkspace?: (() => any) | undefined;
|
|
@@ -98,7 +99,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
98
99
|
onCancelEditing?: (() => any) | undefined;
|
|
99
100
|
onDismissOutdatedBanner?: (() => any) | undefined;
|
|
100
101
|
onSaveTitle?: (() => any) | undefined;
|
|
101
|
-
onSelectConversation?: ((id: string) => any) | undefined;
|
|
102
102
|
"onUpdate:drawerOpen"?: ((value: boolean) => any) | undefined;
|
|
103
103
|
"onUpdate:editTitle"?: ((value: string) => any) | undefined;
|
|
104
104
|
"onUpdate:workspaceSheetOpen"?: ((value: boolean) => any) | undefined;
|
|
@@ -61,13 +61,14 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
61
61
|
} & {
|
|
62
62
|
delete: () => any;
|
|
63
63
|
cancel: () => any;
|
|
64
|
-
settings: () => any;
|
|
65
|
-
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
66
|
-
copyLink: () => any;
|
|
67
64
|
rename: () => any;
|
|
68
65
|
duplicate: () => any;
|
|
69
66
|
export: () => any;
|
|
67
|
+
copyLink: () => any;
|
|
70
68
|
debug: () => any;
|
|
69
|
+
selectConversation: (id: string) => any;
|
|
70
|
+
settings: () => any;
|
|
71
|
+
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
71
72
|
tabChange: (tab: TopbarTab) => any;
|
|
72
73
|
newConversation: (groupId?: string | null | undefined) => any;
|
|
73
74
|
switchWorkspace: () => any;
|
|
@@ -75,22 +76,22 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
75
76
|
cancelEditing: () => any;
|
|
76
77
|
dismissOutdatedBanner: () => any;
|
|
77
78
|
saveTitle: () => any;
|
|
78
|
-
selectConversation: (id: string) => any;
|
|
79
79
|
"update:drawerOpen": (value: boolean) => any;
|
|
80
80
|
"update:editTitle": (value: string) => any;
|
|
81
81
|
"update:workspaceSheetOpen": (value: boolean) => any;
|
|
82
82
|
}, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
|
|
83
83
|
onDelete?: (() => any) | undefined;
|
|
84
84
|
onCancel?: (() => any) | undefined;
|
|
85
|
-
onSettings?: (() => any) | undefined;
|
|
86
|
-
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
87
|
-
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
88
|
-
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
89
|
-
onCopyLink?: (() => any) | undefined;
|
|
90
85
|
onRename?: (() => any) | undefined;
|
|
91
86
|
onDuplicate?: (() => any) | undefined;
|
|
92
87
|
onExport?: (() => any) | undefined;
|
|
88
|
+
onCopyLink?: (() => any) | undefined;
|
|
93
89
|
onDebug?: (() => any) | undefined;
|
|
90
|
+
onSelectConversation?: ((id: string) => any) | undefined;
|
|
91
|
+
onSettings?: (() => any) | undefined;
|
|
92
|
+
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
93
|
+
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
94
|
+
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
94
95
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
95
96
|
onNewConversation?: ((groupId?: string | null | undefined) => any) | undefined;
|
|
96
97
|
onSwitchWorkspace?: (() => any) | undefined;
|
|
@@ -98,7 +99,6 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
98
99
|
onCancelEditing?: (() => any) | undefined;
|
|
99
100
|
onDismissOutdatedBanner?: (() => any) | undefined;
|
|
100
101
|
onSaveTitle?: (() => any) | undefined;
|
|
101
|
-
onSelectConversation?: ((id: string) => any) | undefined;
|
|
102
102
|
"onUpdate:drawerOpen"?: ((value: boolean) => any) | undefined;
|
|
103
103
|
"onUpdate:editTitle"?: ((value: string) => any) | undefined;
|
|
104
104
|
"onUpdate:workspaceSheetOpen"?: ((value: boolean) => any) | undefined;
|
|
@@ -7,12 +7,12 @@ export function createMessagePartsAccumulator(runId = null) {
|
|
|
7
7
|
}
|
|
8
8
|
export function applyMessagePartsEvent(accumulator, input) {
|
|
9
9
|
if (input.harness !== "lightweight" && accumulator.lightweight?.runId !== input.runId)
|
|
10
|
-
return { text: accumulator.lightweight?.
|
|
10
|
+
return { text: accumulator.lightweight?.stepText ?? "", thinking: accumulator.lightweight?.thinking ?? "", changed: false };
|
|
11
11
|
if (accumulator.lightweight?.runId !== input.runId)
|
|
12
12
|
accumulator.lightweight = createLightweightTurn(input.runId, input.sessionId ?? "");
|
|
13
13
|
accumulator.runId = input.runId;
|
|
14
14
|
const changed = applyLightweightPart(accumulator.lightweight, input.event, input.deltaSeq, input.timestamp ?? 0);
|
|
15
|
-
return { text: accumulator.lightweight.
|
|
15
|
+
return { text: accumulator.lightweight.stepText, thinking: accumulator.lightweight.thinking, changed, reasoning: accumulator.lightweight.reasoning, files: accumulator.lightweight.files };
|
|
16
16
|
}
|
|
17
17
|
export function useDirectStream(options = {}) {
|
|
18
18
|
return useDirectStreamWithProtocol({
|
|
@@ -3,8 +3,8 @@ import ChatDebugConversationRail from "./chat-debug-conversation-rail.vue";
|
|
|
3
3
|
import ChatMessageList from "./chat-message-list.vue";
|
|
4
4
|
import { provideEmbedConfig } from "../../embed/composables/embed-config";
|
|
5
5
|
import { createChatDebugCitationsConfig } from "../debug/chat-debug-citations";
|
|
6
|
-
import { createReasoningCache
|
|
7
|
-
import { createChatDebugScenarios } from "../debug/chat-debug-scenarios";
|
|
6
|
+
import { createReasoningCache } from "../message-reasoning";
|
|
7
|
+
import { createChatDebugScenarios, resolveChatDebugDisplayMessages } from "../debug/chat-debug-scenarios";
|
|
8
8
|
import { useChatDebugDiagnostics, useChatDebugWindowListenerProbe } from "../debug/use-chat-debug-diagnostics";
|
|
9
9
|
import { formatChatDebugTime as formatTime, useChatDebugPlayback } from "../debug/use-chat-debug-playback";
|
|
10
10
|
const scenarios = createChatDebugScenarios();
|
|
@@ -52,7 +52,7 @@ const { diagnostics, reset: resetDiagnostics, recordFrame } = useChatDebugDiagno
|
|
|
52
52
|
});
|
|
53
53
|
const windowListeners = useChatDebugWindowListenerProbe();
|
|
54
54
|
const reasoningCache = createReasoningCache();
|
|
55
|
-
const displayMessages = computed(() => selectedScenario.value
|
|
55
|
+
const displayMessages = computed(() => resolveChatDebugDisplayMessages(selectedScenario.value, playbackState.value, reasoningCache));
|
|
56
56
|
const reasoningCacheEntries = ref(0);
|
|
57
57
|
watch(displayMessages, () => {
|
|
58
58
|
reasoningCacheEntries.value = reasoningCache.bySignature.size;
|
|
@@ -27,6 +27,7 @@ import { CHAT_PREPARING_STEPS, nextChatPreparingStepDelay } from "../../embed/lo
|
|
|
27
27
|
import { usePolling } from "../../shared/composables/polling.js";
|
|
28
28
|
import { ChatMessageStatus, terminalMessageTransitions, useChatMessageTerminal } from "./chat-message-terminal.js";
|
|
29
29
|
import { useDirectStream } from "./use-direct-stream.js";
|
|
30
|
+
import { overlayStreamedMessage } from "../stream-overlay.js";
|
|
30
31
|
import { useOutboundQueue } from "./outbound-queue.js";
|
|
31
32
|
const POLL_OUTAGE_NOTICE_FAILURES = 5;
|
|
32
33
|
const POLL_OUTAGE_BUDGET_MS = 6e4;
|
|
@@ -219,12 +220,7 @@ export function useChat(options = {}, adapter = {}) {
|
|
|
219
220
|
const content = directStream.streamingText.value;
|
|
220
221
|
const reasoning = directStream.streamingReasoning?.value ?? [];
|
|
221
222
|
const files = directStream.streamingFiles?.value ?? [];
|
|
222
|
-
const overlaid = !messageId || content === null && !reasoning.length && !files.length ? messages.value : messages.value.map((message) => message.id === messageId && (message.status === "pending" || pendingStreamReconciliationIds.value.has(message.id)) ? {
|
|
223
|
-
...message,
|
|
224
|
-
content: content === null ? message.content : content,
|
|
225
|
-
...reasoning.length ? { reasoningData: reasoning } : {},
|
|
226
|
-
...files.length ? { files: files.map((file) => ({ ...file })) } : {}
|
|
227
|
-
} : message);
|
|
223
|
+
const overlaid = !messageId || content === null && !reasoning.length && !files.length ? messages.value : messages.value.map((message) => message.id === messageId && (message.status === "pending" || pendingStreamReconciliationIds.value.has(message.id)) ? overlayStreamedMessage(message, { content, reasoning, files }) : message);
|
|
228
224
|
return resolveReasoningDisplayMessages(overlaid, reasoningCache);
|
|
229
225
|
});
|
|
230
226
|
const stopCondition = computed(
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Conversation, Message } from '../../types/schemas/chat/conversations.js';
|
|
2
|
+
import { type ReasoningCache } from '../message-reasoning.js';
|
|
2
3
|
export type ChatDebugEventTone = 'neutral' | 'user' | 'assistant' | 'reasoning' | 'tool' | 'error';
|
|
3
4
|
type ChatDebugEventBase = {
|
|
4
5
|
id: string;
|
|
@@ -20,6 +21,9 @@ export type ChatDebugEvent = ChatDebugEventBase & ({
|
|
|
20
21
|
type: 'conversation.switch';
|
|
21
22
|
conversationId: string;
|
|
22
23
|
messages: Message[];
|
|
24
|
+
} | {
|
|
25
|
+
type: 'stream.part';
|
|
26
|
+
part: Record<string, unknown>;
|
|
23
27
|
});
|
|
24
28
|
/** One switchable conversation of a sidebar fixture: identity plus its full history. */
|
|
25
29
|
export type ChatDebugConversationFixture = {
|
|
@@ -50,17 +54,28 @@ export type ChatDebugScenario = {
|
|
|
50
54
|
* like production. Absent means the fixture ships pre-parsed steps.
|
|
51
55
|
*/
|
|
52
56
|
reasoningFormat?: 'raw';
|
|
57
|
+
/**
|
|
58
|
+
* Harness whose stream adapter turns `stream.part` events into the pending
|
|
59
|
+
* message's text and reasoning, exactly like the embed's direct stream.
|
|
60
|
+
*/
|
|
61
|
+
streamHarness?: 'lightweight';
|
|
53
62
|
};
|
|
54
63
|
export type ChatDebugPlaybackState = {
|
|
55
64
|
messages: Message[];
|
|
56
65
|
loading: boolean;
|
|
57
66
|
streamingActiveMessageId: string | null;
|
|
67
|
+
streamParts: Record<string, unknown>[];
|
|
58
68
|
preparingSteps: string[] | null;
|
|
59
69
|
activeConversationId: string | null;
|
|
60
70
|
};
|
|
61
71
|
export declare const EMPTY_CHAT_DEBUG_PLAYBACK_STATE: ChatDebugPlaybackState;
|
|
62
72
|
export declare function applyChatDebugEvent(state: ChatDebugPlaybackState, event: ChatDebugEvent): ChatDebugPlaybackState;
|
|
63
73
|
export declare function resolveChatDebugPlayback(scenario: ChatDebugScenario, elapsedMs: number): ChatDebugPlaybackState;
|
|
74
|
+
/**
|
|
75
|
+
* What the stage renders: streamed parts go through the harness's real
|
|
76
|
+
* adapter, and raw reasoning through the production resolution.
|
|
77
|
+
*/
|
|
78
|
+
export declare function resolveChatDebugDisplayMessages(scenario: ChatDebugScenario, state: ChatDebugPlaybackState, cache: ReasoningCache): Message[];
|
|
64
79
|
export declare function countAppliedChatDebugEvents(scenario: ChatDebugScenario, elapsedMs: number): number;
|
|
65
80
|
export declare function createChatDebugScenarios(baseTime?: number): ChatDebugScenario[];
|
|
66
81
|
export {};
|
|
@@ -4,10 +4,15 @@ var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", { value: __f
|
|
|
4
4
|
var _a;
|
|
5
5
|
import { CHAT_PREPARING_STEPS } from "../../embed/loading-messages.js";
|
|
6
6
|
import { createConversationSwitchScenario } from "./chat-debug-switch-scenario.js";
|
|
7
|
+
import { applyLightweightPart, createLightweightTurn } from "../../types/schemas/integrations/lightweight.js";
|
|
8
|
+
import { applyMessagePartsEvent as applyLightweightEvent, createMessagePartsAccumulator as createLightweightAccumulator } from "../../lightweight/messages/composables/use-direct-stream.js";
|
|
9
|
+
import { resolveReasoningDisplayMessages } from "../message-reasoning.js";
|
|
10
|
+
import { overlayStreamedMessage } from "../stream-overlay.js";
|
|
7
11
|
export const EMPTY_CHAT_DEBUG_PLAYBACK_STATE = {
|
|
8
12
|
messages: [],
|
|
9
13
|
loading: false,
|
|
10
14
|
streamingActiveMessageId: null,
|
|
15
|
+
streamParts: [],
|
|
11
16
|
preparingSteps: null,
|
|
12
17
|
activeConversationId: null
|
|
13
18
|
};
|
|
@@ -25,6 +30,7 @@ export function applyChatDebugEvent(state, event2) {
|
|
|
25
30
|
messages: event2.messages.map(cloneMessage),
|
|
26
31
|
loading: false,
|
|
27
32
|
streamingActiveMessageId: null,
|
|
33
|
+
streamParts: [],
|
|
28
34
|
preparingSteps: null,
|
|
29
35
|
activeConversationId: event2.conversationId
|
|
30
36
|
};
|
|
@@ -38,6 +44,8 @@ export function applyChatDebugEvent(state, event2) {
|
|
|
38
44
|
preparingSteps
|
|
39
45
|
};
|
|
40
46
|
}
|
|
47
|
+
if (event2.type === "stream.part")
|
|
48
|
+
return { ...state, streamParts: [...state.streamParts, event2.part] };
|
|
41
49
|
if (event2.type === "message.patch") {
|
|
42
50
|
return {
|
|
43
51
|
...state,
|
|
@@ -68,6 +76,31 @@ export function resolveChatDebugPlayback(scenario, elapsedMs) {
|
|
|
68
76
|
}
|
|
69
77
|
return state;
|
|
70
78
|
}
|
|
79
|
+
function overlayLightweightStream(state) {
|
|
80
|
+
if (!state.streamingActiveMessageId || state.streamParts.length === 0)
|
|
81
|
+
return state.messages;
|
|
82
|
+
const accumulator = createLightweightAccumulator();
|
|
83
|
+
let update = { text: "", thinking: "", changed: false };
|
|
84
|
+
state.streamParts.forEach((part, deltaSeq) => {
|
|
85
|
+
update = applyLightweightEvent(accumulator, {
|
|
86
|
+
kind: "message-parts",
|
|
87
|
+
harness: "lightweight",
|
|
88
|
+
sessionId: "debug-session",
|
|
89
|
+
runId: "debug-run",
|
|
90
|
+
deltaSeq,
|
|
91
|
+
event: part
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
return state.messages.map((message2) => message2.id === state.streamingActiveMessageId && message2.status === "pending" ? overlayStreamedMessage(message2, {
|
|
95
|
+
content: update.text,
|
|
96
|
+
reasoning: "reasoning" in update ? [...update.reasoning] : [],
|
|
97
|
+
files: "files" in update ? [...update.files] : []
|
|
98
|
+
}) : message2);
|
|
99
|
+
}
|
|
100
|
+
export function resolveChatDebugDisplayMessages(scenario, state, cache) {
|
|
101
|
+
const messages = scenario.streamHarness === "lightweight" ? overlayLightweightStream(state) : state.messages;
|
|
102
|
+
return scenario.reasoningFormat === "raw" ? resolveReasoningDisplayMessages(messages, cache) : messages;
|
|
103
|
+
}
|
|
71
104
|
export function countAppliedChatDebugEvents(scenario, elapsedMs) {
|
|
72
105
|
let count = 0;
|
|
73
106
|
for (const event2 of scenario.events) {
|
|
@@ -494,12 +527,48 @@ function sessionWakeOpeningEvents(input) {
|
|
|
494
527
|
})
|
|
495
528
|
];
|
|
496
529
|
}
|
|
530
|
+
const LIGHTWEIGHT_THOUGHT_FIRST = "O usu\xE1rio quer que eu pesquise as not\xEDcias de hoje.";
|
|
531
|
+
const LIGHTWEIGHT_INTERIM_TEXT = "Vou usar a skill de not\xEDcias para isso.";
|
|
532
|
+
const LIGHTWEIGHT_THOUGHT_SECOND = "J\xE1 tenho as manchetes do dia. Vou organizar por tema.";
|
|
533
|
+
const LIGHTWEIGHT_ANSWER = [
|
|
534
|
+
"Aqui est\xE3o as not\xEDcias de hoje:",
|
|
535
|
+
"",
|
|
536
|
+
"- **Economia:** o Copom manteve a Selic em 10,50% ao ano.",
|
|
537
|
+
"- **Tecnologia:** o governo publicou a regulamenta\xE7\xE3o do uso de IA no setor p\xFAblico.",
|
|
538
|
+
"- **Esportes:** a sele\xE7\xE3o confirmou os convocados para as Eliminat\xF3rias."
|
|
539
|
+
].join("\n");
|
|
540
|
+
const LIGHTWEIGHT_STREAM_PARTS = [
|
|
541
|
+
[600, "Step starts", { type: "start-step" }],
|
|
542
|
+
[900, "Reasoning delta", { type: "reasoning-delta", id: "r0", text: LIGHTWEIGHT_THOUGHT_FIRST.slice(0, 30) }],
|
|
543
|
+
[1500, "Reasoning delta", { type: "reasoning-delta", id: "r0", text: LIGHTWEIGHT_THOUGHT_FIRST.slice(30) }],
|
|
544
|
+
[2300, "Text delta", { type: "text-delta", id: "t0", delta: LIGHTWEIGHT_INTERIM_TEXT.slice(0, 28) }],
|
|
545
|
+
[2800, "Text delta", { type: "text-delta", id: "t0", delta: LIGHTWEIGHT_INTERIM_TEXT.slice(28) }],
|
|
546
|
+
[3300, "Skill call", { type: "tool-call", toolCallId: "lightweight-news-skill", toolName: "Skill", input: { skill: "noticias" } }],
|
|
547
|
+
[3300, "Step finishes", { type: "finish-step" }],
|
|
548
|
+
[4300, "Skill result", { type: "tool-result", toolCallId: "lightweight-news-skill", toolName: "Skill", output: "Manchetes de economia, tecnologia e esportes." }],
|
|
549
|
+
[4600, "Step starts", { type: "start-step" }],
|
|
550
|
+
[5e3, "Reasoning delta", { type: "reasoning-delta", id: "r1", text: LIGHTWEIGHT_THOUGHT_SECOND.slice(0, 30) }],
|
|
551
|
+
[5600, "Reasoning delta", { type: "reasoning-delta", id: "r1", text: LIGHTWEIGHT_THOUGHT_SECOND.slice(30) }],
|
|
552
|
+
[6300, "Text delta", { type: "text-delta", id: "t1", delta: LIGHTWEIGHT_ANSWER.slice(0, 90) }],
|
|
553
|
+
[7100, "Text delta", { type: "text-delta", id: "t1", delta: LIGHTWEIGHT_ANSWER.slice(90) }],
|
|
554
|
+
[7500, "Step finishes", { type: "finish-step" }]
|
|
555
|
+
];
|
|
556
|
+
function lightweightPersistedReasoning() {
|
|
557
|
+
const turn = createLightweightTurn("debug-run", "debug-session");
|
|
558
|
+
LIGHTWEIGHT_STREAM_PARTS.forEach(([, , part], sequence) => applyLightweightPart(turn, part, sequence, 0));
|
|
559
|
+
return turn.reasoning;
|
|
560
|
+
}
|
|
497
561
|
export function createChatDebugScenarios(baseTime = Date.now()) {
|
|
498
562
|
const streamingMessage = message(baseTime, 650, {
|
|
499
563
|
id: "streaming-assistant",
|
|
500
564
|
role: "assistant",
|
|
501
565
|
status: "pending"
|
|
502
566
|
});
|
|
567
|
+
const lightweightMessage = message(baseTime, 0, {
|
|
568
|
+
id: "lightweight-assistant",
|
|
569
|
+
role: "assistant",
|
|
570
|
+
status: "pending"
|
|
571
|
+
});
|
|
503
572
|
const wakeMessage = message(baseTime, 0, {
|
|
504
573
|
id: "wake-assistant",
|
|
505
574
|
role: "assistant",
|
|
@@ -693,6 +762,75 @@ export function createChatDebugScenarios(baseTime = Date.now()) {
|
|
|
693
762
|
})
|
|
694
763
|
]
|
|
695
764
|
},
|
|
765
|
+
{
|
|
766
|
+
id: "lightweight-stream",
|
|
767
|
+
name: "Lightweight stream",
|
|
768
|
+
intent: "Lightweight parts through the real adapter: each step shows only its own text, like the Claude harness.",
|
|
769
|
+
durationMs: 8600,
|
|
770
|
+
reasoningFormat: "raw",
|
|
771
|
+
streamHarness: "lightweight",
|
|
772
|
+
events: [
|
|
773
|
+
event({
|
|
774
|
+
id: "lightweight-user",
|
|
775
|
+
atMs: 0,
|
|
776
|
+
label: "User message",
|
|
777
|
+
tone: "user",
|
|
778
|
+
type: "message.upsert",
|
|
779
|
+
message: message(baseTime, 0, {
|
|
780
|
+
id: "lightweight-user-message",
|
|
781
|
+
role: "user",
|
|
782
|
+
content: "Quais s\xE3o as not\xEDcias de hoje?"
|
|
783
|
+
})
|
|
784
|
+
}),
|
|
785
|
+
event({
|
|
786
|
+
id: "lightweight-pending",
|
|
787
|
+
atMs: 0,
|
|
788
|
+
label: "Assistant pending",
|
|
789
|
+
tone: "assistant",
|
|
790
|
+
type: "message.upsert",
|
|
791
|
+
message: lightweightMessage
|
|
792
|
+
}),
|
|
793
|
+
event({
|
|
794
|
+
id: "lightweight-stream-open",
|
|
795
|
+
atMs: 300,
|
|
796
|
+
label: "Stream opens",
|
|
797
|
+
tone: "neutral",
|
|
798
|
+
type: "playback.patch",
|
|
799
|
+
patch: { streamingActiveMessageId: lightweightMessage.id }
|
|
800
|
+
}),
|
|
801
|
+
...LIGHTWEIGHT_STREAM_PARTS.map(([atMs, label, part], index) => event({
|
|
802
|
+
id: `lightweight-part-${index}`,
|
|
803
|
+
atMs,
|
|
804
|
+
label,
|
|
805
|
+
tone: part.type === "tool-call" || part.type === "tool-result" ? "tool" : part.type === "reasoning-delta" ? "reasoning" : "assistant",
|
|
806
|
+
type: "stream.part",
|
|
807
|
+
part
|
|
808
|
+
})),
|
|
809
|
+
event({
|
|
810
|
+
id: "lightweight-complete",
|
|
811
|
+
atMs: 7900,
|
|
812
|
+
label: "Message completed",
|
|
813
|
+
tone: "assistant",
|
|
814
|
+
type: "message.patch",
|
|
815
|
+
messageId: lightweightMessage.id,
|
|
816
|
+
patch: {
|
|
817
|
+
status: "completed",
|
|
818
|
+
content: LIGHTWEIGHT_ANSWER,
|
|
819
|
+
reasoningData: lightweightPersistedReasoning(),
|
|
820
|
+
updatedAt: new Date(baseTime + 7900),
|
|
821
|
+
generationEndedAt: new Date(baseTime + 7900)
|
|
822
|
+
}
|
|
823
|
+
}),
|
|
824
|
+
event({
|
|
825
|
+
id: "lightweight-stream-close",
|
|
826
|
+
atMs: 7900,
|
|
827
|
+
label: "Stream closes",
|
|
828
|
+
tone: "neutral",
|
|
829
|
+
type: "playback.patch",
|
|
830
|
+
patch: { streamingActiveMessageId: null }
|
|
831
|
+
})
|
|
832
|
+
]
|
|
833
|
+
},
|
|
696
834
|
{
|
|
697
835
|
id: "session-wake",
|
|
698
836
|
name: "Session wake",
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { Message } from '../types/schemas/chat/conversations.js';
|
|
2
|
+
import type { MessageFile } from '../types/schemas/chat/files.js';
|
|
3
|
+
import type { DeepReadonly } from 'vue';
|
|
4
|
+
export type StreamOverlay = {
|
|
5
|
+
content: string | null;
|
|
6
|
+
reasoning: DeepReadonly<unknown[]>;
|
|
7
|
+
files: DeepReadonly<MessageFile[]>;
|
|
8
|
+
};
|
|
9
|
+
export declare function overlayStreamedMessage(message: Message, stream: StreamOverlay): Message;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export function overlayStreamedMessage(message, stream) {
|
|
2
|
+
return {
|
|
3
|
+
...message,
|
|
4
|
+
content: stream.content === null ? message.content : stream.content,
|
|
5
|
+
...stream.reasoning.length ? { reasoningData: stream.reasoning } : {},
|
|
6
|
+
...stream.files.length ? { files: stream.files.map((file) => ({ ...file })) } : {}
|
|
7
|
+
};
|
|
8
|
+
}
|
|
@@ -57,6 +57,10 @@ export function createLightweightTurn(runId, sessionId) {
|
|
|
57
57
|
sessionId,
|
|
58
58
|
lastSequence: -1,
|
|
59
59
|
text: '',
|
|
60
|
+
// Text of the current provider step only, the equivalent of the Claude
|
|
61
|
+
// harness's current assistant message: an interim line gives way to the
|
|
62
|
+
// next step instead of prefixing the answer.
|
|
63
|
+
stepText: '',
|
|
60
64
|
pendingText: '',
|
|
61
65
|
thinking: '',
|
|
62
66
|
reasoning: [],
|
|
@@ -76,8 +80,16 @@ export function applyLightweightPart(state, part, sequence, timestamp) {
|
|
|
76
80
|
return false;
|
|
77
81
|
state.lastSequence = sequence;
|
|
78
82
|
const delta = typeof part.delta === 'string' ? part.delta : typeof part.text === 'string' ? part.text : '';
|
|
83
|
+
// Deliberately empties the answer slot until this step's own text arrives,
|
|
84
|
+
// exactly as the Claude harness does at message_start; the finished step's
|
|
85
|
+
// interim line is already in the reasoning timeline.
|
|
86
|
+
if (part.type === 'start-step') {
|
|
87
|
+
state.stepText = '';
|
|
88
|
+
return true;
|
|
89
|
+
}
|
|
79
90
|
if (part.type === 'text-delta') {
|
|
80
91
|
state.text += delta;
|
|
92
|
+
state.stepText += delta;
|
|
81
93
|
state.pendingText += delta;
|
|
82
94
|
state.files = lightweightFiles([state.toolFiles, state.text]);
|
|
83
95
|
return true;
|