@dudousxd/nestjs-agent-react 0.11.0 → 0.12.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/dist/index.d.cts CHANGED
@@ -1,7 +1,8 @@
1
1
  import * as ai from 'ai';
2
2
  import { ChatTransport, UIMessage, UIMessageChunk, ToolUIPart, DynamicToolUIPart, DataUIPart, UIDataTypes } from 'ai';
3
3
  import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
4
- import { StoredMessage, ThreadSummary, SkillCatalogEntry, ToolCatalogEntry, ThreadDetail, MessageAttachment, QuotaView, ToolPresentation, ToolResultField, ToolResultView, ToolPresentationTone } from '@dudousxd/nestjs-agent-core';
4
+ import { StoredMessage, ThreadSummary, SkillCatalogEntry, ToolCatalogEntry, ThreadDetail, MessageAttachment, QuotaView, ElicitationQuestion, ElicitationInputType, ToolPresentation, ToolResultField, ToolResultView, ToolPresentationTone, ElicitationInput } from '@dudousxd/nestjs-agent-core';
5
+ export { ElicitationInput, ElicitationInputType, validateElicitationAnswer as validateAnswer, validateElicitationValue as validateAnswerValue } from '@dudousxd/nestjs-agent-core';
5
6
  import React from 'react';
6
7
 
7
8
  /** Identity surfaced by the backend's `meta` SSE frame / response headers. */
