@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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@meistrari/chat-nuxt",
3
3
  "configKey": "chatNuxt",
4
- "version": "4.6.0-rc.4",
4
+ "version": "4.6.0-rc.5",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "unknown"
@@ -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 displayToolUse = computed(() => typeof props.step === "string" ? null : withReportedToolInput(props.step.toolUse, props.step.toolResult));
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 (typeof props.step === "string")
33
+ if (!toolGroup.value)
33
34
  return null;
34
- return resolveToolDisplay(props.step.toolUse);
35
+ return resolveToolDisplay(toolGroup.value.toolUse);
35
36
  });
36
37
  const stepWasExecuted = computed(
37
- () => typeof props.step !== "string" && props.step.toolResult !== void 0 && !props.isActive
38
+ () => toolGroup.value?.toolResult !== void 0 && !props.isActive
38
39
  );
39
40
  const stepMeta = computed(() => {
40
- if (typeof props.step === "string")
41
+ if (!toolGroup.value)
41
42
  return null;
42
43
  return resolveToolMeta(displayToolUse.value);
43
44
  });
44
45
  const stepTitle = computed(() => {
45
- if (typeof props.step === "string")
46
+ if (!toolGroup.value)
46
47
  return "";
47
- return resolveToolTitle(props.step.toolUse, stepWasExecuted.value);
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 thinkingTexts = /* @__PURE__ */ new Set();
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 ((part.type === "text" || part.type === "thinking") && typeof part.text === "string") {
121
- if (part.type === "text")
122
- answerParts.push(part.text);
123
- if (part.type === "thinking")
124
- thinkingTexts.add(part.text);
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
- if (part.type === "text")
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), thinkingTexts, currentAnswerParts, currentAnswerStepTexts };
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) && !parsed.thinkingTexts.has(step)) {
212
+ if (typeof step === "string" && currentAnswerMatches && parsed.currentAnswerStepTexts.has(step)) {
202
213
  continue;
203
214
  }
204
215
  renderedSteps.add(key);
@@ -1,5 +1,7 @@
1
1
  export function getReasoningStepKey(step, index) {
2
2
  if (typeof step === "string")
3
3
  return `text-${index}`;
4
+ if (step.type === "thinking")
5
+ return `thinking-${index}`;
4
6
  return `tool-${step.toolUse.id}`;
5
7
  }
@@ -14,7 +14,11 @@ export type ToolGroup = {
14
14
  toolUse: ToolUse;
15
15
  toolResult?: ToolResult;
16
16
  };
17
- export type ReasoningStep = string | ToolGroup;
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: 'text', text: text + delta }, timestamp));
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meistrari/chat-nuxt",
3
- "version": "4.6.0-rc.4",
3
+ "version": "4.6.0-rc.5",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": {