@athenaintel/react 0.42.1 → 0.42.2
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 +36 -7
- package/dist/agent-runtime/src/index.d.ts +2 -2
- package/dist/agent-runtime/src/messages.cjs +38 -7
- package/dist/agent-runtime/src/messages.cjs.map +1 -1
- package/dist/agent-runtime/src/messages.d.ts +26 -8
- package/dist/agent-runtime/src/messages.js +38 -7
- package/dist/agent-runtime/src/messages.js.map +1 -1
- package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs +10 -0
- package/dist/agent-runtime/src/quota-safe-local-storage-session.cjs.map +1 -1
- package/dist/agent-runtime/src/quota-safe-local-storage-session.d.ts +7 -0
- package/dist/agent-runtime/src/quota-safe-local-storage-session.js +10 -0
- package/dist/agent-runtime/src/quota-safe-local-storage-session.js.map +1 -1
- package/dist/agent-runtime/src/session-lane-scope.cjs +25 -0
- package/dist/agent-runtime/src/session-lane-scope.cjs.map +1 -0
- package/dist/agent-runtime/src/session-lane-scope.d.ts +59 -0
- package/dist/agent-runtime/src/session-lane-scope.js +25 -0
- package/dist/agent-runtime/src/session-lane-scope.js.map +1 -0
- package/dist/agent-runtime/src/subagent-transcripts.cjs +2 -2
- package/dist/agent-runtime/src/subagent-transcripts.cjs.map +1 -1
- package/dist/agent-runtime/src/subagent-transcripts.d.ts +2 -2
- package/dist/agent-runtime/src/subagent-transcripts.js +3 -3
- package/dist/agent-runtime/src/subagent-transcripts.js.map +1 -1
- package/dist/agent-runtime/src/tool-names.cjs +4 -0
- package/dist/agent-runtime/src/tool-names.cjs.map +1 -1
- package/dist/agent-runtime/src/tool-names.d.ts +7 -0
- package/dist/agent-runtime/src/tool-names.js +4 -0
- package/dist/agent-runtime/src/tool-names.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-runtime.cjs +18 -1
- package/dist/agent-runtime/src/use-deep-agent-runtime.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-runtime.d.ts +19 -10
- package/dist/agent-runtime/src/use-deep-agent-runtime.js +19 -2
- package/dist/agent-runtime/src/use-deep-agent-runtime.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs +28 -10
- package/dist/agent-runtime/src/use-deep-agent-thread.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-thread.d.ts +35 -3
- package/dist/agent-runtime/src/use-deep-agent-thread.js +28 -10
- package/dist/agent-runtime/src/use-deep-agent-thread.js.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-voice.cjs +20 -0
- package/dist/agent-runtime/src/use-deep-agent-voice.cjs.map +1 -1
- package/dist/agent-runtime/src/use-deep-agent-voice.js +20 -0
- package/dist/agent-runtime/src/use-deep-agent-voice.js.map +1 -1
- package/dist/agent-runtime/src/voice-presentation.cjs +2 -0
- package/dist/agent-runtime/src/voice-presentation.cjs.map +1 -1
- package/dist/agent-runtime/src/voice-presentation.js +2 -0
- package/dist/agent-runtime/src/voice-presentation.js.map +1 -1
- package/dist/catalog/runtime-catalog.js +1 -1
- package/dist/chat/AthenaChat.cjs +125 -103
- package/dist/chat/AthenaChat.cjs.map +1 -1
- package/dist/chat/AthenaChat.d.ts +9 -0
- package/dist/chat/AthenaChat.js +126 -104
- package/dist/chat/AthenaChat.js.map +1 -1
- package/dist/chat/chat-voice-controls.cjs +128 -0
- package/dist/chat/chat-voice-controls.cjs.map +1 -0
- package/dist/chat/chat-voice-controls.d.ts +19 -0
- package/dist/chat/chat-voice-controls.js +128 -0
- package/dist/chat/chat-voice-controls.js.map +1 -0
- package/dist/chat/use-statewire-approval-request.js +1 -1
- package/dist/chat-ui/composer/tiptap-composer.cjs +42 -22
- package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
- package/dist/chat-ui/composer/tiptap-composer.d.ts +1 -0
- package/dist/chat-ui/composer/tiptap-composer.js +43 -23
- package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +2 -1
- package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/api-client.d.ts +3 -1
- package/dist/chat-ui/mentions/suggestions/data/api-client.js +2 -1
- package/dist/chat-ui/mentions/suggestions/data/api-client.js.map +1 -1
- package/dist/chat-ui/mentions/use-account-workspace-id.cjs +29 -51
- package/dist/chat-ui/mentions/use-account-workspace-id.cjs.map +1 -1
- package/dist/chat-ui/mentions/use-account-workspace-id.d.ts +2 -2
- package/dist/chat-ui/mentions/use-account-workspace-id.js +30 -52
- package/dist/chat-ui/mentions/use-account-workspace-id.js.map +1 -1
- package/dist/chat-ui/thread/composer-send-or-stop.cjs +2 -1
- package/dist/chat-ui/thread/composer-send-or-stop.cjs.map +1 -1
- package/dist/chat-ui/thread/composer-send-or-stop.d.ts +2 -0
- package/dist/chat-ui/thread/composer-send-or-stop.js +2 -1
- package/dist/chat-ui/thread/composer-send-or-stop.js.map +1 -1
- package/dist/diagnostics/athena-diagnostics.cjs.map +1 -1
- package/dist/diagnostics/athena-diagnostics.d.ts +1 -1
- package/dist/diagnostics/athena-diagnostics.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/react/package.json.cjs +1 -1
- package/dist/react/package.json.js +1 -1
- package/dist/runtime/statewire-session-key.cjs.map +1 -1
- package/dist/runtime/statewire-session-key.d.ts +8 -5
- package/dist/runtime/statewire-session-key.js.map +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.cjs +5 -2
- package/dist/runtime/useAthenaStatewireRuntime.cjs.map +1 -1
- package/dist/runtime/useAthenaStatewireRuntime.js +5 -2
- package/dist/runtime/useAthenaStatewireRuntime.js.map +1 -1
- package/dist/voice/use-chat-voice-enabled.cjs +43 -0
- package/dist/voice/use-chat-voice-enabled.cjs.map +1 -0
- package/dist/voice/use-chat-voice-enabled.d.ts +9 -0
- package/dist/voice/use-chat-voice-enabled.js +43 -0
- package/dist/voice/use-chat-voice-enabled.js.map +1 -0
- package/package.json +4 -8
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"voice-presentation.js","sources":["../../../../agent-runtime/src/voice-presentation.ts"],"sourcesContent":["/**\n * How voice-mode transcript entries present, shared by every chat surface\n * (Olympus, the Chrome side panel, the mobile app) so a spoken turn, a\n * delegation the live voice model handed off, and an interim spoken update\n * read the same everywhere. The wire contract is the deep-agent host's\n * `additional_kwargs.metadata` (exposed as `message.metadata.custom`):\n *\n * - `source: \"voice\"` — a spoken turn; `voice_live: true` while it is still\n * being heard or spoken (the ephemeral entry the durable row replaces);\n * - `source: \"text\"` — a message typed into the live conversation;\n * - `source: \"voice_delegation\"` (id prefix `voicetask_`) — the unit of work\n * the live voice model delegated to the thread.\n */\nimport { getExternalStoreMessages, type ThreadMessage } from '@assistant-ui/core';\n\n/** `metadata.custom.source` of a spoken turn. */\nexport const VOICE_SOURCE_SPOKEN = 'voice';\n/** `metadata.custom.source` of a message typed into the live conversation. */\nexport const VOICE_SOURCE_TYPED = 'text';\n/** `metadata.custom.source` of a voice delegation's anchor message. */\nexport const VOICE_SOURCE_DELEGATION = 'voice_delegation';\n/** Id prefix of a voice delegation's anchor message (the working signal on\n * hosts that drop the command's metadata). */\nexport const VOICE_DELEGATION_ID_PREFIX = 'voicetask_';\n/** `metadata.custom` flag on a spoken turn still in flight. */\nexport const VOICE_LIVE_KEY = 'voice_live';\n/** `metadata.custom` list of the wire ids a grouped spoken bubble stands for\n * (see `groupSpokenUserTurns`), so id-keyed lookups such as checkpoint markers\n * can resolve any member to the bubble. */\nexport const VOICE_TURN_IDS_KEY = 'voice_turn_ids';\n\n/** The delegated run's interim-update tool (agora `send_voice_update`). */\nexport const VOICE_UPDATE_TOOL_NAME = 'send_voice_update';\n\n/** Trailing hint on the live-session strip, worded once for every surface. */\nexport const VOICE_LIVE_TYPED_HINT = 'typed messages go to the voice conversation';\n\nexport interface VoiceMessageMarker {\n /** The thread message id; a host may not have assigned one yet. */\n messageId: string | undefined;\n /** The thread message's `metadata.custom`, when any. */\n custom: Record<string, unknown> | undefined;\n}\n\n/** Whether a thread message is a voice delegation's anchor (the ask the live\n * voice model handed to the thread), by source or by id prefix. */\nexport function isVoiceDelegationMessage({ messageId, custom }: VoiceMessageMarker): boolean {\n return (\n custom?.source === VOICE_SOURCE_DELEGATION ||\n (typeof messageId === 'string' && messageId.startsWith(VOICE_DELEGATION_ID_PREFIX))\n );\n}\n\nexport interface VoiceProvenance {\n /** Chip copy: \"Listening\", \"Speaking\", \"Spoken\", or \"Delegated from voice\". */\n readonly label: string;\n /** True while the turn is still being heard or spoken. */\n readonly live: boolean;\n}\n\n// These values are read directly by useAuiState/useSyncExternalStore selectors.\n// Equal presentation must retain its identity, even when a transport replaces\n// the message metadata. Fresh objects here cause React's update-depth crash.\nconst SPOKEN_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Spoken',\n live: false,\n});\nconst LISTENING_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Listening',\n live: true,\n});\nconst SPEAKING_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Speaking',\n live: true,\n});\nconst DELEGATED_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Delegated from voice',\n live: false,\n});\n\n/**\n * The provenance chip for a message, or `null` for ordinary chat messages so\n * the chip is free to mount on every row. A spoken turn still in flight reads\n * as what is happening (\"Listening\" for the user, \"Speaking\" for the\n * assistant) rather than as a finished \"Spoken\" turn; a typed-in-voice turn\n * is a normal message and gets no chip. Results are immutable and stable for\n * equal presentation, so all surfaces can use this function as a selector.\n */\nexport function voiceProvenanceLabel({\n messageId,\n custom,\n role,\n}: VoiceMessageMarker & { role: 'user' | 'assistant' | string }): VoiceProvenance | null {\n const source = custom?.source;\n if (source === VOICE_SOURCE_SPOKEN) {\n if (custom?.[VOICE_LIVE_KEY] === true) {\n return role === 'user' ? LISTENING_PROVENANCE : SPEAKING_PROVENANCE;\n }\n return SPOKEN_PROVENANCE;\n }\n if (isVoiceDelegationMessage({ messageId, custom })) {\n return DELEGATED_PROVENANCE;\n }\n return null;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/**\n * Whether a part of an assistant message holds the words of a spoken\n * assistant turn.\n *\n * The converter joins consecutive assistant entries into one message. The\n * host appends a live turn while it is heard, and a delegated run keeps\n * appending its own steps after it, so a turn spoken during a run becomes a\n * text part inside the run's message, before the run's later tool calls.\n * Grouped views put the text before the last tool call in the details panel\n * as the run's narration; they use this to keep the spoken words visible.\n *\n * The joined message's `metadata.custom` merges every entry in it, so this\n * reads the part's own entry, which the converter binds to the part.\n */\nexport function isSpokenTurnTextPart(part: { readonly type: string }): boolean {\n if (part.type !== 'text') return false;\n const entries: readonly unknown[] = getExternalStoreMessages<unknown>(\n part as ThreadMessage['content'][number]\n );\n return entries.some((entry) => {\n if (!isRecord(entry) || entry.role !== 'assistant' || !isRecord(entry.metadata)) return false;\n const custom = entry.metadata.custom;\n return isRecord(custom) && custom.source === VOICE_SOURCE_SPOKEN;\n });\n}\n\nexport interface VoiceUpdateToolCall {\n /** `mode: \"speak\"` — read aloud to the user; otherwise a silent progress note. */\n spoken: boolean;\n /** The update's words. */\n text: string;\n /** Whether the live session took it; `null` while the call is still running. */\n delivered: boolean | null;\n}\n\n/**\n * What a `send_voice_update` tool call did, from its arguments and the tool's\n * teaching-text result (agora returns prose, not JSON, so the run can read it).\n */\nexport function describeVoiceUpdateToolCall({\n args,\n result,\n}: {\n args: Record<string, unknown> | undefined;\n result: unknown;\n}): VoiceUpdateToolCall {\n const text = typeof args?.text === 'string' ? args.text.trim() : '';\n const spoken = args?.mode === 'speak';\n if (typeof result !== 'string' || result.trim() === '') {\n return { spoken, text, delivered: null };\n }\n const outcome = result.toLowerCase();\n const failed =\n outcome.includes('could not be delivered') ||\n outcome.includes('was not delivered') ||\n outcome.includes('rejected the update') ||\n outcome.includes('has ended') ||\n outcome.includes('not configured') ||\n outcome.includes('no voice session');\n return { spoken, text, delivered: !failed };\n}\n\n/** The card's status line for a voice update in a given tool-call state. */\nexport function voiceUpdateStatusLabel(\n call: VoiceUpdateToolCall,\n status: 'running' | 'complete' | 'incomplete' | 'requires-action' | undefined\n): string {\n if (status === 'running' || (call.delivered === null && status !== 'incomplete')) {\n return call.spoken ? 'Saying to you…' : 'Noting progress…';\n }\n if (call.delivered === false || status === 'incomplete') {\n return call.spoken ? 'Could not say this to you' : 'Progress note not delivered';\n }\n return call.spoken ? 'Said aloud' : 'Progress noted silently';\n}\n"],"names":[],"mappings":";AAgBO,MAAM,sBAAsB;AAI5B,MAAM,0BAA0B;AAGhC,MAAM,6BAA6B;AAEnC,MAAM,iBAAiB;AAIvB,MAAM,qBAAqB;AAG3B,MAAM,yBAAyB;
|
|
1
|
+
{"version":3,"file":"voice-presentation.js","sources":["../../../../agent-runtime/src/voice-presentation.ts"],"sourcesContent":["/**\n * How voice-mode transcript entries present, shared by every chat surface\n * (Olympus, the Chrome side panel, the mobile app) so a spoken turn, a\n * delegation the live voice model handed off, and an interim spoken update\n * read the same everywhere. The wire contract is the deep-agent host's\n * `additional_kwargs.metadata` (exposed as `message.metadata.custom`):\n *\n * - `source: \"voice\"` — a spoken turn; `voice_live: true` while it is still\n * being heard or spoken (the ephemeral entry the durable row replaces);\n * - `source: \"text\"` — a message typed into the live conversation;\n * - `source: \"voice_delegation\"` (id prefix `voicetask_`) — the unit of work\n * the live voice model delegated to the thread.\n */\nimport { getExternalStoreMessages, type ThreadMessage } from '@assistant-ui/core';\n\n/** `metadata.custom.source` of a spoken turn. */\nexport const VOICE_SOURCE_SPOKEN = 'voice';\n/** `metadata.custom.source` of a message typed into the live conversation. */\nexport const VOICE_SOURCE_TYPED = 'text';\n/** `metadata.custom.source` of a voice delegation's anchor message. */\nexport const VOICE_SOURCE_DELEGATION = 'voice_delegation';\n/** Id prefix of a voice delegation's anchor message (the working signal on\n * hosts that drop the command's metadata). */\nexport const VOICE_DELEGATION_ID_PREFIX = 'voicetask_';\n/** `metadata.custom` flag on a spoken turn still in flight. */\nexport const VOICE_LIVE_KEY = 'voice_live';\n/** `metadata.custom` list of the wire ids a grouped spoken bubble stands for\n * (see `groupSpokenUserTurns`), so id-keyed lookups such as checkpoint markers\n * can resolve any member to the bubble. */\nexport const VOICE_TURN_IDS_KEY = 'voice_turn_ids';\n\n/** The delegated run's interim-update tool (agora `send_voice_update`). */\nexport const VOICE_UPDATE_TOOL_NAME = 'send_voice_update';\n\n/** Trailing hint on the live-session strip, worded once for every surface. */\nexport const VOICE_LIVE_TYPED_HINT = 'typed messages go to the voice conversation';\n\nexport interface VoiceMessageMarker {\n /** The thread message id; a host may not have assigned one yet. */\n messageId: string | undefined;\n /** The thread message's `metadata.custom`, when any. */\n custom: Record<string, unknown> | undefined;\n}\n\n/** Whether a thread message is a voice delegation's anchor (the ask the live\n * voice model handed to the thread), by source or by id prefix. */\nexport function isVoiceDelegationMessage({ messageId, custom }: VoiceMessageMarker): boolean {\n return (\n custom?.source === VOICE_SOURCE_DELEGATION ||\n (typeof messageId === 'string' && messageId.startsWith(VOICE_DELEGATION_ID_PREFIX))\n );\n}\n\nexport interface VoiceProvenance {\n /** Chip copy: \"Listening\", \"Speaking\", \"Spoken\", or \"Delegated from voice\". */\n readonly label: string;\n /** True while the turn is still being heard or spoken. */\n readonly live: boolean;\n}\n\n// These values are read directly by useAuiState/useSyncExternalStore selectors.\n// Equal presentation must retain its identity, even when a transport replaces\n// the message metadata. Fresh objects here cause React's update-depth crash.\nconst SPOKEN_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Spoken',\n live: false,\n});\nconst LISTENING_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Listening',\n live: true,\n});\nconst SPEAKING_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Speaking',\n live: true,\n});\nconst DELEGATED_PROVENANCE: VoiceProvenance = Object.freeze({\n label: 'Delegated from voice',\n live: false,\n});\n\n/**\n * The provenance chip for a message, or `null` for ordinary chat messages so\n * the chip is free to mount on every row. A spoken turn still in flight reads\n * as what is happening (\"Listening\" for the user, \"Speaking\" for the\n * assistant) rather than as a finished \"Spoken\" turn; a typed-in-voice turn\n * is a normal message and gets no chip. Results are immutable and stable for\n * equal presentation, so all surfaces can use this function as a selector.\n */\nexport function voiceProvenanceLabel({\n messageId,\n custom,\n role,\n}: VoiceMessageMarker & { role: 'user' | 'assistant' | string }): VoiceProvenance | null {\n const source = custom?.source;\n if (source === VOICE_SOURCE_SPOKEN) {\n if (custom?.[VOICE_LIVE_KEY] === true) {\n return role === 'user' ? LISTENING_PROVENANCE : SPEAKING_PROVENANCE;\n }\n return SPOKEN_PROVENANCE;\n }\n if (isVoiceDelegationMessage({ messageId, custom })) {\n return DELEGATED_PROVENANCE;\n }\n return null;\n}\n\nconst isRecord = (value: unknown): value is Record<string, unknown> =>\n typeof value === 'object' && value !== null && !Array.isArray(value);\n\n/**\n * Whether a part of an assistant message holds the words of a spoken\n * assistant turn.\n *\n * The converter joins consecutive assistant entries into one message. The\n * host appends a live turn while it is heard, and a delegated run keeps\n * appending its own steps after it, so a turn spoken during a run becomes a\n * text part inside the run's message, before the run's later tool calls.\n * Grouped views put the text before the last tool call in the details panel\n * as the run's narration; they use this to keep the spoken words visible.\n *\n * The joined message's `metadata.custom` merges every entry in it, so this\n * reads the part's own entry, which the converter binds to the part.\n */\nexport function isSpokenTurnTextPart(part: { readonly type: string }): boolean {\n if (part.type !== 'text') return false;\n const entries: readonly unknown[] = getExternalStoreMessages<unknown>(\n part as ThreadMessage['content'][number]\n );\n return entries.some((entry) => {\n if (!isRecord(entry) || entry.role !== 'assistant' || !isRecord(entry.metadata)) return false;\n const custom = entry.metadata.custom;\n return isRecord(custom) && custom.source === VOICE_SOURCE_SPOKEN;\n });\n}\n\nexport interface VoiceUpdateToolCall {\n /** `mode: \"speak\"` — read aloud to the user; otherwise a silent progress note. */\n spoken: boolean;\n /** The update's words. */\n text: string;\n /** Whether the live session took it; `null` while the call is still running. */\n delivered: boolean | null;\n}\n\n/**\n * What a `send_voice_update` tool call did, from its arguments and the tool's\n * teaching-text result (agora returns prose, not JSON, so the run can read it).\n */\nexport function describeVoiceUpdateToolCall({\n args,\n result,\n}: {\n args: Record<string, unknown> | undefined;\n result: unknown;\n}): VoiceUpdateToolCall {\n const text = typeof args?.text === 'string' ? args.text.trim() : '';\n const spoken = args?.mode === 'speak';\n if (typeof result !== 'string' || result.trim() === '') {\n return { spoken, text, delivered: null };\n }\n const outcome = result.toLowerCase();\n const failed =\n outcome.includes('could not be delivered') ||\n outcome.includes('was not delivered') ||\n outcome.includes('rejected the update') ||\n outcome.includes('has ended') ||\n outcome.includes('not configured') ||\n outcome.includes('no voice session');\n return { spoken, text, delivered: !failed };\n}\n\n/** The card's status line for a voice update in a given tool-call state. */\nexport function voiceUpdateStatusLabel(\n call: VoiceUpdateToolCall,\n status: 'running' | 'complete' | 'incomplete' | 'requires-action' | undefined\n): string {\n if (status === 'running' || (call.delivered === null && status !== 'incomplete')) {\n return call.spoken ? 'Saying to you…' : 'Noting progress…';\n }\n if (call.delivered === false || status === 'incomplete') {\n return call.spoken ? 'Could not say this to you' : 'Progress note not delivered';\n }\n return call.spoken ? 'Said aloud' : 'Progress noted silently';\n}\n"],"names":[],"mappings":";AAgBO,MAAM,sBAAsB;AAI5B,MAAM,0BAA0B;AAGhC,MAAM,6BAA6B;AAEnC,MAAM,iBAAiB;AAIvB,MAAM,qBAAqB;AAG3B,MAAM,yBAAyB;AAG/B,MAAM,wBAAwB;AAW9B,SAAS,yBAAyB,EAAE,WAAW,UAAuC;AAC3F,UACE,iCAAQ,YAAW,2BAClB,OAAO,cAAc,YAAY,UAAU,WAAW,0BAA0B;AAErF;AAuDA,MAAM,WAAW,CAAC,UAChB,OAAO,UAAU,YAAY,UAAU,QAAQ,CAAC,MAAM,QAAQ,KAAK;AAgB9D,SAAS,qBAAqB,MAA0C;AAC7E,MAAI,KAAK,SAAS,OAAQ,QAAO;AACjC,QAAM,UAA8B;AAAA,IAClC;AAAA,EAAA;AAEF,SAAO,QAAQ,KAAK,CAAC,UAAU;AAC7B,QAAI,CAAC,SAAS,KAAK,KAAK,MAAM,SAAS,eAAe,CAAC,SAAS,MAAM,QAAQ,EAAG,QAAO;AACxF,UAAM,SAAS,MAAM,SAAS;AAC9B,WAAO,SAAS,MAAM,KAAK,OAAO,WAAW;AAAA,EAC/C,CAAC;AACH;AAeO,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AACF,GAGwB;AACtB,QAAM,OAAO,QAAO,6BAAM,UAAS,WAAW,KAAK,KAAK,SAAS;AACjE,QAAM,UAAS,6BAAM,UAAS;AAC9B,MAAI,OAAO,WAAW,YAAY,OAAO,KAAA,MAAW,IAAI;AACtD,WAAO,EAAE,QAAQ,MAAM,WAAW,KAAA;AAAA,EACpC;AACA,QAAM,UAAU,OAAO,YAAA;AACvB,QAAM,SACJ,QAAQ,SAAS,wBAAwB,KACzC,QAAQ,SAAS,mBAAmB,KACpC,QAAQ,SAAS,qBAAqB,KACtC,QAAQ,SAAS,WAAW,KAC5B,QAAQ,SAAS,gBAAgB,KACjC,QAAQ,SAAS,kBAAkB;AACrC,SAAO,EAAE,QAAQ,MAAM,WAAW,CAAC,OAAA;AACrC;AAGO,SAAS,uBACd,MACA,QACQ;AACR,MAAI,WAAW,aAAc,KAAK,cAAc,QAAQ,WAAW,cAAe;AAChF,WAAO,KAAK,SAAS,mBAAmB;AAAA,EAC1C;AACA,MAAI,KAAK,cAAc,SAAS,WAAW,cAAc;AACvD,WAAO,KAAK,SAAS,8BAA8B;AAAA,EACrD;AACA,SAAO,KAAK,SAAS,eAAe;AACtC;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useQuery, QueryClientContext, QueryClient } from "@tanstack/react-query";
|
|
2
|
-
import {
|
|
2
|
+
import { useContext, useState, useMemo, useCallback } from "react";
|
|
3
3
|
import { AthenaAuthContext } from "../auth/AthenaAuthContext.js";
|
|
4
4
|
import { fetchGraphQL, AthenaGraphQLError } from "../chat-ui/mentions/suggestions/data/api-client.js";
|
|
5
5
|
import { useAthenaConfig } from "../provider/AthenaContext.js";
|
package/dist/chat/AthenaChat.cjs
CHANGED
|
@@ -70,6 +70,10 @@ const index = require("../toolkits/index.cjs");
|
|
|
70
70
|
const runActivity = require("./run-activity.cjs");
|
|
71
71
|
const messageTime = require("./message-time.cjs");
|
|
72
72
|
const threadScrollToBottom = require("./thread-scroll-to-bottom.cjs");
|
|
73
|
+
const reactQuery = require("@tanstack/react-query");
|
|
74
|
+
const runtimeCatalog = require("../catalog/runtime-catalog.cjs");
|
|
75
|
+
const statewireLifecycle = require("../runtime/statewire-lifecycle.cjs");
|
|
76
|
+
const chatVoiceControls = require("./chat-voice-controls.cjs");
|
|
73
77
|
const toolNames = require("../agent-runtime/src/tool-names.cjs");
|
|
74
78
|
const subagents = require("../agent-runtime/src/subagents.cjs");
|
|
75
79
|
const githubWakeEvent = require("../agent-runtime/src/github-wake-event.cjs");
|
|
@@ -146,7 +150,11 @@ const withNestedPtcMessages = (ToolUI) => {
|
|
|
146
150
|
};
|
|
147
151
|
return ToolUIWithNestedPtcMessages;
|
|
148
152
|
};
|
|
149
|
-
const AthenaChat = ({
|
|
153
|
+
const AthenaChat = (props) => {
|
|
154
|
+
const queryClient = runtimeCatalog.useCatalogQueryClient();
|
|
155
|
+
return /* @__PURE__ */ jsxRuntime.jsx(reactQuery.QueryClientProvider, { client: queryClient, children: /* @__PURE__ */ jsxRuntime.jsx(AthenaChatContent, { ...props }) });
|
|
156
|
+
};
|
|
157
|
+
const AthenaChatContent = ({
|
|
150
158
|
className,
|
|
151
159
|
welcomeMessage = "Hello there!",
|
|
152
160
|
welcomeSubtext = "What can I help you with?",
|
|
@@ -159,7 +167,8 @@ const AthenaChat = ({
|
|
|
159
167
|
components,
|
|
160
168
|
groupToolCalls = true,
|
|
161
169
|
composer: composerSlots,
|
|
162
|
-
dictation = true
|
|
170
|
+
dictation = true,
|
|
171
|
+
voice = true
|
|
163
172
|
}) => {
|
|
164
173
|
var _a, _b, _c, _d, _e, _f;
|
|
165
174
|
const athenaConfig = AthenaContext.useAthenaConfig();
|
|
@@ -301,6 +310,7 @@ const AthenaChat = ({
|
|
|
301
310
|
tools,
|
|
302
311
|
slots: composerSlots,
|
|
303
312
|
dictation,
|
|
313
|
+
voice: readOnly ? false : voice,
|
|
304
314
|
welcomeSuggestionCount: welcomeSuggestions.length
|
|
305
315
|
}
|
|
306
316
|
)
|
|
@@ -359,7 +369,7 @@ const ATHENA_CHAT_MENTION_CATEGORIES = [
|
|
|
359
369
|
"projects",
|
|
360
370
|
"folders"
|
|
361
371
|
];
|
|
362
|
-
const AthenaChatComposer = ({ tools, slots, dictation, welcomeSuggestionCount }) => {
|
|
372
|
+
const AthenaChatComposer = ({ tools, slots, dictation, voice: voiceOptions, welcomeSuggestionCount }) => {
|
|
363
373
|
const aui = react.useAui();
|
|
364
374
|
const threadId = threadIdContext.useAthenaStatewireThreadId();
|
|
365
375
|
const { appUrl } = AthenaContext.useAthenaConfig();
|
|
@@ -384,6 +394,7 @@ const AthenaChatComposer = ({ tools, slots, dictation, welcomeSuggestionCount })
|
|
|
384
394
|
return ((_a = state.optional.thread) == null ? void 0 : _a.isRunning) ?? false;
|
|
385
395
|
});
|
|
386
396
|
const connection = threadStatus.useDeepAgentConnection();
|
|
397
|
+
const { voice, active: voiceActive, enabled: voiceEnabled, audioRef } = chatVoiceControls.useComposerChatVoice({ options: voiceOptions });
|
|
387
398
|
const runLive = react.useAuiState((state) => {
|
|
388
399
|
const thread = state.optional.thread;
|
|
389
400
|
return thread ? threadStatus.readRunLive(thread, connection) : false;
|
|
@@ -420,7 +431,7 @@ const AthenaChatComposer = ({ tools, slots, dictation, welcomeSuggestionCount })
|
|
|
420
431
|
onAutoEnd: appendSpokenText
|
|
421
432
|
});
|
|
422
433
|
const recording = dictationEnabled && dictationCtl.isActive;
|
|
423
|
-
const showMic = dictationEnabled && dictationCtl.isSupported;
|
|
434
|
+
const showMic = dictationEnabled && dictationCtl.isSupported && !voiceActive;
|
|
424
435
|
const { isActive: dictationActive, cancel: cancelDictation } = dictationCtl;
|
|
425
436
|
react$1.useEffect(() => {
|
|
426
437
|
if (!dictationEnabled && dictationActive) cancelDictation();
|
|
@@ -470,8 +481,13 @@ const AthenaChatComposer = ({ tools, slots, dictation, welcomeSuggestionCount })
|
|
|
470
481
|
[appUrl, aui, clearAttachments, clearQuote, threadId]
|
|
471
482
|
);
|
|
472
483
|
const interceptSubmit = react$1.useCallback(
|
|
473
|
-
(text, draftMarkdown) =>
|
|
474
|
-
|
|
484
|
+
async (text, draftMarkdown) => {
|
|
485
|
+
if (attachmentsRef.current.length > 0 || quoteRef.current !== null) {
|
|
486
|
+
return sendComposed({ text, draftMarkdown });
|
|
487
|
+
}
|
|
488
|
+
return voice.phase === "live" && text.length > 0 ? voice.sendUserText(text) : false;
|
|
489
|
+
},
|
|
490
|
+
[sendComposed, voice.phase, voice.sendUserText]
|
|
475
491
|
);
|
|
476
492
|
const hasPendingExtras = react$1.useCallback(
|
|
477
493
|
() => attachmentsRef.current.length > 0 || quoteRef.current !== null,
|
|
@@ -543,104 +559,110 @@ const AthenaChatComposer = ({ tools, slots, dictation, welcomeSuggestionCount })
|
|
|
543
559
|
aui.composer.setText(send.text);
|
|
544
560
|
aui.composer.send({ steer: false });
|
|
545
561
|
}, [appendSpokenText, aui, dictationCtl, isRunning, sendComposed, sessionLane, slots, threadId]);
|
|
546
|
-
return /* @__PURE__ */ jsxRuntime.
|
|
547
|
-
"
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
560
|
-
/* @__PURE__ */ jsxRuntime.
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
recording && /* @__PURE__ */ jsxRuntime.jsx(
|
|
584
|
-
DictationStrip.DictationStrip,
|
|
585
|
-
{
|
|
586
|
-
status: dictationCtl.status,
|
|
587
|
-
transcript: dictationCtl.transcript,
|
|
588
|
-
stream: dictationCtl.stream,
|
|
589
|
-
stoppingLabel: dictationCtl.engine.stoppingLabel
|
|
590
|
-
}
|
|
591
|
-
),
|
|
592
|
-
dictationEnabled && dictationCtl.status === dictationState.DICTATION_STATUSES.error && dictationCtl.error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "aui-dictation-error px-1.5 pb-1 text-destructive text-xs", role: "alert", children: dictationCtl.error.message })
|
|
593
|
-
] }),
|
|
594
|
-
toolbarStart: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: recording ? /* @__PURE__ */ jsxRuntime.jsx(dictationControls.DictationCancelButton, { onClick: dictationCtl.cancel }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
595
|
-
/* @__PURE__ */ jsxRuntime.jsx(FileUploadButton.FileUploadButton, { className: "aui-composer-attach size-8 rounded-full p-0 disabled:opacity-30" }),
|
|
596
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
597
|
-
athenaComposerControls.AthenaComposerMentionButton,
|
|
598
|
-
{
|
|
599
|
-
onClick: () => {
|
|
600
|
-
var _a, _b;
|
|
601
|
-
return (_b = (_a = composerRef.current) == null ? void 0 : _a.openMentionMenu) == null ? void 0 : _b.call(_a);
|
|
562
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(ComposerDropZone.ComposerDropZone, { onDragActiveChange: setDragActive, children: [
|
|
563
|
+
/* @__PURE__ */ jsxRuntime.jsx("audio", { ref: audioRef, autoPlay: true, playsInline: true }),
|
|
564
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
565
|
+
"div",
|
|
566
|
+
{
|
|
567
|
+
className: cnfast.cn("aui-composer-entrance", entrance.className),
|
|
568
|
+
style: entrance.style,
|
|
569
|
+
onFocus: keyboardHint.onFocus,
|
|
570
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
571
|
+
chatComposerDock.ChatComposerDock,
|
|
572
|
+
{
|
|
573
|
+
appearance: "paper",
|
|
574
|
+
dragActive,
|
|
575
|
+
aboveSurface: /* @__PURE__ */ jsxRuntime.jsx(threadScrollToBottom.ThreadScrollToBottom, {}),
|
|
576
|
+
beforeEditor: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
577
|
+
/* @__PURE__ */ jsxRuntime.jsx(chatVoiceControls.ChatVoiceStatus, { voice }),
|
|
578
|
+
/* @__PURE__ */ jsxRuntime.jsx(ComposerQuotePreview.ComposerQuotePreview, {}),
|
|
579
|
+
/* @__PURE__ */ jsxRuntime.jsx(ComposerAttachmentPreview.ComposerAttachmentPreview, {})
|
|
580
|
+
] }),
|
|
581
|
+
editor: /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
582
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { className: cnfast.cn(recording && "hidden"), children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
583
|
+
tiptapComposer.TiptapComposer,
|
|
584
|
+
{
|
|
585
|
+
ref: composerRef,
|
|
586
|
+
threadId,
|
|
587
|
+
appearance: "paper",
|
|
588
|
+
placeholder: (runLive ? slots == null ? void 0 : slots.runningPlaceholder : void 0) ?? (slots == null ? void 0 : slots.placeholder) ?? DEFAULT_COMPOSER_PLACEHOLDER,
|
|
589
|
+
tools,
|
|
590
|
+
rootCategories,
|
|
591
|
+
onDraftStateChange,
|
|
592
|
+
waitForHostUploads,
|
|
593
|
+
interceptSubmit,
|
|
594
|
+
hasPendingExtras,
|
|
595
|
+
holdPendingExtras,
|
|
596
|
+
onAttachmentError: setComposerNotice,
|
|
597
|
+
fileIntake,
|
|
598
|
+
onSubmitted: keyboardHint.onSubmitted
|
|
602
599
|
}
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
}
|
|
615
|
-
),
|
|
616
|
-
/* @__PURE__ */ jsxRuntime.jsx(
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
600
|
+
) }),
|
|
601
|
+
notice && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "aui-composer-notice px-1.5 pb-1 text-destructive text-xs", role: "alert", children: notice }),
|
|
602
|
+
recording && /* @__PURE__ */ jsxRuntime.jsx(
|
|
603
|
+
DictationStrip.DictationStrip,
|
|
604
|
+
{
|
|
605
|
+
status: dictationCtl.status,
|
|
606
|
+
transcript: dictationCtl.transcript,
|
|
607
|
+
stream: dictationCtl.stream,
|
|
608
|
+
stoppingLabel: dictationCtl.engine.stoppingLabel
|
|
609
|
+
}
|
|
610
|
+
),
|
|
611
|
+
dictationEnabled && dictationCtl.status === dictationState.DICTATION_STATUSES.error && dictationCtl.error && /* @__PURE__ */ jsxRuntime.jsx("p", { className: "aui-dictation-error px-1.5 pb-1 text-destructive text-xs", role: "alert", children: dictationCtl.error.message })
|
|
612
|
+
] }),
|
|
613
|
+
toolbarStart: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: recording ? /* @__PURE__ */ jsxRuntime.jsx(dictationControls.DictationCancelButton, { onClick: dictationCtl.cancel }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
614
|
+
/* @__PURE__ */ jsxRuntime.jsx(FileUploadButton.FileUploadButton, { className: "aui-composer-attach size-8 rounded-full p-0 disabled:opacity-30" }),
|
|
615
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
616
|
+
athenaComposerControls.AthenaComposerMentionButton,
|
|
617
|
+
{
|
|
618
|
+
onClick: () => {
|
|
619
|
+
var _a, _b;
|
|
620
|
+
return (_b = (_a = composerRef.current) == null ? void 0 : _a.openMentionMenu) == null ? void 0 : _b.call(_a);
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
),
|
|
624
|
+
/* @__PURE__ */ jsxRuntime.jsx(chatPickers.AthenaChatModeMenu, {}),
|
|
625
|
+
slots == null ? void 0 : slots.toolbarStart
|
|
626
|
+
] }) }),
|
|
627
|
+
toolbarEnd: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-1", children: recording ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
628
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
629
|
+
dictationControls.DictationStopButton,
|
|
630
|
+
{
|
|
631
|
+
onClick: () => void stopDictation(),
|
|
632
|
+
disabled: dictationCtl.status === dictationState.DICTATION_STATUSES.stopping
|
|
633
|
+
}
|
|
634
|
+
),
|
|
635
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
636
|
+
athenaComposerControls.AthenaComposerSendButton,
|
|
637
|
+
{
|
|
638
|
+
action: isRunning ? "queue" : "send",
|
|
639
|
+
onSend: () => void sendDictation(),
|
|
640
|
+
disabled: dictationCtl.status !== dictationState.DICTATION_STATUSES.listening || isUploading,
|
|
641
|
+
title: isUploading ? "Upload in progress..." : void 0
|
|
642
|
+
}
|
|
643
|
+
)
|
|
644
|
+
] }) : /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
645
|
+
slots == null ? void 0 : slots.toolbarEnd,
|
|
646
|
+
showMic && /* @__PURE__ */ jsxRuntime.jsx(dictationControls.DictationMicButton, { onClick: dictationCtl.start, disabled: isUploading }),
|
|
647
|
+
voiceEnabled && /* @__PURE__ */ jsxRuntime.jsx(chatVoiceControls.ChatVoiceButton, { voice, disabled: isUploading || dictationCtl.isActive || !statewireLifecycle.isStatewireChannelLive(connection) }),
|
|
648
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
649
|
+
composerSendOrStop.ComposerSendOrStop,
|
|
650
|
+
{
|
|
651
|
+
composerRef,
|
|
652
|
+
hasDraft: hasText || hasExtras,
|
|
653
|
+
liveVoice: voice.phase === "live" && !hasExtras,
|
|
654
|
+
sendBlockedReason: isUploading ? "Upload in progress..." : null,
|
|
655
|
+
onBeforeSend: slots == null ? void 0 : slots.onBeforeSend,
|
|
656
|
+
components: athenaComposerControls.ATHENA_COMPOSER_COMPONENTS
|
|
657
|
+
}
|
|
658
|
+
)
|
|
659
|
+
] }) }),
|
|
660
|
+
belowSurface: /* @__PURE__ */ jsxRuntime.jsx(composerKeyboardHint.ComposerKeyboardHint, { visible: keyboardHint.visible })
|
|
661
|
+
}
|
|
662
|
+
)
|
|
663
|
+
}
|
|
664
|
+
)
|
|
665
|
+
] });
|
|
644
666
|
};
|
|
645
667
|
const MessageError = () => /* @__PURE__ */ jsxRuntime.jsx(react.MessagePrimitive.Error, { children: /* @__PURE__ */ jsxRuntime.jsxs(react.ErrorPrimitive.Root, { className: "aui-message-error-root mt-2 flex items-start gap-2 rounded-md border border-destructive bg-destructive/10 p-3 text-destructive text-sm dark:bg-destructive/5 dark:text-red-200", children: [
|
|
646
668
|
/* @__PURE__ */ jsxRuntime.jsx(lucideReact.AlertCircleIcon, { className: "mt-0.5 size-4 shrink-0" }),
|