@dudousxd/nestjs-agent-react 0.8.0 → 0.9.0
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/README.md +15 -0
- package/dist/index.cjs +255 -162
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +33 -1
- package/dist/index.d.ts +33 -1
- package/dist/index.js +160 -70
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.cts
CHANGED
|
@@ -345,6 +345,12 @@ interface TranscriptReasoningBlock {
|
|
|
345
345
|
key: string;
|
|
346
346
|
text: string;
|
|
347
347
|
isStreaming: boolean;
|
|
348
|
+
/**
|
|
349
|
+
* How long the model thought, in ms — the backend's measurement once the run closed (live) or as
|
|
350
|
+
* persisted (reloaded). `null` while it still streams, or when nothing was recorded: pair it with
|
|
351
|
+
* `useElapsed(block.isStreaming)` for a ticking label (`block.durationMs ?? elapsed`).
|
|
352
|
+
*/
|
|
353
|
+
durationMs: number | null;
|
|
348
354
|
isOpen: boolean;
|
|
349
355
|
toggle: (open?: boolean) => void;
|
|
350
356
|
}
|
|
@@ -1151,6 +1157,32 @@ interface ComposerAutocomplete {
|
|
|
1151
1157
|
*/
|
|
1152
1158
|
declare function useComposerAutocomplete(options: UseComposerAutocompleteOptions): ComposerAutocomplete;
|
|
1153
1159
|
|
|
1160
|
+
/** The thinking time stamped on a reasoning part, or `null` when it carries none. */
|
|
1161
|
+
declare function readReasoningMs(part: {
|
|
1162
|
+
providerMetadata?: unknown;
|
|
1163
|
+
}): number | null;
|
|
1164
|
+
interface UseElapsedOptions {
|
|
1165
|
+
/** How often the value re-renders while running. Default 1000 — a seconds label needs no more. */
|
|
1166
|
+
intervalMs?: number;
|
|
1167
|
+
/** Injectable clock for tests. */
|
|
1168
|
+
now?: () => number;
|
|
1169
|
+
}
|
|
1170
|
+
/**
|
|
1171
|
+
* Milliseconds since `running` last turned true — ticking while it stays true, frozen at the final
|
|
1172
|
+
* value once it turns false, `0` before it has ever run. Headless: pair it with
|
|
1173
|
+
* {@link formatElapsed} or any label of your own.
|
|
1174
|
+
*
|
|
1175
|
+
* For a reasoning block, prefer the duration the block already carries (`block.durationMs`, the
|
|
1176
|
+
* server's own measurement) and fall back to this only while the block streams:
|
|
1177
|
+
* `block.durationMs ?? elapsed`.
|
|
1178
|
+
*/
|
|
1179
|
+
declare function useElapsed(running: boolean, options?: UseElapsedOptions): number;
|
|
1180
|
+
/**
|
|
1181
|
+
* `"<1s"`, `"4s"`, `"1m 5s"`, `"1h 2m"` — whole units, the shape a "Thought for …" label wants.
|
|
1182
|
+
* Negative or non-finite input reads as `"<1s"` rather than a nonsense figure.
|
|
1183
|
+
*/
|
|
1184
|
+
declare function formatElapsed(ms: number): string;
|
|
1185
|
+
|
|
1154
1186
|
declare function storedMessageToUiMessage(message: StoredMessage): UIMessage;
|
|
1155
1187
|
|
|
1156
1188
|
/**
|
|
@@ -1399,4 +1431,4 @@ declare function useAgentChat(options: UseAgentChatOptions): {
|
|
|
1399
1431
|
clearError: () => void;
|
|
1400
1432
|
};
|
|
1401
1433
|
|
|
1402
|
-
export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type BuildBlocksOptions, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, type ChatStatus, type ChatTranscript, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type ElicitationBlockOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type RetrievedPassage, SPEECH_LANGUAGES, type SettleAction, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type ThreadPatch, type TimestampInfo, type TranscriptActionState, type TranscriptApproval, type TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, type TranscriptElicitationBlock, type TranscriptElicitationOutcome, type TranscriptFile, type TranscriptFilesBlock, type TranscriptItem, type TranscriptItemOptions, type TranscriptQuestion, type TranscriptQuestionOption, type TranscriptReasoningBlock, type TranscriptSettleState, type TranscriptSource, type TranscriptSourcesBlock, type TranscriptStopState, type TranscriptTextBlock, type TranscriptToolBlock, type TranscriptToolCall, type TranscriptUiBlock, type TranscriptWindow, type TriggerMatch, type TriggerPosition, type UsageSummary, type UseAgentChatOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseSpeechRecognitionOptions, type UseTranscriptItemOptions, applyCompletion, backgroundRunsFromThread, buildTranscriptBlocks, createSkillsSource, describeTimestamp, describeUsage, extractMessageText, filterAutocompleteItems, findActiveTrigger, formatRelativeTime, loadStoredSpeechLang, persistSpeechLang, storedMessageToUiMessage, storedThreadToUiMessages, useAgentChat, useChatTranscript, useComposerAutocomplete, useSpeechRecognition, useStickToBottom, useTranscriptItem };
|
|
1434
|
+
export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type BuildBlocksOptions, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, type ChatStatus, type ChatTranscript, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type ElicitationBlockOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type RetrievedPassage, SPEECH_LANGUAGES, type SettleAction, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type ThreadPatch, type TimestampInfo, type TranscriptActionState, type TranscriptApproval, type TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, type TranscriptElicitationBlock, type TranscriptElicitationOutcome, type TranscriptFile, type TranscriptFilesBlock, type TranscriptItem, type TranscriptItemOptions, type TranscriptQuestion, type TranscriptQuestionOption, type TranscriptReasoningBlock, type TranscriptSettleState, type TranscriptSource, type TranscriptSourcesBlock, type TranscriptStopState, type TranscriptTextBlock, type TranscriptToolBlock, type TranscriptToolCall, type TranscriptUiBlock, type TranscriptWindow, type TriggerMatch, type TriggerPosition, type UsageSummary, type UseAgentChatOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseElapsedOptions, type UseSpeechRecognitionOptions, type UseTranscriptItemOptions, applyCompletion, backgroundRunsFromThread, buildTranscriptBlocks, createSkillsSource, describeTimestamp, describeUsage, extractMessageText, filterAutocompleteItems, findActiveTrigger, formatElapsed, formatRelativeTime, loadStoredSpeechLang, persistSpeechLang, readReasoningMs, storedMessageToUiMessage, storedThreadToUiMessages, useAgentChat, useChatTranscript, useComposerAutocomplete, useElapsed, useSpeechRecognition, useStickToBottom, useTranscriptItem };
|
package/dist/index.d.ts
CHANGED
|
@@ -345,6 +345,12 @@ interface TranscriptReasoningBlock {
|
|
|
345
345
|
key: string;
|
|
346
346
|
text: string;
|
|
347
347
|
isStreaming: boolean;
|
|
348
|
+
/**
|
|
349
|
+
* How long the model thought, in ms — the backend's measurement once the run closed (live) or as
|
|
350
|
+
* persisted (reloaded). `null` while it still streams, or when nothing was recorded: pair it with
|
|
351
|
+
* `useElapsed(block.isStreaming)` for a ticking label (`block.durationMs ?? elapsed`).
|
|
352
|
+
*/
|
|
353
|
+
durationMs: number | null;
|
|
348
354
|
isOpen: boolean;
|
|
349
355
|
toggle: (open?: boolean) => void;
|
|
350
356
|
}
|
|
@@ -1151,6 +1157,32 @@ interface ComposerAutocomplete {
|
|
|
1151
1157
|
*/
|
|
1152
1158
|
declare function useComposerAutocomplete(options: UseComposerAutocompleteOptions): ComposerAutocomplete;
|
|
1153
1159
|
|
|
1160
|
+
/** The thinking time stamped on a reasoning part, or `null` when it carries none. */
|
|
1161
|
+
declare function readReasoningMs(part: {
|
|
1162
|
+
providerMetadata?: unknown;
|
|
1163
|
+
}): number | null;
|
|
1164
|
+
interface UseElapsedOptions {
|
|
1165
|
+
/** How often the value re-renders while running. Default 1000 — a seconds label needs no more. */
|
|
1166
|
+
intervalMs?: number;
|
|
1167
|
+
/** Injectable clock for tests. */
|
|
1168
|
+
now?: () => number;
|
|
1169
|
+
}
|
|
1170
|
+
/**
|
|
1171
|
+
* Milliseconds since `running` last turned true — ticking while it stays true, frozen at the final
|
|
1172
|
+
* value once it turns false, `0` before it has ever run. Headless: pair it with
|
|
1173
|
+
* {@link formatElapsed} or any label of your own.
|
|
1174
|
+
*
|
|
1175
|
+
* For a reasoning block, prefer the duration the block already carries (`block.durationMs`, the
|
|
1176
|
+
* server's own measurement) and fall back to this only while the block streams:
|
|
1177
|
+
* `block.durationMs ?? elapsed`.
|
|
1178
|
+
*/
|
|
1179
|
+
declare function useElapsed(running: boolean, options?: UseElapsedOptions): number;
|
|
1180
|
+
/**
|
|
1181
|
+
* `"<1s"`, `"4s"`, `"1m 5s"`, `"1h 2m"` — whole units, the shape a "Thought for …" label wants.
|
|
1182
|
+
* Negative or non-finite input reads as `"<1s"` rather than a nonsense figure.
|
|
1183
|
+
*/
|
|
1184
|
+
declare function formatElapsed(ms: number): string;
|
|
1185
|
+
|
|
1154
1186
|
declare function storedMessageToUiMessage(message: StoredMessage): UIMessage;
|
|
1155
1187
|
|
|
1156
1188
|
/**
|
|
@@ -1399,4 +1431,4 @@ declare function useAgentChat(options: UseAgentChatOptions): {
|
|
|
1399
1431
|
clearError: () => void;
|
|
1400
1432
|
};
|
|
1401
1433
|
|
|
1402
|
-
export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type BuildBlocksOptions, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, type ChatStatus, type ChatTranscript, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type ElicitationBlockOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type RetrievedPassage, SPEECH_LANGUAGES, type SettleAction, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type ThreadPatch, type TimestampInfo, type TranscriptActionState, type TranscriptApproval, type TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, type TranscriptElicitationBlock, type TranscriptElicitationOutcome, type TranscriptFile, type TranscriptFilesBlock, type TranscriptItem, type TranscriptItemOptions, type TranscriptQuestion, type TranscriptQuestionOption, type TranscriptReasoningBlock, type TranscriptSettleState, type TranscriptSource, type TranscriptSourcesBlock, type TranscriptStopState, type TranscriptTextBlock, type TranscriptToolBlock, type TranscriptToolCall, type TranscriptUiBlock, type TranscriptWindow, type TriggerMatch, type TriggerPosition, type UsageSummary, type UseAgentChatOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseSpeechRecognitionOptions, type UseTranscriptItemOptions, applyCompletion, backgroundRunsFromThread, buildTranscriptBlocks, createSkillsSource, describeTimestamp, describeUsage, extractMessageText, filterAutocompleteItems, findActiveTrigger, formatRelativeTime, loadStoredSpeechLang, persistSpeechLang, storedMessageToUiMessage, storedThreadToUiMessages, useAgentChat, useChatTranscript, useComposerAutocomplete, useSpeechRecognition, useStickToBottom, useTranscriptItem };
|
|
1434
|
+
export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type AutocompleteInputProps, type AutocompleteItem, type AutocompleteListboxProps, type AutocompleteOptionProps, type AutocompleteSource, type BackgroundRun, type BuildBlocksOptions, type CancelResult, type ChatBackground, ChatInput, type ChatInputProps, type ChatStatus, type ChatTranscript, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type ElicitationBlockOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type RetrievedPassage, SPEECH_LANGUAGES, type SettleAction, type SkillSuggestionData, type SkillsSourceOptions, type SpeechLanguage, type SpeechRecognitionHook, type StickToBottom, type StickToBottomOptions, type StoredTurnMetadata, type ThreadPatch, type TimestampInfo, type TranscriptActionState, type TranscriptApproval, type TranscriptBlock, type TranscriptCopyState, type TranscriptEditState, type TranscriptElicitationBlock, type TranscriptElicitationOutcome, type TranscriptFile, type TranscriptFilesBlock, type TranscriptItem, type TranscriptItemOptions, type TranscriptQuestion, type TranscriptQuestionOption, type TranscriptReasoningBlock, type TranscriptSettleState, type TranscriptSource, type TranscriptSourcesBlock, type TranscriptStopState, type TranscriptTextBlock, type TranscriptToolBlock, type TranscriptToolCall, type TranscriptUiBlock, type TranscriptWindow, type TriggerMatch, type TriggerPosition, type UsageSummary, type UseAgentChatOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseElapsedOptions, type UseSpeechRecognitionOptions, type UseTranscriptItemOptions, applyCompletion, backgroundRunsFromThread, buildTranscriptBlocks, createSkillsSource, describeTimestamp, describeUsage, extractMessageText, filterAutocompleteItems, findActiveTrigger, formatElapsed, formatRelativeTime, loadStoredSpeechLang, persistSpeechLang, readReasoningMs, storedMessageToUiMessage, storedThreadToUiMessages, useAgentChat, useChatTranscript, useComposerAutocomplete, useElapsed, useSpeechRecognition, useStickToBottom, useTranscriptItem };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,65 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
2
|
var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
|
|
3
3
|
|
|
4
|
+
// src/reasoning/timing.ts
|
|
5
|
+
import { useEffect, useRef, useState } from "react";
|
|
6
|
+
var REASONING_METADATA_KEY = "agent";
|
|
7
|
+
function reasoningDurationMetadata(reasoningMs) {
|
|
8
|
+
return {
|
|
9
|
+
[REASONING_METADATA_KEY]: {
|
|
10
|
+
reasoningMs
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
__name(reasoningDurationMetadata, "reasoningDurationMetadata");
|
|
15
|
+
function readReasoningMs(part) {
|
|
16
|
+
const metadata = part.providerMetadata;
|
|
17
|
+
if (typeof metadata !== "object" || metadata === null) return null;
|
|
18
|
+
const scoped = metadata[REASONING_METADATA_KEY];
|
|
19
|
+
if (typeof scoped !== "object" || scoped === null) return null;
|
|
20
|
+
const value = scoped.reasoningMs;
|
|
21
|
+
return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : null;
|
|
22
|
+
}
|
|
23
|
+
__name(readReasoningMs, "readReasoningMs");
|
|
24
|
+
function useElapsed(running, options = {}) {
|
|
25
|
+
const { intervalMs = 1e3 } = options;
|
|
26
|
+
const nowRef = useRef(options.now ?? Date.now);
|
|
27
|
+
nowRef.current = options.now ?? Date.now;
|
|
28
|
+
const startedAt = useRef(null);
|
|
29
|
+
const [elapsed, setElapsed] = useState(0);
|
|
30
|
+
useEffect(() => {
|
|
31
|
+
if (!running) {
|
|
32
|
+
if (startedAt.current !== null) {
|
|
33
|
+
setElapsed(nowRef.current() - startedAt.current);
|
|
34
|
+
startedAt.current = null;
|
|
35
|
+
}
|
|
36
|
+
return;
|
|
37
|
+
}
|
|
38
|
+
startedAt.current = nowRef.current();
|
|
39
|
+
setElapsed(0);
|
|
40
|
+
const timer = setInterval(() => {
|
|
41
|
+
if (startedAt.current !== null) setElapsed(nowRef.current() - startedAt.current);
|
|
42
|
+
}, intervalMs);
|
|
43
|
+
return () => clearInterval(timer);
|
|
44
|
+
}, [
|
|
45
|
+
running,
|
|
46
|
+
intervalMs
|
|
47
|
+
]);
|
|
48
|
+
return elapsed;
|
|
49
|
+
}
|
|
50
|
+
__name(useElapsed, "useElapsed");
|
|
51
|
+
function formatElapsed(ms) {
|
|
52
|
+
if (!Number.isFinite(ms) || ms < 1e3) return "<1s";
|
|
53
|
+
const totalSeconds = Math.floor(ms / 1e3);
|
|
54
|
+
const hours = Math.floor(totalSeconds / 3600);
|
|
55
|
+
const minutes = Math.floor(totalSeconds % 3600 / 60);
|
|
56
|
+
const seconds = totalSeconds % 60;
|
|
57
|
+
if (hours > 0) return minutes > 0 ? `${hours}h ${minutes}m` : `${hours}h`;
|
|
58
|
+
if (minutes > 0) return seconds > 0 ? `${minutes}m ${seconds}s` : `${minutes}m`;
|
|
59
|
+
return `${seconds}s`;
|
|
60
|
+
}
|
|
61
|
+
__name(formatElapsed, "formatElapsed");
|
|
62
|
+
|
|
4
63
|
// src/agent-chat-transport.ts
|
|
5
64
|
var HEADER_RUN_ID = "x-agent-run-id";
|
|
6
65
|
var HEADER_THREAD_ID = "x-agent-thread-id";
|
|
@@ -158,6 +217,7 @@ var AgentChatTransport = class {
|
|
|
158
217
|
let stepIndex = 0;
|
|
159
218
|
let textId = null;
|
|
160
219
|
let reasoningId = null;
|
|
220
|
+
let reasoningStartedAt = 0;
|
|
161
221
|
let textSeq = 0;
|
|
162
222
|
let reasoningSeq = 0;
|
|
163
223
|
const announced = /* @__PURE__ */ new Set();
|
|
@@ -194,7 +254,7 @@ var AgentChatTransport = class {
|
|
|
194
254
|
if (!stepOpen) openStep();
|
|
195
255
|
}
|
|
196
256
|
__name(ensureStep, "ensureStep");
|
|
197
|
-
function closeRuns() {
|
|
257
|
+
function closeRuns(reasoningMs) {
|
|
198
258
|
if (textId !== null) {
|
|
199
259
|
controller.enqueue({
|
|
200
260
|
type: "text-end",
|
|
@@ -205,15 +265,16 @@ var AgentChatTransport = class {
|
|
|
205
265
|
if (reasoningId !== null) {
|
|
206
266
|
controller.enqueue({
|
|
207
267
|
type: "reasoning-end",
|
|
208
|
-
id: reasoningId
|
|
268
|
+
id: reasoningId,
|
|
269
|
+
providerMetadata: reasoningDurationMetadata(reasoningMs ?? Math.max(0, Date.now() - reasoningStartedAt))
|
|
209
270
|
});
|
|
210
271
|
reasoningId = null;
|
|
211
272
|
}
|
|
212
273
|
}
|
|
213
274
|
__name(closeRuns, "closeRuns");
|
|
214
|
-
function closeStep() {
|
|
275
|
+
function closeStep(reasoningMs) {
|
|
215
276
|
if (!stepOpen) return;
|
|
216
|
-
closeRuns();
|
|
277
|
+
closeRuns(reasoningMs);
|
|
217
278
|
controller.enqueue({
|
|
218
279
|
type: "finish-step"
|
|
219
280
|
});
|
|
@@ -252,7 +313,7 @@ var AgentChatTransport = class {
|
|
|
252
313
|
openStep();
|
|
253
314
|
break;
|
|
254
315
|
case "step-finish":
|
|
255
|
-
closeStep();
|
|
316
|
+
closeStep(event.reasoningMs);
|
|
256
317
|
if (event.costUsd !== void 0) {
|
|
257
318
|
controller.enqueue({
|
|
258
319
|
type: "message-metadata",
|
|
@@ -283,6 +344,7 @@ var AgentChatTransport = class {
|
|
|
283
344
|
if (reasoningId === null) {
|
|
284
345
|
reasoningId = reasoningSeq === 0 ? `rsn-${stepIndex}` : `rsn-${stepIndex}.${reasoningSeq}`;
|
|
285
346
|
reasoningSeq += 1;
|
|
347
|
+
reasoningStartedAt = Date.now();
|
|
286
348
|
controller.enqueue({
|
|
287
349
|
type: "reasoning-start",
|
|
288
350
|
id: reasoningId
|
|
@@ -730,10 +792,10 @@ var AgentClient = class {
|
|
|
730
792
|
};
|
|
731
793
|
|
|
732
794
|
// src/components/chat-input.tsx
|
|
733
|
-
import React2, { useEffect as
|
|
795
|
+
import React2, { useEffect as useEffect3, useState as useState3 } from "react";
|
|
734
796
|
|
|
735
797
|
// src/components/use-speech-recognition.ts
|
|
736
|
-
import { useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
798
|
+
import { useCallback, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState2 } from "react";
|
|
737
799
|
function getRecognitionCtor() {
|
|
738
800
|
if (typeof window === "undefined") return null;
|
|
739
801
|
const scope = window;
|
|
@@ -741,15 +803,15 @@ function getRecognitionCtor() {
|
|
|
741
803
|
}
|
|
742
804
|
__name(getRecognitionCtor, "getRecognitionCtor");
|
|
743
805
|
function useSpeechRecognition({ lang = "en-US", onFinalTranscript, onInterimTranscript }) {
|
|
744
|
-
const recognitionRef =
|
|
745
|
-
const [isListening, setIsListening] =
|
|
806
|
+
const recognitionRef = useRef2(null);
|
|
807
|
+
const [isListening, setIsListening] = useState2(false);
|
|
746
808
|
const ctor = useMemo(() => getRecognitionCtor(), []);
|
|
747
809
|
const isSupported = ctor !== null;
|
|
748
|
-
const finalRef =
|
|
749
|
-
const interimRef =
|
|
810
|
+
const finalRef = useRef2(onFinalTranscript);
|
|
811
|
+
const interimRef = useRef2(onInterimTranscript);
|
|
750
812
|
finalRef.current = onFinalTranscript;
|
|
751
813
|
interimRef.current = onInterimTranscript;
|
|
752
|
-
|
|
814
|
+
useEffect2(() => {
|
|
753
815
|
if (!ctor) return;
|
|
754
816
|
const recognition = new ctor();
|
|
755
817
|
recognition.lang = lang;
|
|
@@ -817,8 +879,8 @@ __name(useSpeechRecognition, "useSpeechRecognition");
|
|
|
817
879
|
|
|
818
880
|
// src/components/chat-input.tsx
|
|
819
881
|
function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = true, speechLang = "en-US", sendLabel = "Send", onStop, isStreaming = false, stopLabel = "Stop generating", className, textareaClassName, sendButtonClassName, micButtonClassName, stopButtonClassName, renderMic }) {
|
|
820
|
-
const [value, setValue] =
|
|
821
|
-
const [interim, setInterim] =
|
|
882
|
+
const [value, setValue] = useState3("");
|
|
883
|
+
const [interim, setInterim] = useState3("");
|
|
822
884
|
const speech = useSpeechRecognition({
|
|
823
885
|
lang: speechLang,
|
|
824
886
|
onFinalTranscript: /* @__PURE__ */ __name((text) => {
|
|
@@ -829,7 +891,7 @@ function ChatInput({ onSubmit, disabled, placeholder, rows = 2, enableSpeech = t
|
|
|
829
891
|
}, "onFinalTranscript"),
|
|
830
892
|
onInterimTranscript: /* @__PURE__ */ __name((text) => setInterim(text), "onInterimTranscript")
|
|
831
893
|
});
|
|
832
|
-
|
|
894
|
+
useEffect3(() => {
|
|
833
895
|
if (!speech.isListening) setInterim("");
|
|
834
896
|
}, [
|
|
835
897
|
speech.isListening
|
|
@@ -896,7 +958,7 @@ __name(ChatInput, "ChatInput");
|
|
|
896
958
|
import React3 from "react";
|
|
897
959
|
|
|
898
960
|
// src/transcript/use-chat-transcript.ts
|
|
899
|
-
import { useCallback as useCallback3, useEffect as
|
|
961
|
+
import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef4, useState as useState5 } from "react";
|
|
900
962
|
|
|
901
963
|
// src/transcript/model.ts
|
|
902
964
|
import { getToolName, isDataUIPart, isFileUIPart, isReasoningUIPart, isTextUIPart, isToolUIPart } from "ai";
|
|
@@ -1017,6 +1079,7 @@ function buildTranscriptBlocks(message, options) {
|
|
|
1017
1079
|
key,
|
|
1018
1080
|
text: part.text,
|
|
1019
1081
|
isStreaming,
|
|
1082
|
+
durationMs: readReasoningMs(part),
|
|
1020
1083
|
isOpen: options.isReasoningOpen(key, isStreaming),
|
|
1021
1084
|
toggle: /* @__PURE__ */ __name((open) => options.toggleReasoning(key, open), "toggle")
|
|
1022
1085
|
});
|
|
@@ -1429,10 +1492,10 @@ function formatCostUsd(cost) {
|
|
|
1429
1492
|
__name(formatCostUsd, "formatCostUsd");
|
|
1430
1493
|
|
|
1431
1494
|
// src/transcript/use-stick-to-bottom.ts
|
|
1432
|
-
import { useCallback as useCallback2, useEffect as
|
|
1495
|
+
import { useCallback as useCallback2, useEffect as useEffect4, useRef as useRef3, useState as useState4 } from "react";
|
|
1433
1496
|
function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
1434
|
-
const containerRef =
|
|
1435
|
-
const [isAtBottom, setIsAtBottom] =
|
|
1497
|
+
const containerRef = useRef3(null);
|
|
1498
|
+
const [isAtBottom, setIsAtBottom] = useState4(true);
|
|
1436
1499
|
const measure = useCallback2(() => {
|
|
1437
1500
|
const element = containerRef.current;
|
|
1438
1501
|
if (!element) {
|
|
@@ -1459,7 +1522,7 @@ function useStickToBottom({ contentKey, threshold = 32 }) {
|
|
|
1459
1522
|
}, [
|
|
1460
1523
|
measure
|
|
1461
1524
|
]);
|
|
1462
|
-
|
|
1525
|
+
useEffect4(() => {
|
|
1463
1526
|
if (isAtBottom) {
|
|
1464
1527
|
scrollToBottom();
|
|
1465
1528
|
}
|
|
@@ -1490,14 +1553,14 @@ var DEFAULT_LOAD_EARLIER_STEP = 50;
|
|
|
1490
1553
|
var DEFAULT_COPY_RESET_MS = 1500;
|
|
1491
1554
|
function useChatTranscript(options) {
|
|
1492
1555
|
const { messages, status, initialVisibleCount = DEFAULT_VISIBLE_COUNT, loadEarlierStep = DEFAULT_LOAD_EARLIER_STEP, followUps, stickToBottomThreshold } = options;
|
|
1493
|
-
const latest =
|
|
1556
|
+
const latest = useRef4(options);
|
|
1494
1557
|
latest.current = options;
|
|
1495
|
-
const [visibleCount, setVisibleCount] =
|
|
1496
|
-
const [stopRequested, setStopRequested] =
|
|
1558
|
+
const [visibleCount, setVisibleCount] = useState5(initialVisibleCount);
|
|
1559
|
+
const [stopRequested, setStopRequested] = useState5(false);
|
|
1497
1560
|
const isStreaming = status === "streaming";
|
|
1498
1561
|
const isBusy = status === "submitted" || isStreaming;
|
|
1499
1562
|
const isEmpty = messages.length === 0;
|
|
1500
|
-
|
|
1563
|
+
useEffect5(() => {
|
|
1501
1564
|
if (!isBusy) {
|
|
1502
1565
|
setStopRequested(false);
|
|
1503
1566
|
}
|
|
@@ -1559,7 +1622,7 @@ function useChatTranscript(options) {
|
|
|
1559
1622
|
__name(useChatTranscript, "useChatTranscript");
|
|
1560
1623
|
function useTranscriptItem(options) {
|
|
1561
1624
|
const { message, isStreaming = false } = options;
|
|
1562
|
-
const messagesRef =
|
|
1625
|
+
const messagesRef = useRef4([
|
|
1563
1626
|
message
|
|
1564
1627
|
]);
|
|
1565
1628
|
if (messagesRef.current[0] !== message) {
|
|
@@ -1577,13 +1640,13 @@ function useTranscriptItem(options) {
|
|
|
1577
1640
|
}
|
|
1578
1641
|
__name(useTranscriptItem, "useTranscriptItem");
|
|
1579
1642
|
function useTranscriptItems({ messages, visibleStart, streamingMessageId, options }) {
|
|
1580
|
-
const [drafts, setDrafts] =
|
|
1581
|
-
const [copied, setCopied] =
|
|
1582
|
-
const [openReasoning, setOpenReasoning] =
|
|
1583
|
-
const [picks, setPicks] =
|
|
1584
|
-
const [settling, setSettling] =
|
|
1585
|
-
const [settleErrors, setSettleErrors] =
|
|
1586
|
-
const latest =
|
|
1643
|
+
const [drafts, setDrafts] = useState5(() => /* @__PURE__ */ new Map());
|
|
1644
|
+
const [copied, setCopied] = useState5(() => /* @__PURE__ */ new Set());
|
|
1645
|
+
const [openReasoning, setOpenReasoning] = useState5(() => /* @__PURE__ */ new Map());
|
|
1646
|
+
const [picks, setPicks] = useState5(() => /* @__PURE__ */ new Map());
|
|
1647
|
+
const [settling, setSettling] = useState5(() => /* @__PURE__ */ new Map());
|
|
1648
|
+
const [settleErrors, setSettleErrors] = useState5(() => /* @__PURE__ */ new Map());
|
|
1649
|
+
const latest = useRef4({
|
|
1587
1650
|
options,
|
|
1588
1651
|
drafts,
|
|
1589
1652
|
picks,
|
|
@@ -1595,15 +1658,15 @@ function useTranscriptItems({ messages, visibleStart, streamingMessageId, option
|
|
|
1595
1658
|
picks,
|
|
1596
1659
|
messages
|
|
1597
1660
|
};
|
|
1598
|
-
const copyTimers =
|
|
1599
|
-
|
|
1661
|
+
const copyTimers = useRef4(/* @__PURE__ */ new Map());
|
|
1662
|
+
useEffect5(() => () => {
|
|
1600
1663
|
for (const timer of copyTimers.current.values()) {
|
|
1601
1664
|
clearTimeout(timer);
|
|
1602
1665
|
}
|
|
1603
1666
|
copyTimers.current.clear();
|
|
1604
1667
|
}, []);
|
|
1605
|
-
const callbackCache =
|
|
1606
|
-
const reasoningToggleCache =
|
|
1668
|
+
const callbackCache = useRef4(/* @__PURE__ */ new Map());
|
|
1669
|
+
const reasoningToggleCache = useRef4(/* @__PURE__ */ new Map());
|
|
1607
1670
|
const toggleReasoning = useCallback3((key, open) => {
|
|
1608
1671
|
setOpenReasoning((current) => {
|
|
1609
1672
|
const next = new Map(current);
|
|
@@ -2332,18 +2395,18 @@ function toItem(entry) {
|
|
|
2332
2395
|
__name(toItem, "toItem");
|
|
2333
2396
|
|
|
2334
2397
|
// src/composer/use-composer-autocomplete.ts
|
|
2335
|
-
import { useCallback as useCallback4, useEffect as
|
|
2398
|
+
import { useCallback as useCallback4, useEffect as useEffect6, useId, useLayoutEffect, useMemo as useMemo2, useRef as useRef5, useState as useState6 } from "react";
|
|
2336
2399
|
function useComposerAutocomplete(options) {
|
|
2337
2400
|
const { value, sources, acceptOnTab = true } = options;
|
|
2338
|
-
const latest =
|
|
2401
|
+
const latest = useRef5(options);
|
|
2339
2402
|
latest.current = options;
|
|
2340
|
-
const inputRef =
|
|
2341
|
-
const [caret, setCaret] =
|
|
2342
|
-
const [items, setItems] =
|
|
2343
|
-
const [isLoading, setLoading] =
|
|
2344
|
-
const [error, setError] =
|
|
2345
|
-
const [activeIndex, setActiveIndex] =
|
|
2346
|
-
const [dismissedIndex, setDismissedIndex] =
|
|
2403
|
+
const inputRef = useRef5(null);
|
|
2404
|
+
const [caret, setCaret] = useState6(value.length);
|
|
2405
|
+
const [items, setItems] = useState6([]);
|
|
2406
|
+
const [isLoading, setLoading] = useState6(false);
|
|
2407
|
+
const [error, setError] = useState6(null);
|
|
2408
|
+
const [activeIndex, setActiveIndex] = useState6(0);
|
|
2409
|
+
const [dismissedIndex, setDismissedIndex] = useState6(null);
|
|
2347
2410
|
const safeCaret = Math.min(caret, value.length);
|
|
2348
2411
|
const match = useMemo2(() => findActiveTrigger(value, safeCaret, sources), [
|
|
2349
2412
|
value,
|
|
@@ -2351,16 +2414,16 @@ function useComposerAutocomplete(options) {
|
|
|
2351
2414
|
sources
|
|
2352
2415
|
]);
|
|
2353
2416
|
const isActive = match !== null && dismissedIndex !== match.index;
|
|
2354
|
-
const matchRef =
|
|
2417
|
+
const matchRef = useRef5(match);
|
|
2355
2418
|
matchRef.current = match;
|
|
2356
|
-
const caretRef =
|
|
2419
|
+
const caretRef = useRef5(safeCaret);
|
|
2357
2420
|
caretRef.current = safeCaret;
|
|
2358
|
-
const itemsRef =
|
|
2421
|
+
const itemsRef = useRef5(items);
|
|
2359
2422
|
itemsRef.current = items;
|
|
2360
|
-
const activeIndexRef =
|
|
2423
|
+
const activeIndexRef = useRef5(activeIndex);
|
|
2361
2424
|
activeIndexRef.current = activeIndex;
|
|
2362
2425
|
const requestKey = isActive && match ? `${match.source.id}\0${match.query}` : null;
|
|
2363
|
-
|
|
2426
|
+
useEffect6(() => {
|
|
2364
2427
|
const current = matchRef.current;
|
|
2365
2428
|
if (requestKey === null || current === null) {
|
|
2366
2429
|
setItems([]);
|
|
@@ -2425,7 +2488,7 @@ function useComposerAutocomplete(options) {
|
|
|
2425
2488
|
const current = matchRef.current;
|
|
2426
2489
|
if (current) setDismissedIndex(current.index);
|
|
2427
2490
|
}, []);
|
|
2428
|
-
const pendingCaret =
|
|
2491
|
+
const pendingCaret = useRef5(null);
|
|
2429
2492
|
const accept = useCallback4((item) => {
|
|
2430
2493
|
const current = matchRef.current;
|
|
2431
2494
|
if (!current) return;
|
|
@@ -2590,6 +2653,16 @@ function refusalReason(result) {
|
|
|
2590
2653
|
__name(refusalReason, "refusalReason");
|
|
2591
2654
|
function storedMessageToUiMessage(message) {
|
|
2592
2655
|
const parts = [];
|
|
2656
|
+
if (message.reasoning) {
|
|
2657
|
+
parts.push({
|
|
2658
|
+
type: "reasoning",
|
|
2659
|
+
text: message.reasoning,
|
|
2660
|
+
state: "done",
|
|
2661
|
+
...message.reasoningMs !== void 0 ? {
|
|
2662
|
+
providerMetadata: reasoningDurationMetadata(message.reasoningMs)
|
|
2663
|
+
} : {}
|
|
2664
|
+
});
|
|
2665
|
+
}
|
|
2593
2666
|
if (message.content) {
|
|
2594
2667
|
parts.push({
|
|
2595
2668
|
type: "text",
|
|
@@ -2604,6 +2677,20 @@ function storedMessageToUiMessage(message) {
|
|
|
2604
2677
|
url: attachment.url
|
|
2605
2678
|
});
|
|
2606
2679
|
}
|
|
2680
|
+
for (const component of message.ui ?? []) {
|
|
2681
|
+
parts.push({
|
|
2682
|
+
type: "data-ui",
|
|
2683
|
+
id: component.id,
|
|
2684
|
+
data: {
|
|
2685
|
+
id: component.id,
|
|
2686
|
+
component: component.component,
|
|
2687
|
+
props: component.props,
|
|
2688
|
+
...component.version !== void 0 ? {
|
|
2689
|
+
version: component.version
|
|
2690
|
+
} : {}
|
|
2691
|
+
}
|
|
2692
|
+
});
|
|
2693
|
+
}
|
|
2607
2694
|
for (const call of message.toolCalls ?? []) {
|
|
2608
2695
|
const result = message.toolResults?.find((candidate) => candidate.id === call.id);
|
|
2609
2696
|
const toolKind2 = call.kind;
|
|
@@ -2706,19 +2793,19 @@ __name(sumUsage, "sumUsage");
|
|
|
2706
2793
|
|
|
2707
2794
|
// src/use-agent-chat.ts
|
|
2708
2795
|
import { useChat } from "@ai-sdk/react";
|
|
2709
|
-
import { useCallback as useCallback5, useEffect as
|
|
2796
|
+
import { useCallback as useCallback5, useEffect as useEffect7, useMemo as useMemo3, useRef as useRef6, useState as useState7 } from "react";
|
|
2710
2797
|
function useAgentChat(options) {
|
|
2711
|
-
const latest =
|
|
2798
|
+
const latest = useRef6(options);
|
|
2712
2799
|
latest.current = options;
|
|
2713
|
-
const [runId, setRunId] =
|
|
2714
|
-
const runIdRef =
|
|
2800
|
+
const [runId, setRunId] = useState7(options.resumeRunId);
|
|
2801
|
+
const runIdRef = useRef6(runId);
|
|
2715
2802
|
runIdRef.current = runId;
|
|
2716
|
-
const settlingRunIdRef =
|
|
2717
|
-
const autoResumeRunIdRef =
|
|
2718
|
-
const [autoResume, setAutoResume] =
|
|
2719
|
-
const [activeRunId, setActiveRunId] =
|
|
2720
|
-
const regenerateNext =
|
|
2721
|
-
const createdThreadId =
|
|
2803
|
+
const settlingRunIdRef = useRef6(void 0);
|
|
2804
|
+
const autoResumeRunIdRef = useRef6(void 0);
|
|
2805
|
+
const [autoResume, setAutoResume] = useState7(false);
|
|
2806
|
+
const [activeRunId, setActiveRunId] = useState7(null);
|
|
2807
|
+
const regenerateNext = useRef6(false);
|
|
2808
|
+
const createdThreadId = useRef6(void 0);
|
|
2722
2809
|
const client = useMemo3(() => {
|
|
2723
2810
|
if (options.client) return options.client;
|
|
2724
2811
|
return new AgentClient({
|
|
@@ -2734,7 +2821,7 @@ function useAgentChat(options) {
|
|
|
2734
2821
|
getHeaders: /* @__PURE__ */ __name(async () => mergeHeaders(latest.current), "getHeaders")
|
|
2735
2822
|
});
|
|
2736
2823
|
}, []);
|
|
2737
|
-
|
|
2824
|
+
useEffect7(() => {
|
|
2738
2825
|
if (!options.resume || options.threadId === void 0) return;
|
|
2739
2826
|
let cancelled = false;
|
|
2740
2827
|
const threadId = options.threadId;
|
|
@@ -2803,7 +2890,7 @@ function useAgentChat(options) {
|
|
|
2803
2890
|
}, "onAttemptStart")
|
|
2804
2891
|
});
|
|
2805
2892
|
}, []);
|
|
2806
|
-
const backgroundRef =
|
|
2893
|
+
const backgroundRef = useRef6(() => Promise.resolve());
|
|
2807
2894
|
const chat = useChat({
|
|
2808
2895
|
transport,
|
|
2809
2896
|
resume: options.resumeRunId !== void 0 || autoResume,
|
|
@@ -2834,9 +2921,9 @@ function useAgentChat(options) {
|
|
|
2834
2921
|
}
|
|
2835
2922
|
}, "onFinish")
|
|
2836
2923
|
});
|
|
2837
|
-
const chatRef =
|
|
2924
|
+
const chatRef = useRef6(chat);
|
|
2838
2925
|
chatRef.current = chat;
|
|
2839
|
-
const turnInFlight =
|
|
2926
|
+
const turnInFlight = useRef6(false);
|
|
2840
2927
|
const isTurnInFlight = useCallback5(() => turnInFlight.current || transport.isAttemptLive, [
|
|
2841
2928
|
transport
|
|
2842
2929
|
]);
|
|
@@ -2856,9 +2943,9 @@ function useAgentChat(options) {
|
|
|
2856
2943
|
toolCallId,
|
|
2857
2944
|
output
|
|
2858
2945
|
}), []);
|
|
2859
|
-
const [threads, setThreads] =
|
|
2860
|
-
const [quota, setQuota] =
|
|
2861
|
-
const [backgroundRuns, setBackgroundRuns] =
|
|
2946
|
+
const [threads, setThreads] = useState7([]);
|
|
2947
|
+
const [quota, setQuota] = useState7(null);
|
|
2948
|
+
const [backgroundRuns, setBackgroundRuns] = useState7([]);
|
|
2862
2949
|
const refreshBackground = useCallback5(async () => {
|
|
2863
2950
|
const threadId = latest.current.threadId ?? createdThreadId.current;
|
|
2864
2951
|
if (threadId === void 0) {
|
|
@@ -2884,7 +2971,7 @@ function useAgentChat(options) {
|
|
|
2884
2971
|
]);
|
|
2885
2972
|
backgroundRef.current = refreshBackground;
|
|
2886
2973
|
const isWorking = backgroundRuns.some((run) => run.status === "running");
|
|
2887
|
-
|
|
2974
|
+
useEffect7(() => {
|
|
2888
2975
|
if (options.background !== true || options.threadId === void 0) {
|
|
2889
2976
|
return;
|
|
2890
2977
|
}
|
|
@@ -2894,7 +2981,7 @@ function useAgentChat(options) {
|
|
|
2894
2981
|
options.threadId,
|
|
2895
2982
|
refreshBackground
|
|
2896
2983
|
]);
|
|
2897
|
-
|
|
2984
|
+
useEffect7(() => {
|
|
2898
2985
|
const every = latest.current.backgroundPollMs ?? 5e3;
|
|
2899
2986
|
if (latest.current.background !== true || !isWorking || every <= 0) {
|
|
2900
2987
|
return;
|
|
@@ -3067,14 +3154,17 @@ export {
|
|
|
3067
3154
|
extractMessageText,
|
|
3068
3155
|
filterAutocompleteItems,
|
|
3069
3156
|
findActiveTrigger,
|
|
3157
|
+
formatElapsed,
|
|
3070
3158
|
formatRelativeTime,
|
|
3071
3159
|
loadStoredSpeechLang,
|
|
3072
3160
|
persistSpeechLang,
|
|
3161
|
+
readReasoningMs,
|
|
3073
3162
|
storedMessageToUiMessage,
|
|
3074
3163
|
storedThreadToUiMessages,
|
|
3075
3164
|
useAgentChat,
|
|
3076
3165
|
useChatTranscript,
|
|
3077
3166
|
useComposerAutocomplete,
|
|
3167
|
+
useElapsed,
|
|
3078
3168
|
useSpeechRecognition,
|
|
3079
3169
|
useStickToBottom,
|
|
3080
3170
|
useTranscriptItem
|