@@ -314,6 +315,26 @@ interface ChatInputProps {
314
315
  */
315
316
  declare function ChatInput({ onSubmit, disabled, placeholder, rows, enableSpeech, speechLang, sendLabel, onStop, isStreaming, stopLabel, className, textareaClassName, sendButtonClassName, micButtonClassName, stopButtonClassName, renderMic, }: ChatInputProps): React.JSX.Element;
316
317
 
318
+ /** What a form control can hand over: a field's value, a checkbox's state, a picked date, a list. */
319
+ type RawAnswer = string | number | boolean | Date | null | undefined | readonly RawAnswer[];
320
+ /** The question fields {@link coerceAnswer} reads. A transcript question and a core one both fit. */
321
+ type CoercibleQuestion = Pick<ElicitationQuestion, 'multiple'> & {
322
+ input?: {
323
+ type: ElicitationInputType;
324
+ } | null;
325
+ };
326
+ /**
327
+ * Turn whatever a form control produced into the `string[]` the answer route takes, in the
328
+ * question's canonical form: numbers as decimals, booleans as `"true"`/`"false"`, dates as
329
+ * `YYYY-MM-DD` (a `Date` is read as the local calendar day), trimmed where whitespace means
330
+ * nothing. An empty value becomes `[]` — no answer, not an empty string. A single-choice question
331
+ * keeps the first value.
332
+ *
333
+ * Coercion never judges: pair it with {@link validateAnswer} (the same rules the server applies) to
334
+ * say what is wrong before sending.
335
+ */
336
+ declare function coerceAnswer(question: CoercibleQuestion, raw: RawAnswer): string[];
337
+
317
338
  /** Tool name → how the server said it is spoken about. */
318
339
  type ToolCatalog = Record<string, ToolPresentation>;
319
340
  /** Index `GET <base>/tools` by tool name, keeping only the tools that declared a presentation. */
@@ -669,6 +690,14 @@ interface TranscriptQuestionOption {
669
690
  interface TranscriptQuestion {
670
691
  id: string;
671
692
  prompt: string;
693
+ /** A line of help under the prompt; `null` when the request gave none. */
694
+ description: string | null;
695
+ /**
696
+ * How the answer is typed — `{ type, placeholder?, required?, min?, max?, pattern? }` — or `null`
697
+ * for a plain pick from `options`. Render the control from `input.type`; `select` still picks
698
+ * from `options`.
699
+ */
700
+ input: ElicitationInput | null;
672
701
  multiple: boolean;
673
702
  /** 1-based. The request carries every question up front, so "Question 1 of N" is honest. */
674
703
  position: number;
@@ -680,6 +709,20 @@ interface TranscriptQuestion {
680
709
  * first is recorded as `defaulted` rather than as a choice the user made.
681
710
  */
682
711
  isPristine: boolean;
712
+ /** The first selected value, or `''` — what a single text/number/date field shows. */
713
+ value: string;
714
+ /**
715
+ * Set a typed answer from whatever the control produced (a string, a number, a checkbox's
716
+ * boolean, a `Date`, a list); coerced to the question's canonical strings with `coerceAnswer`.
717
+ * `null`/`''` clears it. Does nothing once the set settled.
718
+ */
719
+ setValue: (raw: RawAnswer) => void;
720
+ /**
721
+ * Why the current selection would be refused (the server's own rules — `validateAnswer`), or
722
+ * `null`. A pristine required question with no default reads `requires an answer`; show it once
723
+ * the user tried to submit, or right away — the model does not decide that for you.
724
+ */
725
+ error: string | null;
683
726
  }
684
727
  /** How a question set settled, once it did. */
685
728
  interface TranscriptElicitationOutcome {
@@ -706,6 +749,8 @@ interface TranscriptElicitationBlock {
706
749
  questionCount: number;
707
750
  /** Still waiting on a human. */
708
751
  isPending: boolean;
752
+ /** Every question's current selection is acceptable (no question has an `error`). */
753
+ isValid: boolean;
709
754
  outcome: TranscriptElicitationOutcome | null;
710
755
  /** A failed submission — the run is still parked, so the form stays live. */
711
756
  error: string | null;
@@ -1711,4 +1756,4 @@ declare function useAgentChat(options: UseAgentChatOptions): {
1711
1756
  clearError: () => void;
1712
1757
  };
1713
1758
 
1714
- export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type ApprovalCountdown, type ApproveOptions, 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 DescribeToolCallOptions, type ElicitationBlockOptions, type GroupToolActivityOptions, 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 ResolvedReading, type ResolvedResultView, 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 ToolActivityGroup, type ToolCallDescription, type ToolCallState, type ToolCallStatus, type ToolCatalog, type ToolCatalogState, type TranscriptActionState, type TranscriptApproval, type TranscriptApprovalStatus, 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 UseApprovalCountdownOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseElapsedOptions, type UseSpeechRecognitionOptions, type UseToolCatalogOptions, type UseTranscriptItemOptions, applyCompletion, approvalCountdown, backgroundRunsFromThread, buildTranscriptBlocks, correctedCallIds, createSkillsSource, describeTimestamp, describeToolCall, describeUsage, extractMessageText, fillTemplate, filterAutocompleteItems, findActiveTrigger, formatElapsed, formatRelativeTime, groupToolActivity, inferResultView, isActionCall, loadStoredSpeechLang, persistSpeechLang, phraseFor, readPath, readReasoningMs, resolveResultView, storedMessageToUiMessage, storedThreadToUiMessages, toolCallState, toolCatalogFrom, useAgentChat, useApprovalCountdown, useChatTranscript, useComposerAutocomplete, useElapsed, useSpeechRecognition, useStickToBottom, useToolCatalog, useTranscriptItem };
1759
+ export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type ApprovalCountdown, type ApproveOptions, 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 CoercibleQuestion, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type DescribeToolCallOptions, type ElicitationBlockOptions, type GroupToolActivityOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RawAnswer, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type ResolvedReading, type ResolvedResultView, 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 ToolActivityGroup, type ToolCallDescription, type ToolCallState, type ToolCallStatus, type ToolCatalog, type ToolCatalogState, type TranscriptActionState, type TranscriptApproval, type TranscriptApprovalStatus, 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 UseApprovalCountdownOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseElapsedOptions, type UseSpeechRecognitionOptions, type UseToolCatalogOptions, type UseTranscriptItemOptions, applyCompletion, approvalCountdown, backgroundRunsFromThread, buildTranscriptBlocks, coerceAnswer, correctedCallIds, createSkillsSource, describeTimestamp, describeToolCall, describeUsage, extractMessageText, fillTemplate, filterAutocompleteItems, findActiveTrigger, formatElapsed, formatRelativeTime, groupToolActivity, inferResultView, isActionCall, loadStoredSpeechLang, persistSpeechLang, phraseFor, readPath, readReasoningMs, resolveResultView, storedMessageToUiMessage, storedThreadToUiMessages, toolCallState, toolCatalogFrom, useAgentChat, useApprovalCountdown, useChatTranscript, useComposerAutocomplete, useElapsed, useSpeechRecognition, useStickToBottom, useToolCatalog, useTranscriptItem };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import * as ai from 'ai';
2
2
  import { ChatTransport, UIMessage, UIMessageChunk, ToolUIPart, DynamicToolUIPart, DataUIPart, UIDataTypes } from 'ai';
3
3
  import * as _dudousxd_nestjs_agent_core from '@dudousxd/nestjs-agent-core';
4
- import { StoredMessage, ThreadSummary, SkillCatalogEntry, ToolCatalogEntry, ThreadDetail, MessageAttachment, QuotaView, ToolPresentation, ToolResultField, ToolResultView, ToolPresentationTone } from '@dudousxd/nestjs-agent-core';
4
+ import { StoredMessage, ThreadSummary, SkillCatalogEntry, ToolCatalogEntry, ThreadDetail, MessageAttachment, QuotaView, ElicitationQuestion, ElicitationInputType, ToolPresentation, ToolResultField, ToolResultView, ToolPresentationTone, ElicitationInput } from '@dudousxd/nestjs-agent-core';
5
+ export { ElicitationInput, ElicitationInputType, validateElicitationAnswer as validateAnswer, validateElicitationValue as validateAnswerValue } from '@dudousxd/nestjs-agent-core';
5
6
  import React from 'react';
6
7
 
7
8
  /** Identity surfaced by the backend's `meta` SSE frame / response headers. */
@@ -314,6 +315,26 @@ interface ChatInputProps {
314
315
  */
315
316
  declare function ChatInput({ onSubmit, disabled, placeholder, rows, enableSpeech, speechLang, sendLabel, onStop, isStreaming, stopLabel, className, textareaClassName, sendButtonClassName, micButtonClassName, stopButtonClassName, renderMic, }: ChatInputProps): React.JSX.Element;
316
317
 
318
+ /** What a form control can hand over: a field's value, a checkbox's state, a picked date, a list. */
319
+ type RawAnswer = string | number | boolean | Date | null | undefined | readonly RawAnswer[];
320
+ /** The question fields {@link coerceAnswer} reads. A transcript question and a core one both fit. */
321
+ type CoercibleQuestion = Pick<ElicitationQuestion, 'multiple'> & {
322
+ input?: {
323
+ type: ElicitationInputType;
324
+ } | null;
325
+ };
326
+ /**
327
+ * Turn whatever a form control produced into the `string[]` the answer route takes, in the
328
+ * question's canonical form: numbers as decimals, booleans as `"true"`/`"false"`, dates as
329
+ * `YYYY-MM-DD` (a `Date` is read as the local calendar day), trimmed where whitespace means
330
+ * nothing. An empty value becomes `[]` — no answer, not an empty string. A single-choice question
331
+ * keeps the first value.
332
+ *
333
+ * Coercion never judges: pair it with {@link validateAnswer} (the same rules the server applies) to
334
+ * say what is wrong before sending.
335
+ */
336
+ declare function coerceAnswer(question: CoercibleQuestion, raw: RawAnswer): string[];
337
+
317
338
  /** Tool name → how the server said it is spoken about. */
318
339
  type ToolCatalog = Record<string, ToolPresentation>;
319
340
  /** Index `GET <base>/tools` by tool name, keeping only the tools that declared a presentation. */
@@ -669,6 +690,14 @@ interface TranscriptQuestionOption {
669
690
  interface TranscriptQuestion {
670
691
  id: string;
671
692
  prompt: string;
693
+ /** A line of help under the prompt; `null` when the request gave none. */
694
+ description: string | null;
695
+ /**
696
+ * How the answer is typed — `{ type, placeholder?, required?, min?, max?, pattern? }` — or `null`
697
+ * for a plain pick from `options`. Render the control from `input.type`; `select` still picks
698
+ * from `options`.
699
+ */
700
+ input: ElicitationInput | null;
672
701
  multiple: boolean;
673
702
  /** 1-based. The request carries every question up front, so "Question 1 of N" is honest. */
674
703
  position: number;
@@ -680,6 +709,20 @@ interface TranscriptQuestion {
680
709
  * first is recorded as `defaulted` rather than as a choice the user made.
681
710
  */
682
711
  isPristine: boolean;
712
+ /** The first selected value, or `''` — what a single text/number/date field shows. */
713
+ value: string;
714
+ /**
715
+ * Set a typed answer from whatever the control produced (a string, a number, a checkbox's
716
+ * boolean, a `Date`, a list); coerced to the question's canonical strings with `coerceAnswer`.
717
+ * `null`/`''` clears it. Does nothing once the set settled.
718
+ */
719
+ setValue: (raw: RawAnswer) => void;
720
+ /**
721
+ * Why the current selection would be refused (the server's own rules — `validateAnswer`), or
722
+ * `null`. A pristine required question with no default reads `requires an answer`; show it once
723
+ * the user tried to submit, or right away — the model does not decide that for you.
724
+ */
725
+ error: string | null;
683
726
  }
684
727
  /** How a question set settled, once it did. */
685
728
  interface TranscriptElicitationOutcome {
@@ -706,6 +749,8 @@ interface TranscriptElicitationBlock {
706
749
  questionCount: number;
707
750
  /** Still waiting on a human. */
708
751
  isPending: boolean;
752
+ /** Every question's current selection is acceptable (no question has an `error`). */
753
+ isValid: boolean;
709
754
  outcome: TranscriptElicitationOutcome | null;
710
755
  /** A failed submission — the run is still parked, so the form stays live. */
711
756
  error: string | null;
@@ -1711,4 +1756,4 @@ declare function useAgentChat(options: UseAgentChatOptions): {
1711
1756
  clearError: () => void;
1712
1757
  };
1713
1758
 
1714
- export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type ApprovalCountdown, type ApproveOptions, 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 DescribeToolCallOptions, type ElicitationBlockOptions, type GroupToolActivityOptions, 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 ResolvedReading, type ResolvedResultView, 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 ToolActivityGroup, type ToolCallDescription, type ToolCallState, type ToolCallStatus, type ToolCatalog, type ToolCatalogState, type TranscriptActionState, type TranscriptApproval, type TranscriptApprovalStatus, 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 UseApprovalCountdownOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseElapsedOptions, type UseSpeechRecognitionOptions, type UseToolCatalogOptions, type UseTranscriptItemOptions, applyCompletion, approvalCountdown, backgroundRunsFromThread, buildTranscriptBlocks, correctedCallIds, createSkillsSource, describeTimestamp, describeToolCall, describeUsage, extractMessageText, fillTemplate, filterAutocompleteItems, findActiveTrigger, formatElapsed, formatRelativeTime, groupToolActivity, inferResultView, isActionCall, loadStoredSpeechLang, persistSpeechLang, phraseFor, readPath, readReasoningMs, resolveResultView, storedMessageToUiMessage, storedThreadToUiMessages, toolCallState, toolCatalogFrom, useAgentChat, useApprovalCountdown, useChatTranscript, useComposerAutocomplete, useElapsed, useSpeechRecognition, useStickToBottom, useToolCatalog, useTranscriptItem };
1759
+ export { AgentChatTransport, type AgentChatTransportOptions, AgentClient, type AgentClientOptions, AgentHttpError, type AgentStreamMeta, type AggregatedTurnUsage, type AnyToolUIPart, type ApprovalBlockOptions, type ApprovalCountdown, type ApproveOptions, 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 CoercibleQuestion, type CompletionEdit, type ComposerAutocomplete, DEFAULT_SPEECH_LANG, type DescribeToolCallOptions, type ElicitationBlockOptions, type GroupToolActivityOptions, MessageItem, type MessageItemClassNames, type MessageItemProps, MessageItemView, type MessageItemViewProps, MessageList, type MessageListClassNames, type MessageListProps, type MessageUsageInfo, type QuotaToday, type RawAnswer, type RenderFilesFn, type RenderReasoningFn, type RenderTextFn, type RenderToolGroupFn, type RenderToolPartFn, type RenderUiFn, type ResolvedReading, type ResolvedResultView, 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 ToolActivityGroup, type ToolCallDescription, type ToolCallState, type ToolCallStatus, type ToolCatalog, type ToolCatalogState, type TranscriptActionState, type TranscriptApproval, type TranscriptApprovalStatus, 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 UseApprovalCountdownOptions, type UseChatTranscriptOptions, type UseComposerAutocompleteOptions, type UseElapsedOptions, type UseSpeechRecognitionOptions, type UseToolCatalogOptions, type UseTranscriptItemOptions, applyCompletion, approvalCountdown, backgroundRunsFromThread, buildTranscriptBlocks, coerceAnswer, correctedCallIds, createSkillsSource, describeTimestamp, describeToolCall, describeUsage, extractMessageText, fillTemplate, filterAutocompleteItems, findActiveTrigger, formatElapsed, formatRelativeTime, groupToolActivity, inferResultView, isActionCall, loadStoredSpeechLang, persistSpeechLang, phraseFor, readPath, readReasoningMs, resolveResultView, storedMessageToUiMessage, storedThreadToUiMessages, toolCallState, toolCatalogFrom, useAgentChat, useApprovalCountdown, useChatTranscript, useComposerAutocomplete, useElapsed, useSpeechRecognition, useStickToBottom, useToolCatalog, useTranscriptItem };
package/dist/index.js CHANGED
@@ -978,8 +978,66 @@ import React3 from "react";
978
978
  import { useCallback as useCallback3, useEffect as useEffect5, useRef as useRef4, useState as useState5 } from "react";
979
979
 
980
980
  // src/transcript/model.ts
981
+ import { readElicitationInput, validateElicitationAnswer as validateElicitationAnswer2 } from "@dudousxd/nestjs-agent-core";
981
982
  import { getToolName as getToolName2, isDataUIPart, isFileUIPart, isReasoningUIPart, isTextUIPart, isToolUIPart } from "ai";
982
983
 
984
+ // src/elicitation/answers.ts
985
+ import { validateElicitationAnswer, validateElicitationValue } from "@dudousxd/nestjs-agent-core";
986
+ function pad(value) {
987
+ return String(value).padStart(2, "0");
988
+ }
989
+ __name(pad, "pad");
990
+ function toDay(date) {
991
+ if (Number.isNaN(date.getTime())) {
992
+ return null;
993
+ }
994
+ return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
995
+ }
996
+ __name(toDay, "toDay");
997
+ function coerceOne(type, raw) {
998
+ if (raw === null || raw === void 0) {
999
+ return null;
1000
+ }
1001
+ if (Array.isArray(raw)) {
1002
+ return null;
1003
+ }
1004
+ if (raw instanceof Date) {
1005
+ return type === "date" || type === void 0 ? toDay(raw) : raw.toISOString();
1006
+ }
1007
+ if (typeof raw === "boolean") {
1008
+ return raw ? "true" : "false";
1009
+ }
1010
+ if (typeof raw === "number") {
1011
+ return Number.isFinite(raw) ? String(raw) : null;
1012
+ }
1013
+ const text = raw;
1014
+ switch (type) {
1015
+ case "number":
1016
+ case "email":
1017
+ case "url":
1018
+ case "date":
1019
+ return text.trim() === "" ? null : text.trim();
1020
+ case "boolean": {
1021
+ const lowered = text.trim().toLowerCase();
1022
+ if (lowered === "true" || lowered === "on" || lowered === "yes") return "true";
1023
+ if (lowered === "false" || lowered === "off" || lowered === "no") return "false";
1024
+ return lowered === "" ? null : text;
1025
+ }
1026
+ default:
1027
+ return text === "" ? null : text;
1028
+ }
1029
+ }
1030
+ __name(coerceOne, "coerceOne");
1031
+ function coerceAnswer(question, raw) {
1032
+ const type = question.input?.type;
1033
+ const items = Array.isArray(raw) ? raw : [
1034
+ raw
1035
+ ];
1036
+ const values = items.map((item) => coerceOne(type, item)).filter((value) => value !== null);
1037
+ return question.multiple === true ? values : values.slice(0, 1);
1038
+ }
1039
+ __name(coerceAnswer, "coerceAnswer");
1040
+
983
1041
  // src/presentation/tool-activity.ts
984
1042
  import { getToolName } from "ai";
985
1043
 
@@ -1516,11 +1574,16 @@ function readElicitationRequest(part) {
1516
1574
  }
1517
1575
  const questions = [];
1518
1576
  for (const candidate of input.questions) {
1519
- if (!isRecord2(candidate) || typeof candidate.id !== "string" || typeof candidate.prompt !== "string" || !Array.isArray(candidate.options) || candidate.options.length === 0) {
1577
+ if (!isRecord2(candidate) || typeof candidate.id !== "string" || typeof candidate.prompt !== "string") {
1578
+ return null;
1579
+ }
1580
+ const input2 = readElicitationInput(candidate.input) ?? null;
1581
+ const rawOptions = Array.isArray(candidate.options) ? candidate.options : [];
1582
+ if (rawOptions.length === 0 && (input2 === null || input2.type === "select")) {
1520
1583
  return null;
1521
1584
  }
1522
1585
  const options = [];
1523
- for (const option of candidate.options) {
1586
+ for (const option of rawOptions) {
1524
1587
  if (!isRecord2(option) || typeof option.value !== "string" || typeof option.label !== "string") {
1525
1588
  return null;
1526
1589
  }
@@ -1533,7 +1596,10 @@ function readElicitationRequest(part) {
1533
1596
  questions.push({
1534
1597
  id: candidate.id,
1535
1598
  prompt: candidate.prompt,
1599
+ description: typeof candidate.description === "string" ? candidate.description : null,
1600
+ input: input2,
1536
1601
  multiple: candidate.multiple === true,
1602
+ allowFreeText: candidate.allowFreeText === true,
1537
1603
  defaults: Array.isArray(candidate.defaults) ? candidate.defaults.filter((value) => typeof value === "string") : [],
1538
1604
  options
1539
1605
  });
@@ -1569,12 +1635,38 @@ function buildElicitationBlock(key, part, request, options) {
1569
1635
  const picked = isPending ? options.picked(toolCallId, question.id) : void 0;
1570
1636
  const selected = picked ?? outcome?.answers[question.id] ?? question.defaults;
1571
1637
  const pick = /* @__PURE__ */ __name((values) => options.pick(toolCallId, question.id, values), "pick");
1638
+ const error = isPending ? validateElicitationAnswer2({
1639
+ id: question.id,
1640
+ prompt: question.prompt,
1641
+ options: question.options.map(({ value, label }) => ({
1642
+ value,
1643
+ label
1644
+ })),
1645
+ ...question.input !== null ? {
1646
+ input: question.input
1647
+ } : {},
1648
+ ...question.multiple ? {
1649
+ multiple: true
1650
+ } : {},
1651
+ ...question.allowFreeText ? {
1652
+ allowFreeText: true
1653
+ } : {}
1654
+ }, selected) : null;
1572
1655
  return {
1573
1656
  id: question.id,
1574
1657
  prompt: question.prompt,
1658
+ description: question.description,
1659
+ input: question.input,
1575
1660
  multiple: question.multiple,
1576
1661
  position: index + 1,
1577
1662
  selected,
1663
+ value: selected[0] ?? "",
1664
+ error,
1665
+ setValue: /* @__PURE__ */ __name((raw) => {
1666
+ if (isPending) {
1667
+ pick(coerceAnswer(question, raw));
1668
+ }
1669
+ }, "setValue"),
1578
1670
  isPristine: isPending ? picked === void 0 : outcome?.defaulted.includes(question.id) ?? true,
1579
1671
  options: question.options.map((option) => ({
1580
1672
  value: option.value,
@@ -1609,6 +1701,7 @@ function buildElicitationBlock(key, part, request, options) {
1609
1701
  questions,
1610
1702
  questionCount: questions.length,
1611
1703
  isPending,
1704
+ isValid: questions.every((question) => question.error === null),
1612
1705
  outcome,
1613
1706
  error: options.errorOf(toolCallId),
1614
1707
  answer: {
@@ -3677,6 +3770,7 @@ export {
3677
3770
  approvalCountdown,
3678
3771
  backgroundRunsFromThread,
3679
3772
  buildTranscriptBlocks,
3773
+ coerceAnswer,
3680
3774
  correctedCallIds,
3681
3775
  createSkillsSource,
3682
3776
  describeTimestamp,
@@ -3709,6 +3803,8 @@ export {
3709
3803
  useSpeechRecognition,
3710
3804
  useStickToBottom,
3711
3805
  useToolCatalog,
3712
- useTranscriptItem
3806
+ useTranscriptItem,
3807
+ validateElicitationAnswer as validateAnswer,
3808
+ validateElicitationValue as validateAnswerValue
3713
3809
  };
3714
3810
  //# sourceMappingURL=index.js.map