@meistrari/chat-nuxt 4.6.0-rc.4 → 4.6.0-rc.5
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/embed/components/mobile/chat-mobile-shell.d.vue.ts +2 -2
- package/dist/runtime/embed/components/mobile/chat-mobile-shell.vue.d.ts +2 -2
- package/dist/runtime/messages/components/reasoning/chat-reasoning-message.vue +23 -7
- package/dist/runtime/messages/components/reasoning/chat-reasoning-thought.vue +3 -0
- package/dist/runtime/messages/message-reasoning.d.ts +0 -1
- package/dist/runtime/messages/message-reasoning.js +21 -10
- package/dist/runtime/messages/reasoning-step-key.js +2 -0
- package/dist/runtime/messages/reasoning.d.ts +5 -1
- package/dist/runtime/types/schemas/integrations/lightweight.js +2 -2
- package/package.json +1 -1
package/dist/module.json
CHANGED
|
@@ -67,8 +67,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
67
67
|
copyLink: () => any;
|
|
68
68
|
debug: () => any;
|
|
69
69
|
selectConversation: (id: string) => any;
|
|
70
|
-
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
71
70
|
settings: () => any;
|
|
71
|
+
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
72
72
|
tabChange: (tab: TopbarTab) => any;
|
|
73
73
|
newConversation: (groupId?: string | null | undefined) => any;
|
|
74
74
|
switchWorkspace: () => any;
|
|
@@ -88,8 +88,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
88
88
|
onCopyLink?: (() => any) | undefined;
|
|
89
89
|
onDebug?: (() => any) | undefined;
|
|
90
90
|
onSelectConversation?: ((id: string) => any) | undefined;
|
|
91
|
-
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
92
91
|
onSettings?: (() => any) | undefined;
|
|
92
|
+
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
93
93
|
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
94
94
|
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
95
95
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
@@ -67,8 +67,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
67
67
|
copyLink: () => any;
|
|
68
68
|
debug: () => any;
|
|
69
69
|
selectConversation: (id: string) => any;
|
|
70
|
-
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
71
70
|
settings: () => any;
|
|
71
|
+
send: (content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any;
|
|
72
72
|
tabChange: (tab: TopbarTab) => any;
|
|
73
73
|
newConversation: (groupId?: string | null | undefined) => any;
|
|
74
74
|
switchWorkspace: () => any;
|
|
@@ -88,8 +88,8 @@ declare const __VLS_base: import("vue").DefineComponent<__VLS_PublicProps, {}, {
|
|
|
88
88
|
onCopyLink?: (() => any) | undefined;
|
|
89
89
|
onDebug?: (() => any) | undefined;
|
|
90
90
|
onSelectConversation?: ((id: string) => any) | undefined;
|
|
91
|
-
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
92
91
|
onSettings?: (() => any) | undefined;
|
|
92
|
+
onSend?: ((content: string, files: FileUploadInput[], agentInputs?: TelaAgentExecutionInput[] | undefined) => any) | undefined;
|
|
93
93
|
"onUpdate:selectedModel"?: ((value: string | null) => any) | undefined;
|
|
94
94
|
"onUpdate:selectedReasoningEffort"?: ((value: any) => any) | undefined;
|
|
95
95
|
onTabChange?: ((tab: TopbarTab) => any) | undefined;
|
|
@@ -27,24 +27,25 @@ const TOOL_WIDGETS = {
|
|
|
27
27
|
"grep": ChatGrepWidget,
|
|
28
28
|
"generic": ChatGenericToolWidget
|
|
29
29
|
};
|
|
30
|
-
const
|
|
30
|
+
const toolGroup = computed(() => typeof props.step !== "string" && props.step.type === "tool_group" ? props.step : null);
|
|
31
|
+
const displayToolUse = computed(() => toolGroup.value ? withReportedToolInput(toolGroup.value.toolUse, toolGroup.value.toolResult) : null);
|
|
31
32
|
const toolDisplay = computed(() => {
|
|
32
|
-
if (
|
|
33
|
+
if (!toolGroup.value)
|
|
33
34
|
return null;
|
|
34
|
-
return resolveToolDisplay(
|
|
35
|
+
return resolveToolDisplay(toolGroup.value.toolUse);
|
|
35
36
|
});
|
|
36
37
|
const stepWasExecuted = computed(
|
|
37
|
-
() =>
|
|
38
|
+
() => toolGroup.value?.toolResult !== void 0 && !props.isActive
|
|
38
39
|
);
|
|
39
40
|
const stepMeta = computed(() => {
|
|
40
|
-
if (
|
|
41
|
+
if (!toolGroup.value)
|
|
41
42
|
return null;
|
|
42
43
|
return resolveToolMeta(displayToolUse.value);
|
|
43
44
|
});
|
|
44
45
|
const stepTitle = computed(() => {
|
|
45
|
-
if (
|
|
46
|
+
if (!toolGroup.value)
|
|
46
47
|
return "";
|
|
47
|
-
return resolveToolTitle(
|
|
48
|
+
return resolveToolTitle(toolGroup.value.toolUse, stepWasExecuted.value);
|
|
48
49
|
});
|
|
49
50
|
</script>
|
|
50
51
|
|
|
@@ -61,6 +62,21 @@ const stepTitle = computed(() => {
|
|
|
61
62
|
/>
|
|
62
63
|
</div>
|
|
63
64
|
|
|
65
|
+
<div v-else-if="step.type === 'thinking'" class="chat-reasoning-step">
|
|
66
|
+
<ChatReasoningToolRow
|
|
67
|
+
:title="isActive && !completed ? 'Pensando' : 'Pensou'"
|
|
68
|
+
has-result
|
|
69
|
+
:is-active="isActive && !completed"
|
|
70
|
+
>
|
|
71
|
+
<ChatThinkingWidget
|
|
72
|
+
class="chat-reasoning-thinking-detail"
|
|
73
|
+
:content="step.text"
|
|
74
|
+
:is-active="isActive"
|
|
75
|
+
:completed="completed"
|
|
76
|
+
/>
|
|
77
|
+
</ChatReasoningToolRow>
|
|
78
|
+
</div>
|
|
79
|
+
|
|
64
80
|
<div v-else class="chat-reasoning-step">
|
|
65
81
|
<ChatReasoningToolRow
|
|
66
82
|
:title="stepTitle"
|
|
@@ -34,6 +34,9 @@ const currentStepName = computed(() => {
|
|
|
34
34
|
if (step && typeof step !== "string" && step.type === "tool_group") {
|
|
35
35
|
return resolveToolTitle(step.toolUse, false);
|
|
36
36
|
}
|
|
37
|
+
if (step && typeof step !== "string" && step.type === "thinking") {
|
|
38
|
+
return "Pensando";
|
|
39
|
+
}
|
|
37
40
|
if (step && typeof step === "string") {
|
|
38
41
|
const truncated = step.length > TEXT_TRUNCATE_LENGTH ? `${step.slice(0, TEXT_TRUNCATE_LENGTH)}...` : step;
|
|
39
42
|
return truncated;
|
|
@@ -2,7 +2,6 @@ import type { Message } from '../types/schemas/chat/conversations.js';
|
|
|
2
2
|
import type { ReasoningStep } from './reasoning.js';
|
|
3
3
|
type ParsedReasoning = {
|
|
4
4
|
steps: ReasoningStep[];
|
|
5
|
-
thinkingTexts: Set<string>;
|
|
6
5
|
currentAnswerParts: string[];
|
|
7
6
|
currentAnswerStepTexts: Set<string>;
|
|
8
7
|
};
|
|
@@ -7,6 +7,8 @@ export function createReasoningCache() {
|
|
|
7
7
|
function getReasoningStepKey(step) {
|
|
8
8
|
if (typeof step === "string")
|
|
9
9
|
return `text:${step.slice(0, 100)}`;
|
|
10
|
+
if (step.type === "thinking")
|
|
11
|
+
return `thinking:${step.text.slice(0, 100)}`;
|
|
10
12
|
return `tool:${step.toolUse.id}`;
|
|
11
13
|
}
|
|
12
14
|
function groupReasoningSteps(parsedSteps) {
|
|
@@ -15,6 +17,14 @@ function groupReasoningSteps(parsedSteps) {
|
|
|
15
17
|
for (const step of parsedSteps) {
|
|
16
18
|
if (typeof step === "string") {
|
|
17
19
|
grouped.push(step);
|
|
20
|
+
} else if ("type" in step) {
|
|
21
|
+
const previous = grouped.at(-1);
|
|
22
|
+
if (typeof previous === "object" && previous.type === "thinking")
|
|
23
|
+
grouped[grouped.length - 1] = { type: "thinking", text: `${previous.text}
|
|
24
|
+
|
|
25
|
+
${step.text}` };
|
|
26
|
+
else
|
|
27
|
+
grouped.push(step);
|
|
18
28
|
} else if ("name" in step && "input" in step) {
|
|
19
29
|
pendingToolUses.set(step.id, step);
|
|
20
30
|
grouped.push({
|
|
@@ -77,7 +87,7 @@ function parseReasoningFromPolling(reasoning) {
|
|
|
77
87
|
const allSteps = [];
|
|
78
88
|
const seenContentIds = /* @__PURE__ */ new Set();
|
|
79
89
|
const seenTexts = /* @__PURE__ */ new Set();
|
|
80
|
-
const
|
|
90
|
+
const seenThoughts = /* @__PURE__ */ new Set();
|
|
81
91
|
let currentAnswerParts = [];
|
|
82
92
|
let currentAnswerStepTexts = /* @__PURE__ */ new Set();
|
|
83
93
|
for (const item of reasoning) {
|
|
@@ -117,17 +127,18 @@ function parseReasoningFromPolling(reasoning) {
|
|
|
117
127
|
if (!contentPart || typeof contentPart !== "object")
|
|
118
128
|
continue;
|
|
119
129
|
const part = contentPart;
|
|
120
|
-
if (
|
|
121
|
-
if (part.
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
130
|
+
if (part.type === "thinking" && typeof part.text === "string") {
|
|
131
|
+
if (seenThoughts.has(part.text))
|
|
132
|
+
continue;
|
|
133
|
+
seenThoughts.add(part.text);
|
|
134
|
+
allSteps.push({ type: "thinking", text: part.text });
|
|
135
|
+
} else if (part.type === "text" && typeof part.text === "string") {
|
|
136
|
+
answerParts.push(part.text);
|
|
125
137
|
if (seenTexts.has(part.text))
|
|
126
138
|
continue;
|
|
127
139
|
seenTexts.add(part.text);
|
|
128
140
|
allSteps.push(part.text);
|
|
129
|
-
|
|
130
|
-
answerStepTexts.add(part.text);
|
|
141
|
+
answerStepTexts.add(part.text);
|
|
131
142
|
} else if (part.type === "tool_use" && part.id && part.name) {
|
|
132
143
|
const toolId = part.id;
|
|
133
144
|
if (seenContentIds.has(`tool_use:${toolId}`))
|
|
@@ -183,7 +194,7 @@ function parseReasoningFromPolling(reasoning) {
|
|
|
183
194
|
});
|
|
184
195
|
}
|
|
185
196
|
}
|
|
186
|
-
return { steps: groupReasoningSteps(allSteps),
|
|
197
|
+
return { steps: groupReasoningSteps(allSteps), currentAnswerParts, currentAnswerStepTexts };
|
|
187
198
|
}
|
|
188
199
|
export function resolveReasoningDisplayMessages(messages, cache = createReasoningCache()) {
|
|
189
200
|
pruneReasoningCache(cache, messages);
|
|
@@ -198,7 +209,7 @@ export function resolveReasoningDisplayMessages(messages, cache = createReasonin
|
|
|
198
209
|
const key = getReasoningStepKey(step);
|
|
199
210
|
if (renderedSteps.has(key))
|
|
200
211
|
continue;
|
|
201
|
-
if (typeof step === "string" && currentAnswerMatches && parsed.currentAnswerStepTexts.has(step)
|
|
212
|
+
if (typeof step === "string" && currentAnswerMatches && parsed.currentAnswerStepTexts.has(step)) {
|
|
202
213
|
continue;
|
|
203
214
|
}
|
|
204
215
|
renderedSteps.add(key);
|
|
@@ -14,7 +14,11 @@ export type ToolGroup = {
|
|
|
14
14
|
toolUse: ToolUse;
|
|
15
15
|
toolResult?: ToolResult;
|
|
16
16
|
};
|
|
17
|
-
export type
|
|
17
|
+
export type ThinkingStep = {
|
|
18
|
+
type: 'thinking';
|
|
19
|
+
text: string;
|
|
20
|
+
};
|
|
21
|
+
export type ReasoningStep = string | ToolGroup | ThinkingStep;
|
|
18
22
|
/**
|
|
19
23
|
* A turn that is still working towards its first output has no reasoning of its
|
|
20
24
|
* own yet, so the preparing steps stand in. That makes the wait read as an agent
|
|
@@ -99,7 +99,7 @@ export function applyLightweightPart(state, part, sequence, timestamp) {
|
|
|
99
99
|
const id = `${state.runId}:thinking:${typeof part.id === 'string' ? part.id : 'default'}`;
|
|
100
100
|
const existing = state.reasoning.find(item => item.uuid === id)?.message.content[0];
|
|
101
101
|
const text = existing && 'text' in existing && typeof existing.text === 'string' ? existing.text : '';
|
|
102
|
-
upsertReasoning(state, reasoningItem(state.sessionId, id, { type: '
|
|
102
|
+
upsertReasoning(state, reasoningItem(state.sessionId, id, { type: 'thinking', text: text + delta }, timestamp));
|
|
103
103
|
return true;
|
|
104
104
|
}
|
|
105
105
|
if (part.type === 'tool-call' && typeof part.toolCallId === 'string') {
|
|
@@ -134,7 +134,7 @@ export function lightweightThreadReasoning(sessionId, runId, events) {
|
|
|
134
134
|
for (const [index, event] of events.entries()) {
|
|
135
135
|
const timestamp = typeof event.timestamp === 'number' ? event.timestamp : 0;
|
|
136
136
|
if ((event.type === 'thinking' || event.type === 'text') && typeof event.text === 'string') {
|
|
137
|
-
upsertReasoning(state, reasoningItem(sessionId, `${runId}:${event.type}:${event.sequenceIndex ?? index}`, { type: 'text', text: event.text }, timestamp));
|
|
137
|
+
upsertReasoning(state, reasoningItem(sessionId, `${runId}:${event.type}:${event.sequenceIndex ?? index}`, { type: event.type === 'thinking' ? 'thinking' : 'text', text: event.text }, timestamp));
|
|
138
138
|
}
|
|
139
139
|
else if (event.type === 'tool_call') {
|
|
140
140
|
applyLightweightPart(state, { type: 'tool-call', toolCallId: event.callId, toolName: event.toolName, input: event.arguments }, index, timestamp);
|