@athenaintel/react 0.24.1 → 0.26.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 +24 -0
- package/dist/assets/AssetPanel.cjs +4 -3
- package/dist/assets/AssetPanel.cjs.map +1 -1
- package/dist/assets/AssetPanel.js +4 -3
- package/dist/assets/AssetPanel.js.map +1 -1
- package/dist/assets/AthenaAssetEmbed.cjs +2 -1
- package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
- package/dist/assets/AthenaAssetEmbed.js +2 -1
- package/dist/assets/AthenaAssetEmbed.js.map +1 -1
- package/dist/assets/use-asset-embed.cjs +22 -23
- package/dist/assets/use-asset-embed.cjs.map +1 -1
- package/dist/assets/use-asset-embed.d.ts +9 -0
- package/dist/assets/use-asset-embed.js +22 -23
- package/dist/assets/use-asset-embed.js.map +1 -1
- package/dist/auth/AthenaAuthProvider.cjs +32 -4
- package/dist/auth/AthenaAuthProvider.cjs.map +1 -1
- package/dist/auth/AthenaAuthProvider.d.ts +21 -0
- package/dist/auth/AthenaAuthProvider.js +33 -5
- package/dist/auth/AthenaAuthProvider.js.map +1 -1
- package/dist/auth/AthenaCredentialSourceContext.cjs +21 -0
- package/dist/auth/AthenaCredentialSourceContext.cjs.map +1 -0
- package/dist/auth/AthenaCredentialSourceContext.d.ts +14 -0
- package/dist/auth/AthenaCredentialSourceContext.js +21 -0
- package/dist/auth/AthenaCredentialSourceContext.js.map +1 -0
- package/dist/auth/AthenaSSOProvider.cjs +71 -47
- package/dist/auth/AthenaSSOProvider.cjs.map +1 -1
- package/dist/auth/AthenaSSOProvider.js +71 -47
- package/dist/auth/AthenaSSOProvider.js.map +1 -1
- package/dist/auth/credential-source.cjs +120 -0
- package/dist/auth/credential-source.cjs.map +1 -0
- package/dist/auth/credential-source.d.ts +68 -0
- package/dist/auth/credential-source.js +120 -0
- package/dist/auth/credential-source.js.map +1 -0
- package/dist/auth/types.d.ts +9 -0
- package/dist/chat/AthenaChat.cjs +8 -0
- package/dist/chat/AthenaChat.cjs.map +1 -1
- package/dist/chat/AthenaChat.js +8 -0
- package/dist/chat/AthenaChat.js.map +1 -1
- package/dist/chat-ui/composer/run-input-rules-on-enter.cjs +14 -0
- package/dist/chat-ui/composer/run-input-rules-on-enter.cjs.map +1 -0
- package/dist/chat-ui/composer/run-input-rules-on-enter.d.ts +10 -0
- package/dist/chat-ui/composer/run-input-rules-on-enter.js +14 -0
- package/dist/chat-ui/composer/run-input-rules-on-enter.js.map +1 -0
- package/dist/chat-ui/composer/tiptap-composer.cjs +7 -4
- package/dist/chat-ui/composer/tiptap-composer.cjs.map +1 -1
- package/dist/chat-ui/composer/tiptap-composer.js +7 -4
- package/dist/chat-ui/composer/tiptap-composer.js.map +1 -1
- package/dist/chat-ui/markdown-storage.cjs +16 -0
- package/dist/chat-ui/markdown-storage.cjs.map +1 -0
- package/dist/chat-ui/markdown-storage.d.ts +21 -0
- package/dist/chat-ui/markdown-storage.js +16 -0
- package/dist/chat-ui/markdown-storage.js.map +1 -0
- package/dist/chat-ui/mentions/suggestions/data/api-client.cjs +20 -11
- package/dist/chat-ui/mentions/suggestions/data/api-client.cjs.map +1 -1
- package/dist/chat-ui/mentions/suggestions/data/api-client.d.ts +11 -2
- package/dist/chat-ui/mentions/suggestions/data/api-client.js +20 -11
- package/dist/chat-ui/mentions/suggestions/data/api-client.js.map +1 -1
- package/dist/chat-ui/rich-text/chat-node-views.cjs.map +1 -1
- package/dist/chat-ui/rich-text/chat-node-views.js.map +1 -1
- package/dist/chat-ui/rich-text/chat-text-schema.cjs +15 -10
- package/dist/chat-ui/rich-text/chat-text-schema.cjs.map +1 -1
- package/dist/chat-ui/rich-text/chat-text-schema.js +11 -6
- package/dist/chat-ui/rich-text/chat-text-schema.js.map +1 -1
- package/dist/collab/mint.cjs +6 -15
- package/dist/collab/mint.cjs.map +1 -1
- package/dist/collab/mint.d.ts +8 -0
- package/dist/collab/mint.js +6 -15
- package/dist/collab/mint.js.map +1 -1
- package/dist/collab/presence-mint.cjs +20 -16
- package/dist/collab/presence-mint.cjs.map +1 -1
- package/dist/collab/presence-mint.js +21 -17
- package/dist/collab/presence-mint.js.map +1 -1
- package/dist/collab/presence-react.cjs +12 -5
- package/dist/collab/presence-react.cjs.map +1 -1
- package/dist/collab/presence-react.d.ts +3 -1
- package/dist/collab/presence-react.js +12 -5
- package/dist/collab/presence-react.js.map +1 -1
- package/dist/collab/react.cjs +5 -2
- package/dist/collab/react.cjs.map +1 -1
- package/dist/collab/react.js +5 -2
- package/dist/collab/react.js.map +1 -1
- package/dist/dictation/use-athena-dictation-engine.cjs +12 -11
- package/dist/dictation/use-athena-dictation-engine.cjs.map +1 -1
- package/dist/dictation/use-athena-dictation-engine.d.ts +4 -3
- package/dist/dictation/use-athena-dictation-engine.js +12 -11
- package/dist/dictation/use-athena-dictation-engine.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/packages/agent-runtime/src/conversation-list.cjs +3 -0
- package/dist/packages/agent-runtime/src/conversation-list.cjs.map +1 -1
- package/dist/packages/agent-runtime/src/conversation-list.js +3 -0
- package/dist/packages/agent-runtime/src/conversation-list.js.map +1 -1
- package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs +2 -2
- package/dist/packages/agent-runtime/src/generated/runconfig-contract.cjs.map +1 -1
- package/dist/packages/agent-runtime/src/generated/runconfig-contract.js +2 -2
- package/dist/packages/agent-runtime/src/generated/runconfig-contract.js.map +1 -1
- package/dist/packages/agent-runtime/src/use-conversation-list.cjs +1 -0
- package/dist/packages/agent-runtime/src/use-conversation-list.cjs.map +1 -1
- package/dist/packages/agent-runtime/src/use-conversation-list.js +1 -0
- package/dist/packages/agent-runtime/src/use-conversation-list.js.map +1 -1
- package/dist/packages/react/package.json.cjs +1 -1
- package/dist/packages/react/package.json.js +1 -1
- package/dist/provider/AthenaContext.cjs.map +1 -1
- package/dist/provider/AthenaContext.d.ts +7 -1
- package/dist/provider/AthenaContext.js.map +1 -1
- package/dist/provider/AthenaProvider.cjs +23 -2
- package/dist/provider/AthenaProvider.cjs.map +1 -1
- package/dist/provider/AthenaProvider.js +23 -2
- package/dist/provider/AthenaProvider.js.map +1 -1
- package/dist/runtime/auth-refusal-restart.cjs +66 -0
- package/dist/runtime/auth-refusal-restart.cjs.map +1 -0
- package/dist/runtime/auth-refusal-restart.d.ts +35 -0
- package/dist/runtime/auth-refusal-restart.js +66 -0
- package/dist/runtime/auth-refusal-restart.js.map +1 -0
- package/dist/runtime/auth.cjs +58 -21
- package/dist/runtime/auth.cjs.map +1 -1
- package/dist/runtime/auth.d.ts +11 -1
- package/dist/runtime/auth.js +59 -22
- package/dist/runtime/auth.js.map +1 -1
- package/dist/runtime/credential-renewal.cjs +29 -0
- package/dist/runtime/credential-renewal.cjs.map +1 -0
- package/dist/runtime/credential-renewal.d.ts +35 -0
- package/dist/runtime/credential-renewal.js +29 -0
- package/dist/runtime/credential-renewal.js.map +1 -0
- package/dist/runtime/statewire-run-config.cjs +1 -1
- package/dist/runtime/statewire-run-config.cjs.map +1 -1
- package/dist/runtime/statewire-run-config.d.ts +1 -1
- package/dist/runtime/statewire-run-config.js +1 -1
- package/dist/runtime/statewire-run-config.js.map +1 -1
- package/dist/search/useAthenaRepoSearch.cjs +3 -5
- package/dist/search/useAthenaRepoSearch.cjs.map +1 -1
- package/dist/search/useAthenaRepoSearch.d.ts +7 -7
- package/dist/search/useAthenaRepoSearch.js +3 -5
- package/dist/search/useAthenaRepoSearch.js.map +1 -1
- package/dist/threads/api.cjs +5 -1
- package/dist/threads/api.cjs.map +1 -1
- package/dist/threads/api.js +5 -1
- package/dist/threads/api.js.map +1 -1
- package/dist/threads/conversation-list-fetcher.cjs +5 -5
- package/dist/threads/conversation-list-fetcher.cjs.map +1 -1
- package/dist/threads/conversation-list-fetcher.d.ts +6 -5
- package/dist/threads/conversation-list-fetcher.js +5 -5
- package/dist/threads/conversation-list-fetcher.js.map +1 -1
- package/dist/threads/statewire-thread-list.cjs +13 -14
- package/dist/threads/statewire-thread-list.cjs.map +1 -1
- package/dist/threads/statewire-thread-list.js +13 -14
- package/dist/threads/statewire-thread-list.js.map +1 -1
- package/dist/threads/use-rest-conversation-history.cjs +6 -2
- package/dist/threads/use-rest-conversation-history.cjs.map +1 -1
- package/dist/threads/use-rest-conversation-history.d.ts +4 -1
- package/dist/threads/use-rest-conversation-history.js +7 -3
- package/dist/threads/use-rest-conversation-history.js.map +1 -1
- package/dist/threads/use-statewire-conversation-history.cjs +9 -2
- package/dist/threads/use-statewire-conversation-history.cjs.map +1 -1
- package/dist/threads/use-statewire-conversation-history.d.ts +5 -1
- package/dist/threads/use-statewire-conversation-history.js +10 -3
- package/dist/threads/use-statewire-conversation-history.js.map +1 -1
- package/dist/threads/use-thread-archive.cjs +2 -1
- package/dist/threads/use-thread-archive.cjs.map +1 -1
- package/dist/threads/use-thread-archive.d.ts +3 -1
- package/dist/threads/use-thread-archive.js +2 -1
- package/dist/threads/use-thread-archive.js.map +1 -1
- package/dist/threads/use-thread-favorite.cjs.map +1 -1
- package/dist/threads/use-thread-favorite.d.ts +3 -1
- package/dist/threads/use-thread-favorite.js.map +1 -1
- package/dist/threads/use-thread-field-override.cjs +2 -1
- package/dist/threads/use-thread-field-override.cjs.map +1 -1
- package/dist/threads/use-thread-field-override.d.ts +3 -1
- package/dist/threads/use-thread-field-override.js +2 -1
- package/dist/threads/use-thread-field-override.js.map +1 -1
- package/dist/threads/use-thread-rename.cjs.map +1 -1
- package/dist/threads/use-thread-rename.d.ts +3 -1
- package/dist/threads/use-thread-rename.js.map +1 -1
- package/dist/tools/append-document-tool-ui.cjs +5 -0
- package/dist/tools/append-document-tool-ui.cjs.map +1 -1
- package/dist/tools/append-document-tool-ui.js +5 -0
- package/dist/tools/append-document-tool-ui.js.map +1 -1
- package/dist/tools/tool-uis.cjs +11 -15
- package/dist/tools/tool-uis.cjs.map +1 -1
- package/dist/tools/tool-uis.js +11 -15
- package/dist/tools/tool-uis.js.map +1 -1
- package/dist/voice/use-athena-voice-session.cjs +17 -5
- package/dist/voice/use-athena-voice-session.cjs.map +1 -1
- package/dist/voice/use-athena-voice-session.d.ts +2 -2
- package/dist/voice/use-athena-voice-session.js +17 -5
- package/dist/voice/use-athena-voice-session.js.map +1 -1
- package/package.json +13 -16
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runconfig-contract.js","sources":["../../../../../../agent-runtime/src/generated/runconfig-contract.ts"],"sourcesContent":["// GENERATED FILE — DO NOT EDIT BY HAND.\n//\n// Source of truth (agora):\n// agora/agora/graphs/athena_deep_agent/run_config.py (_PARSED_CUSTOM_KEYS / _COMPANION_CUSTOM_KEYS / PER_SEND_CUSTOM_KEYS)\n// agora/agora/graphs/athena_deep_agent/thread_config.py (server config lane + config/* command names)\n// agora/agora/graphs/athena_deep_agent/session_asset.py (KNOWN_START_CHANNELS / DEEP_AGENT_RUNTIME_MARKER)\n// agora/agora/graphs/athena_deep_agent/client_tools.py (client-tool interrupt + result-envelope literals)\n// agora/agora/graphs/athena_deep_agent/protocol_version.py (wire-contract version negotiation)\n// agora/agora/graphs/athena_deep_agent/message_window.py (interest windows + history commands)\n// agora/agora/type_definitions/collab_agent.py (CAPABILITIES ladder: absent mode + new-agent default)\n//\n// Regenerate:\n// cd agora && mise exec -- infisical run --command 'uv run python scripts/export_runconfig_contract.py'\n//\n// CI verifies this file matches the Python source (agora-check runs the\n// exporter with --check), so hand edits and un-regenerated key changes fail.\n\n/** `runConfig.custom` keys parsed by agora's `parse_deep_agent_run_config`. */\nexport const RUN_CONFIG_PARSED_CUSTOM_KEYS = [\n \"agent_catalog_asset_ids\",\n \"async_subagents\",\n \"catalog_asset_ids\",\n \"coding_worker_asset_id\",\n \"coding_workers\",\n \"compiled_subagents\",\n \"declined_toolkit_ids\",\n \"drive_mounts\",\n \"enable_interpreter\",\n \"enable_persistent_fs\",\n \"enable_sandbox\",\n \"enable_skills\",\n \"enabled_tools\",\n \"environment\",\n \"environment_asset_id\",\n \"environment_id\",\n \"environment_name\",\n \"excluded_middleware\",\n \"excluded_tools\",\n \"extra_middleware\",\n \"include_citation_instructions\",\n \"interpreter_max_ptc_calls\",\n \"interpreter_mode\",\n \"interpreter_ptc\",\n \"interpreter_ptc_exclusive\",\n \"interpreter_runtime\",\n \"interpreter_subagents\",\n \"interpreter_timeout_seconds\",\n \"interrupt_on\",\n \"knowledge_base\",\n \"mcp_server_configs\",\n \"mcp_servers\",\n \"memory\",\n \"permissions\",\n \"project_id\",\n \"recursion_limit\",\n \"run_label\",\n \"sandbox_runtime\",\n \"secret_asset_ids\",\n \"session_machine\",\n \"session_vm_retention\",\n \"skill_asset_ids\",\n \"skills\",\n \"subagents\",\n \"system_prompt\",\n \"tool_description_overrides\",\n \"voice_update_handle\",\n \"workbench\",\n] as const;\n\n/** `runConfig.custom` keys consumed by the surrounding deep-agent request machinery rather than the capability parser. */\nexport const RUN_CONFIG_COMPANION_CUSTOM_KEYS = [\n \"agent\",\n \"allowed_tab_ids\",\n \"app_id\",\n \"channel\",\n \"client_tools\",\n \"collab_agent_id\",\n \"collab_channel_id\",\n \"custom_tool_configs\",\n \"deterministic\",\n \"device_id\",\n \"dry_run\",\n \"enabled_toolkits\",\n \"frontend_available\",\n \"github_identity\",\n \"max_tokens\",\n \"middleware\",\n \"model\",\n \"muses_enabled\",\n \"muses_recall_enabled\",\n \"office_context\",\n \"panel_config\",\n \"run_budget\",\n \"runtime\",\n \"session_id\",\n \"session_origin_kind\",\n \"session_tab_id\",\n \"skip_title_generation\",\n \"source_aop_id\",\n \"start_channel\",\n \"structured_output\",\n \"temperature\",\n \"tool_limit_override\",\n \"trigger_type\",\n \"workspace_id\",\n] as const;\n\n/** Every `runConfig.custom` key some deep-agent request consumer reads. A key outside this set is invisible to the run and trips agora's unknown-key telemetry. */\nexport const RUN_CONFIG_CUSTOM_KEYS = [\n \"agent\",\n \"agent_catalog_asset_ids\",\n \"allowed_tab_ids\",\n \"app_id\",\n \"async_subagents\",\n \"catalog_asset_ids\",\n \"channel\",\n \"client_tools\",\n \"coding_worker_asset_id\",\n \"coding_workers\",\n \"collab_agent_id\",\n \"collab_channel_id\",\n \"compiled_subagents\",\n \"custom_tool_configs\",\n \"declined_toolkit_ids\",\n \"deterministic\",\n \"device_id\",\n \"drive_mounts\",\n \"dry_run\",\n \"enable_interpreter\",\n \"enable_persistent_fs\",\n \"enable_sandbox\",\n \"enable_skills\",\n \"enabled_toolkits\",\n \"enabled_tools\",\n \"environment\",\n \"environment_asset_id\",\n \"environment_id\",\n \"environment_name\",\n \"excluded_middleware\",\n \"excluded_tools\",\n \"extra_middleware\",\n \"frontend_available\",\n \"github_identity\",\n \"include_citation_instructions\",\n \"interpreter_max_ptc_calls\",\n \"interpreter_mode\",\n \"interpreter_ptc\",\n \"interpreter_ptc_exclusive\",\n \"interpreter_runtime\",\n \"interpreter_subagents\",\n \"interpreter_timeout_seconds\",\n \"interrupt_on\",\n \"knowledge_base\",\n \"max_tokens\",\n \"mcp_server_configs\",\n \"mcp_servers\",\n \"memory\",\n \"middleware\",\n \"model\",\n \"muses_enabled\",\n \"muses_recall_enabled\",\n \"office_context\",\n \"panel_config\",\n \"permissions\",\n \"project_id\",\n \"recursion_limit\",\n \"run_budget\",\n \"run_label\",\n \"runtime\",\n \"sandbox_runtime\",\n \"secret_asset_ids\",\n \"session_id\",\n \"session_machine\",\n \"session_origin_kind\",\n \"session_tab_id\",\n \"session_vm_retention\",\n \"skill_asset_ids\",\n \"skills\",\n \"skip_title_generation\",\n \"source_aop_id\",\n \"start_channel\",\n \"structured_output\",\n \"subagents\",\n \"system_prompt\",\n \"temperature\",\n \"tool_description_overrides\",\n \"tool_limit_override\",\n \"trigger_type\",\n \"voice_update_handle\",\n \"workbench\",\n \"workspace_id\",\n] as const;\n\nexport type RunConfigCustomKey = (typeof RUN_CONFIG_CUSTOM_KEYS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const RUN_CONFIG_CUSTOM_KEY_SET: ReadonlySet<string> = new Set(\n RUN_CONFIG_CUSTOM_KEYS,\n);\n\n/** `runConfig.custom` keys a client still carries per send on a thread with server config; every other key is dropped at dispatch. */\nexport const RUN_CONFIG_PER_SEND_CUSTOM_KEYS = [\n \"agent\",\n \"allowed_tab_ids\",\n \"app_id\",\n \"channel\",\n \"client_tools\",\n \"collab_channel_id\",\n \"deterministic\",\n \"device_id\",\n \"dry_run\",\n \"frontend_available\",\n \"github_identity\",\n \"muses_enabled\",\n \"muses_recall_enabled\",\n \"office_context\",\n \"project_id\",\n \"run_budget\",\n \"runtime\",\n \"session_id\",\n \"session_origin_kind\",\n \"session_tab_id\",\n \"skip_title_generation\",\n \"source_aop_id\",\n \"start_channel\",\n \"structured_output\",\n \"tool_limit_override\",\n \"trigger_type\",\n \"voice_update_handle\",\n \"workspace_id\",\n] as const;\n\nexport type RunConfigPerSendCustomKey =\n (typeof RUN_CONFIG_PER_SEND_CUSTOM_KEYS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const RUN_CONFIG_PER_SEND_CUSTOM_KEY_SET: ReadonlySet<string> = new Set(\n RUN_CONFIG_PER_SEND_CUSTOM_KEYS,\n);\n\n/** Keys the thread's server config lane owns — changed only through the `config/*` commands, never per send. */\nexport const THREAD_CONFIG_CUSTOM_KEYS = [\n \"agent_catalog_asset_ids\",\n \"async_subagents\",\n \"catalog_asset_ids\",\n \"coding_worker_asset_id\",\n \"coding_workers\",\n \"collab_agent_id\",\n \"compiled_subagents\",\n \"custom_tool_configs\",\n \"declined_toolkit_ids\",\n \"drive_mounts\",\n \"enable_interpreter\",\n \"enable_persistent_fs\",\n \"enable_sandbox\",\n \"enable_skills\",\n \"enabled_toolkits\",\n \"enabled_tools\",\n \"environment\",\n \"environment_asset_id\",\n \"environment_id\",\n \"environment_name\",\n \"excluded_middleware\",\n \"excluded_tools\",\n \"extra_middleware\",\n \"include_citation_instructions\",\n \"interpreter_max_ptc_calls\",\n \"interpreter_mode\",\n \"interpreter_ptc\",\n \"interpreter_ptc_exclusive\",\n \"interpreter_runtime\",\n \"interpreter_subagents\",\n \"interpreter_timeout_seconds\",\n \"interrupt_on\",\n \"knowledge_base\",\n \"max_tokens\",\n \"mcp_server_configs\",\n \"mcp_servers\",\n \"memory\",\n \"middleware\",\n \"model\",\n \"permissions\",\n \"recursion_limit\",\n \"run_label\",\n \"sandbox_runtime\",\n \"secret_asset_ids\",\n \"session_machine\",\n \"session_vm_retention\",\n \"skill_asset_ids\",\n \"skills\",\n \"subagents\",\n \"system_prompt\",\n \"temperature\",\n \"tool_description_overrides\",\n \"workbench\",\n] as const;\n\nexport type ThreadConfigCustomKey = (typeof THREAD_CONFIG_CUSTOM_KEYS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const THREAD_CONFIG_CUSTOM_KEY_SET: ReadonlySet<string> = new Set(\n THREAD_CONFIG_CUSTOM_KEYS,\n);\n\n/** Replicated-state key of the server config lane (`{ version, custom }`). */\nexport const DEEP_AGENT_CONFIG_STATE_KEY = \"config\";\n\n/** The statewire commands that mutate the server config lane. */\nexport const DEEP_AGENT_CONFIG_COMMANDS = {\n patch: \"config/patch\",\n toolsEnable: \"config/tools/enable\",\n toolsDisable: \"config/tools/disable\",\n} as const;\n\n/** `start_channel` values the session substrate stamps as provenance; anything else clamps to \"web\". */\nexport const KNOWN_START_CHANNELS = [\n \"api\",\n \"chrome_extension\",\n \"cli\",\n \"comment_agent\",\n \"default_voice\",\n \"desktop_app\",\n \"email\",\n \"mobile_app\",\n \"office_addin\",\n \"orchestration\",\n \"programmatic\",\n \"slack\",\n \"sms\",\n \"task\",\n \"teams\",\n \"voice\",\n \"voice_memo\",\n \"web\",\n] as const;\n\nexport type KnownStartChannel = (typeof KNOWN_START_CHANNELS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const KNOWN_START_CHANNEL_SET: ReadonlySet<string> = new Set(\n KNOWN_START_CHANNELS,\n);\n\n/** `runConfig.custom.runtime` marker selecting the deep-agent runtime. */\nexport const DEEP_AGENT_RUNTIME_MARKER = \"athena_deep_agent\";\n\n/**\n * Collab-agent capability ladder (agent schema v3): per explicit\n * capability field, what an ABSENT value means and the value stamped on\n * a new agent. Resolved by agora's `capability_decoder` and the one agent\n * compiler on every run: `passthrough` — explicit only, absent means off;\n * `off` — absent means off under every `runtime` marker; `runtime` —\n * absent derives from the `runtime` marker (`athena_deep_agent` on, any\n * other or missing marker off).\n */\nexport const COLLAB_AGENT_CAPABILITIES = {\n deepAgentBuiltinsEnabled: { absent: \"runtime\", default: true },\n interpreterEnabled: { absent: \"off\", default: false },\n sandboxEnabled: { absent: \"passthrough\", default: false },\n skillsEnabled: { absent: \"runtime\", default: true },\n} as const;\n\nexport type CollabAgentCapabilityField = keyof typeof COLLAB_AGENT_CAPABILITIES;\n\nexport type CollabAgentCapabilityAbsentMode =\n (typeof COLLAB_AGENT_CAPABILITIES)[CollabAgentCapabilityField][\"absent\"];\n\n/** `source`/`type` stamped on client-tool interrupt payloads by agora. */\nexport const CLIENT_TOOL_INTERRUPT_SOURCE = \"client_tool\";\n\n/** `status` literals of the result envelope a client resumes a parked client-tool call with. */\nexport const CLIENT_TOOL_RESULT_STATUSES = [\"error\", \"success\"] as const;\n\nexport type ClientToolResultStatus =\n (typeof CLIENT_TOOL_RESULT_STATUSES)[number];\n\nexport const CLIENT_TOOL_RESULT_STATUS_SUCCESS = \"success\";\n\nexport const CLIENT_TOOL_RESULT_STATUS_ERROR = \"error\";\n\n/**\n * Result envelope a client resumes a parked client-tool call with,\n * keyed by interrupt id:\n * `{ client_tool_results: { <interrupt_id>: <envelope> } }`.\n * Agora relays the envelope to the model verbatim.\n */\nexport type ClientToolResultEnvelopeContract =\n | { status: typeof CLIENT_TOOL_RESULT_STATUS_SUCCESS; result: unknown }\n | { status: typeof CLIENT_TOOL_RESULT_STATUS_ERROR; error: string };\n\n/**\n * The deep-agent wire-contract version this client build speaks,\n * declared on every attach. The host records it for attach telemetry\n * and per-version behaviour; it has no minimum client version, so no\n * build is refused for the version it declares (the `protocol` state\n * lane's `minClientVersion` is the constant 1).\n */\nexport const DEEP_AGENT_PROTOCOL_VERSION = 1;\n\n/** Attach header carrying the client's declared contract version. */\nexport const DEEP_AGENT_PROTOCOL_VERSION_HEADER =\n \"x-athena-deep-agent-protocol-version\";\n\n/** Attach header declaring the head window a fresh client wants in its hello (host-clamped). */\nexport const DEEP_AGENT_MESSAGE_WINDOW_HEADER = \"x-athena-deep-agent-window\";\n\n/** Replicated-state key of the server-advertised version lane. */\nexport const DEEP_AGENT_PROTOCOL_STATE_KEY = \"protocol\";\n\n/** Ephemeral subprotocol carrying a client's message-window interests. */\nexport const DEEP_AGENT_INTEREST_PROTOCOL = \"athena/interest\";\n\n/** Ephemeral subprotocol carrying a client's synced context document. */\nexport const DEEP_AGENT_CONTEXT_PROTOCOL = \"athena/context\";\n\n/** The only interest namespace the host resolves (the linear transcript). */\nexport const DEEP_AGENT_MAIN_NS = \"main\";\n\n/** Window size (interest `before`) a client asks for by default. */\nexport const DEEP_AGENT_DEFAULT_MESSAGE_WINDOW = 40;\n\n/** Bounds on a window size. */\nexport const DEEP_AGENT_MIN_MESSAGE_WINDOW = 8;\n\nexport const DEEP_AGENT_MAX_MESSAGE_WINDOW = 200;\n\n/** Interests one attach may hold at once (the head plus its pages). */\nexport const DEEP_AGENT_MAX_INTERESTS = 16;\n\n/** Command returning a truncated tool output whole. */\nexport const DEEP_AGENT_HISTORY_TOOL_OUTPUT_COMMAND = \"history/tool_output\";\n\n/** Command returning one stored message whole (provenance and full tool output included). */\nexport const DEEP_AGENT_HISTORY_MESSAGE_COMMAND = \"history/message\";\n\n/** Wire key marking a tool message whose content was truncated. */\nexport const DEEP_AGENT_TRUNCATED_CONTENT_KEY = \"athena_content_truncated\";\n"],"names":[],"mappings":"AA4GO,MAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAK8D,IAAI;AAAA,EAChE;AACF;AAGO,MAAM,kCAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMuE,IAAI;AAAA,EACzE;AACF;AAGO,MAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKiE,IAAI;AAAA,EACnE;AACF;AAaO,MAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAK4D,IAAI;AAAA,EAC9D;AACF;AA2BO,MAAM,+BAA+B;AAQrC,MAAM,oCAAoC;AAE1C,MAAM,kCAAkC;AAmBxC,MAAM,8BAA8B;AAGpC,MAAM,qCACX;AAGK,MAAM,mCAAmC;AAGzC,MAAM,gCAAgC;AAGtC,MAAM,+BAA+B;AAMrC,MAAM,qBAAqB;AAG3B,MAAM,oCAAoC;AAG1C,MAAM,gCAAgC;AAEtC,MAAM,gCAAgC;AAGtC,MAAM,2BAA2B;AAGjC,MAAM,yCAAyC;AAM/C,MAAM,mCAAmC;"}
|
|
1
|
+
{"version":3,"file":"runconfig-contract.js","sources":["../../../../../../agent-runtime/src/generated/runconfig-contract.ts"],"sourcesContent":["// GENERATED FILE — DO NOT EDIT BY HAND.\n//\n// Source of truth (agora):\n// agora/agora/graphs/athena_deep_agent/run_config.py (_PARSED_CUSTOM_KEYS / _COMPANION_CUSTOM_KEYS / PER_SEND_CUSTOM_KEYS)\n// agora/agora/graphs/athena_deep_agent/thread_config.py (server config lane + config/* command names)\n// agora/agora/graphs/athena_deep_agent/session_asset.py (KNOWN_START_CHANNELS / DEEP_AGENT_RUNTIME_MARKER)\n// agora/agora/graphs/athena_deep_agent/client_tools.py (client-tool interrupt + result-envelope literals)\n// agora/agora/graphs/athena_deep_agent/protocol_version.py (wire-contract version negotiation)\n// agora/agora/graphs/athena_deep_agent/message_window.py (interest windows + history commands)\n// agora/agora/type_definitions/collab_agent.py (CAPABILITIES ladder: absent mode + new-agent default)\n//\n// Regenerate:\n// cd agora && mise exec -- infisical run --command 'uv run python scripts/export_runconfig_contract.py'\n//\n// CI verifies this file matches the Python source (agora-check runs the\n// exporter with --check), so hand edits and un-regenerated key changes fail.\n\n/** `runConfig.custom` keys parsed by agora's `parse_deep_agent_run_config`. */\nexport const RUN_CONFIG_PARSED_CUSTOM_KEYS = [\n \"agent_catalog_asset_ids\",\n \"async_subagents\",\n \"catalog_asset_ids\",\n \"coding_worker_asset_id\",\n \"coding_workers\",\n \"compiled_subagents\",\n \"declined_toolkit_ids\",\n \"drive_mounts\",\n \"enable_interpreter\",\n \"enable_persistent_fs\",\n \"enable_sandbox\",\n \"enable_skills\",\n \"enabled_tools\",\n \"environment\",\n \"environment_id\",\n \"environment_name\",\n \"excluded_middleware\",\n \"excluded_tools\",\n \"extra_middleware\",\n \"include_citation_instructions\",\n \"interpreter_max_ptc_calls\",\n \"interpreter_mode\",\n \"interpreter_ptc\",\n \"interpreter_ptc_exclusive\",\n \"interpreter_runtime\",\n \"interpreter_subagents\",\n \"interpreter_timeout_seconds\",\n \"interrupt_on\",\n \"knowledge_base\",\n \"mcp_server_configs\",\n \"mcp_servers\",\n \"memory\",\n \"outbound_approval_allowlist\",\n \"permissions\",\n \"project_id\",\n \"recursion_limit\",\n \"run_label\",\n \"sandbox_runtime\",\n \"secret_asset_ids\",\n \"session_machine\",\n \"session_vm_retention\",\n \"skill_asset_ids\",\n \"skills\",\n \"subagents\",\n \"system_prompt\",\n \"tool_description_overrides\",\n \"voice_update_handle\",\n \"workbench\",\n] as const;\n\n/** `runConfig.custom` keys consumed by the surrounding deep-agent request machinery rather than the capability parser. */\nexport const RUN_CONFIG_COMPANION_CUSTOM_KEYS = [\n \"agent\",\n \"allowed_tab_ids\",\n \"app_id\",\n \"channel\",\n \"client_tools\",\n \"collab_agent_id\",\n \"collab_channel_id\",\n \"custom_tool_configs\",\n \"deterministic\",\n \"device_id\",\n \"dry_run\",\n \"enabled_toolkits\",\n \"frontend_available\",\n \"github_identity\",\n \"max_tokens\",\n \"middleware\",\n \"model\",\n \"muses_enabled\",\n \"muses_recall_enabled\",\n \"office_context\",\n \"panel_config\",\n \"run_budget\",\n \"runtime\",\n \"session_id\",\n \"session_origin_kind\",\n \"session_tab_id\",\n \"skip_title_generation\",\n \"source_aop_id\",\n \"start_channel\",\n \"structured_output\",\n \"temperature\",\n \"tool_limit_override\",\n \"trigger_type\",\n \"workspace_id\",\n] as const;\n\n/** Every `runConfig.custom` key some deep-agent request consumer reads. A key outside this set is invisible to the run and trips agora's unknown-key telemetry. */\nexport const RUN_CONFIG_CUSTOM_KEYS = [\n \"agent\",\n \"agent_catalog_asset_ids\",\n \"allowed_tab_ids\",\n \"app_id\",\n \"async_subagents\",\n \"catalog_asset_ids\",\n \"channel\",\n \"client_tools\",\n \"coding_worker_asset_id\",\n \"coding_workers\",\n \"collab_agent_id\",\n \"collab_channel_id\",\n \"compiled_subagents\",\n \"custom_tool_configs\",\n \"declined_toolkit_ids\",\n \"deterministic\",\n \"device_id\",\n \"drive_mounts\",\n \"dry_run\",\n \"enable_interpreter\",\n \"enable_persistent_fs\",\n \"enable_sandbox\",\n \"enable_skills\",\n \"enabled_toolkits\",\n \"enabled_tools\",\n \"environment\",\n \"environment_id\",\n \"environment_name\",\n \"excluded_middleware\",\n \"excluded_tools\",\n \"extra_middleware\",\n \"frontend_available\",\n \"github_identity\",\n \"include_citation_instructions\",\n \"interpreter_max_ptc_calls\",\n \"interpreter_mode\",\n \"interpreter_ptc\",\n \"interpreter_ptc_exclusive\",\n \"interpreter_runtime\",\n \"interpreter_subagents\",\n \"interpreter_timeout_seconds\",\n \"interrupt_on\",\n \"knowledge_base\",\n \"max_tokens\",\n \"mcp_server_configs\",\n \"mcp_servers\",\n \"memory\",\n \"middleware\",\n \"model\",\n \"muses_enabled\",\n \"muses_recall_enabled\",\n \"office_context\",\n \"outbound_approval_allowlist\",\n \"panel_config\",\n \"permissions\",\n \"project_id\",\n \"recursion_limit\",\n \"run_budget\",\n \"run_label\",\n \"runtime\",\n \"sandbox_runtime\",\n \"secret_asset_ids\",\n \"session_id\",\n \"session_machine\",\n \"session_origin_kind\",\n \"session_tab_id\",\n \"session_vm_retention\",\n \"skill_asset_ids\",\n \"skills\",\n \"skip_title_generation\",\n \"source_aop_id\",\n \"start_channel\",\n \"structured_output\",\n \"subagents\",\n \"system_prompt\",\n \"temperature\",\n \"tool_description_overrides\",\n \"tool_limit_override\",\n \"trigger_type\",\n \"voice_update_handle\",\n \"workbench\",\n \"workspace_id\",\n] as const;\n\nexport type RunConfigCustomKey = (typeof RUN_CONFIG_CUSTOM_KEYS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const RUN_CONFIG_CUSTOM_KEY_SET: ReadonlySet<string> = new Set(\n RUN_CONFIG_CUSTOM_KEYS,\n);\n\n/** `runConfig.custom` keys a client still carries per send on a thread with server config; every other key is dropped at dispatch. */\nexport const RUN_CONFIG_PER_SEND_CUSTOM_KEYS = [\n \"agent\",\n \"allowed_tab_ids\",\n \"app_id\",\n \"channel\",\n \"client_tools\",\n \"collab_channel_id\",\n \"deterministic\",\n \"device_id\",\n \"dry_run\",\n \"frontend_available\",\n \"github_identity\",\n \"muses_enabled\",\n \"muses_recall_enabled\",\n \"office_context\",\n \"project_id\",\n \"run_budget\",\n \"runtime\",\n \"session_id\",\n \"session_origin_kind\",\n \"session_tab_id\",\n \"skip_title_generation\",\n \"source_aop_id\",\n \"start_channel\",\n \"structured_output\",\n \"tool_limit_override\",\n \"trigger_type\",\n \"voice_update_handle\",\n \"workspace_id\",\n] as const;\n\nexport type RunConfigPerSendCustomKey =\n (typeof RUN_CONFIG_PER_SEND_CUSTOM_KEYS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const RUN_CONFIG_PER_SEND_CUSTOM_KEY_SET: ReadonlySet<string> = new Set(\n RUN_CONFIG_PER_SEND_CUSTOM_KEYS,\n);\n\n/** Keys the thread's server config lane owns — changed only through the `config/*` commands, never per send. */\nexport const THREAD_CONFIG_CUSTOM_KEYS = [\n \"agent_catalog_asset_ids\",\n \"async_subagents\",\n \"catalog_asset_ids\",\n \"coding_worker_asset_id\",\n \"coding_workers\",\n \"collab_agent_id\",\n \"compiled_subagents\",\n \"custom_tool_configs\",\n \"declined_toolkit_ids\",\n \"drive_mounts\",\n \"enable_interpreter\",\n \"enable_persistent_fs\",\n \"enable_sandbox\",\n \"enable_skills\",\n \"enabled_toolkits\",\n \"enabled_tools\",\n \"environment\",\n \"environment_id\",\n \"environment_name\",\n \"excluded_middleware\",\n \"excluded_tools\",\n \"extra_middleware\",\n \"include_citation_instructions\",\n \"interpreter_max_ptc_calls\",\n \"interpreter_mode\",\n \"interpreter_ptc\",\n \"interpreter_ptc_exclusive\",\n \"interpreter_runtime\",\n \"interpreter_subagents\",\n \"interpreter_timeout_seconds\",\n \"interrupt_on\",\n \"knowledge_base\",\n \"max_tokens\",\n \"mcp_server_configs\",\n \"mcp_servers\",\n \"memory\",\n \"middleware\",\n \"model\",\n \"outbound_approval_allowlist\",\n \"permissions\",\n \"recursion_limit\",\n \"run_label\",\n \"sandbox_runtime\",\n \"secret_asset_ids\",\n \"session_machine\",\n \"session_vm_retention\",\n \"skill_asset_ids\",\n \"skills\",\n \"subagents\",\n \"system_prompt\",\n \"temperature\",\n \"tool_description_overrides\",\n \"workbench\",\n] as const;\n\nexport type ThreadConfigCustomKey = (typeof THREAD_CONFIG_CUSTOM_KEYS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const THREAD_CONFIG_CUSTOM_KEY_SET: ReadonlySet<string> = new Set(\n THREAD_CONFIG_CUSTOM_KEYS,\n);\n\n/** Replicated-state key of the server config lane (`{ version, custom }`). */\nexport const DEEP_AGENT_CONFIG_STATE_KEY = \"config\";\n\n/** The statewire commands that mutate the server config lane. */\nexport const DEEP_AGENT_CONFIG_COMMANDS = {\n patch: \"config/patch\",\n toolsEnable: \"config/tools/enable\",\n toolsDisable: \"config/tools/disable\",\n} as const;\n\n/** `start_channel` values the session substrate stamps as provenance; anything else clamps to \"web\". */\nexport const KNOWN_START_CHANNELS = [\n \"api\",\n \"chrome_extension\",\n \"cli\",\n \"comment_agent\",\n \"default_voice\",\n \"desktop_app\",\n \"email\",\n \"mobile_app\",\n \"office_addin\",\n \"orchestration\",\n \"programmatic\",\n \"slack\",\n \"sms\",\n \"task\",\n \"teams\",\n \"voice\",\n \"voice_memo\",\n \"web\",\n] as const;\n\nexport type KnownStartChannel = (typeof KNOWN_START_CHANNELS)[number];\n\n/** Fast membership checks for builder/test assertions. */\nexport const KNOWN_START_CHANNEL_SET: ReadonlySet<string> = new Set(\n KNOWN_START_CHANNELS,\n);\n\n/** `runConfig.custom.runtime` marker selecting the deep-agent runtime. */\nexport const DEEP_AGENT_RUNTIME_MARKER = \"athena_deep_agent\";\n\n/**\n * Collab-agent capability ladder (agent schema v3): per explicit\n * capability field, what an ABSENT value means and the value stamped on\n * a new agent. Resolved by agora's `capability_decoder` and the one agent\n * compiler on every run: `passthrough` — explicit only, absent means off;\n * `off` — absent means off under every `runtime` marker; `runtime` —\n * absent derives from the `runtime` marker (`athena_deep_agent` on, any\n * other or missing marker off).\n */\nexport const COLLAB_AGENT_CAPABILITIES = {\n deepAgentBuiltinsEnabled: { absent: \"runtime\", default: true },\n interpreterEnabled: { absent: \"off\", default: false },\n sandboxEnabled: { absent: \"passthrough\", default: false },\n skillsEnabled: { absent: \"runtime\", default: true },\n} as const;\n\nexport type CollabAgentCapabilityField = keyof typeof COLLAB_AGENT_CAPABILITIES;\n\nexport type CollabAgentCapabilityAbsentMode =\n (typeof COLLAB_AGENT_CAPABILITIES)[CollabAgentCapabilityField][\"absent\"];\n\n/** `source`/`type` stamped on client-tool interrupt payloads by agora. */\nexport const CLIENT_TOOL_INTERRUPT_SOURCE = \"client_tool\";\n\n/** `status` literals of the result envelope a client resumes a parked client-tool call with. */\nexport const CLIENT_TOOL_RESULT_STATUSES = [\"error\", \"success\"] as const;\n\nexport type ClientToolResultStatus =\n (typeof CLIENT_TOOL_RESULT_STATUSES)[number];\n\nexport const CLIENT_TOOL_RESULT_STATUS_SUCCESS = \"success\";\n\nexport const CLIENT_TOOL_RESULT_STATUS_ERROR = \"error\";\n\n/**\n * Result envelope a client resumes a parked client-tool call with,\n * keyed by interrupt id:\n * `{ client_tool_results: { <interrupt_id>: <envelope> } }`.\n * Agora relays the envelope to the model verbatim.\n */\nexport type ClientToolResultEnvelopeContract =\n | { status: typeof CLIENT_TOOL_RESULT_STATUS_SUCCESS; result: unknown }\n | { status: typeof CLIENT_TOOL_RESULT_STATUS_ERROR; error: string };\n\n/**\n * The deep-agent wire-contract version this client build speaks,\n * declared on every attach. The host records it for attach telemetry\n * and per-version behaviour; it has no minimum client version, so no\n * build is refused for the version it declares (the `protocol` state\n * lane's `minClientVersion` is the constant 1).\n */\nexport const DEEP_AGENT_PROTOCOL_VERSION = 1;\n\n/** Attach header carrying the client's declared contract version. */\nexport const DEEP_AGENT_PROTOCOL_VERSION_HEADER =\n \"x-athena-deep-agent-protocol-version\";\n\n/** Attach header declaring the head window a fresh client wants in its hello (host-clamped). */\nexport const DEEP_AGENT_MESSAGE_WINDOW_HEADER = \"x-athena-deep-agent-window\";\n\n/** Replicated-state key of the server-advertised version lane. */\nexport const DEEP_AGENT_PROTOCOL_STATE_KEY = \"protocol\";\n\n/** Ephemeral subprotocol carrying a client's message-window interests. */\nexport const DEEP_AGENT_INTEREST_PROTOCOL = \"athena/interest\";\n\n/** Ephemeral subprotocol carrying a client's synced context document. */\nexport const DEEP_AGENT_CONTEXT_PROTOCOL = \"athena/context\";\n\n/** The only interest namespace the host resolves (the linear transcript). */\nexport const DEEP_AGENT_MAIN_NS = \"main\";\n\n/** Window size (interest `before`) a client asks for by default. */\nexport const DEEP_AGENT_DEFAULT_MESSAGE_WINDOW = 40;\n\n/** Bounds on a window size. */\nexport const DEEP_AGENT_MIN_MESSAGE_WINDOW = 8;\n\nexport const DEEP_AGENT_MAX_MESSAGE_WINDOW = 200;\n\n/** Interests one attach may hold at once (the head plus its pages). */\nexport const DEEP_AGENT_MAX_INTERESTS = 16;\n\n/** Command returning a truncated tool output whole. */\nexport const DEEP_AGENT_HISTORY_TOOL_OUTPUT_COMMAND = \"history/tool_output\";\n\n/** Command returning one stored message whole (provenance and full tool output included). */\nexport const DEEP_AGENT_HISTORY_MESSAGE_COMMAND = \"history/message\";\n\n/** Wire key marking a tool message whose content was truncated. */\nexport const DEEP_AGENT_TRUNCATED_CONTENT_KEY = \"athena_content_truncated\";\n"],"names":[],"mappings":"AA4GO,MAAM,yBAAyB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAK8D,IAAI;AAAA,EAChE;AACF;AAGO,MAAM,kCAAkC;AAAA,EAC7C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMuE,IAAI;AAAA,EACzE;AACF;AAGO,MAAM,4BAA4B;AAAA,EACvC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAKiE,IAAI;AAAA,EACnE;AACF;AAaO,MAAM,uBAAuB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAK4D,IAAI;AAAA,EAC9D;AACF;AA2BO,MAAM,+BAA+B;AAQrC,MAAM,oCAAoC;AAE1C,MAAM,kCAAkC;AAmBxC,MAAM,8BAA8B;AAGpC,MAAM,qCACX;AAGK,MAAM,mCAAmC;AAGzC,MAAM,gCAAgC;AAGtC,MAAM,+BAA+B;AAMrC,MAAM,qBAAqB;AAG3B,MAAM,oCAAoC;AAG1C,MAAM,gCAAgC;AAEtC,MAAM,gCAAgC;AAGtC,MAAM,2BAA2B;AAGjC,MAAM,yCAAyC;AAM/C,MAAM,mCAAmC;"}
|
|
@@ -127,6 +127,7 @@ function useConversationList(options) {
|
|
|
127
127
|
hasResolvedFirstPage: firstPage.data !== void 0,
|
|
128
128
|
hasNextPage: hasLoadedHistory ? history.hasNextPage ?? false : ((_c = firstPage.data) == null ? void 0 : _c.hasMore) ?? false,
|
|
129
129
|
isFetchingNextPage: history.isFetchingNextPage || !hasLoadedHistory && history.isFetching,
|
|
130
|
+
isFetchNextPageError: history.isError,
|
|
130
131
|
fetchNextPage,
|
|
131
132
|
refresh,
|
|
132
133
|
invalidate,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-conversation-list.cjs","sources":["../../../../../agent-runtime/src/use-conversation-list.ts"],"sourcesContent":["import {\n type InfiniteData,\n useInfiniteQuery,\n useQuery,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { useCallback, useMemo, useRef } from 'react';\nimport {\n CONVERSATION_LIST_DEFAULT_SCOPE_KEY,\n type ConversationListFetcher,\n type ConversationListFilter,\n type ConversationListPage,\n type ConversationSummary,\n conversationListFilterKey,\n conversationListQueryKeys,\n invalidateConversationListCaches,\n mergeConversationPages,\n normalizeConversationListFilter,\n patchConversationsInPage,\n prependConversationToPage,\n removeConversationFromPage,\n} from './conversation-list';\n\nconst DEFAULT_PAGE_SIZE = 20;\nconst DEFAULT_STALE_TIME_MS = 30_000;\nconst DEFAULT_GC_TIME_MS = 10 * 60 * 1000;\n\nexport interface UseConversationListOptions {\n /**\n * Transport adapter for one page (GraphQL `listConversations`, the REST\n * thread list, …). Captured in a ref — identity changes do not re-key the\n * cache, so pair a changing fetcher with a changing `scopeKey`.\n */\n fetchPage: ConversationListFetcher;\n filter?: ConversationListFilter;\n pageSize?: number;\n /**\n * Cache identity beyond the filter. MUST include everything that changes\n * whose list this is — principal/user id, backend base URL — so a\n * credential swap can never serve another identity's rows from the cache.\n */\n scopeKey?: string;\n enabled?: boolean;\n staleTime?: number;\n gcTime?: number;\n refetchOnMount?: boolean | 'always';\n refetchOnWindowFocus?: boolean;\n /**\n * Newest-page freshness is push-based by default (the conversation-index\n * statewire invalidates these caches), so no timer runs unless asked.\n */\n refetchInterval?: number | false;\n retry?: boolean | number | ((failureCount: number, error: Error) => boolean);\n}\n\nexport interface ConversationListController {\n /** Merged newest-first rows: live first page + retained history pages. */\n conversations: ConversationSummary[];\n /** Advisory total from the live first page, when the transport counts. */\n totalCount: number | null;\n isLoading: boolean;\n isFetching: boolean;\n /** True once the live first page has resolved at least once. */\n hasResolvedFirstPage: boolean;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n fetchNextPage: () => Promise<unknown>;\n /** Refetch the live first page (history pages stay frozen). */\n refresh: () => Promise<unknown>;\n /** Invalidate every conversation-list cache in this scope (all filters). */\n invalidate: () => Promise<void>;\n /** Optimistically show a new conversation at the top of THIS filter view. */\n prependConversation: (item: ConversationSummary) => void;\n /** Optimistically drop a conversation from THIS filter view. */\n removeConversation: (threadId: string) => void;\n /** Optimistically patch a conversation's row in THIS filter view. */\n patchConversation: (threadId: string, patch: Partial<ConversationSummary>) => void;\n}\n\n/**\n * The shared headless conversation-list pager (chat-stack unification —\n * thread-list-contract-convergence).\n *\n * Implements, once, the two-tier TanStack Query pattern Olympus and mobile\n * each hand-rolled:\n *\n * - a LIVE first-page query — the only observer that refetches on\n * invalidation/focus, so push-driven freshness costs one page, and\n * - a permanently-disabled infinite \"history\" query whose pages are fetched\n * only by explicit `fetchNextPage()` calls and retained without replay\n * (invalidation/polling never refetches every loaded page).\n *\n * Rows merge newest-first with the live page winning duplicate threads.\n */\nexport function useConversationList(options: UseConversationListOptions): ConversationListController {\n const {\n filter,\n pageSize = DEFAULT_PAGE_SIZE,\n scopeKey = CONVERSATION_LIST_DEFAULT_SCOPE_KEY,\n enabled,\n staleTime = DEFAULT_STALE_TIME_MS,\n gcTime = DEFAULT_GC_TIME_MS,\n refetchOnMount,\n refetchOnWindowFocus,\n refetchInterval = false,\n retry,\n } = options;\n const queryClient = useQueryClient();\n\n const fetchPageRef = useRef(options.fetchPage);\n fetchPageRef.current = options.fetchPage;\n\n // The normalized filter is both the cache identity (via the key) and what\n // queryFn closures fetch, so a cache entry holds exactly what it claims —\n // fresh-but-equal filter objects from the caller never re-key or refetch.\n // (Plain per-render values: only the serialized key participates in\n // identity, so object freshness here is irrelevant.)\n const normalizedFilter = normalizeConversationListFilter(filter ?? {});\n const filterKey = conversationListFilterKey(normalizedFilter);\n\n const firstPageKey = useMemo(\n () => conversationListQueryKeys.firstPage(scopeKey, filterKey, pageSize),\n [scopeKey, filterKey, pageSize]\n );\n const historyKey = useMemo(\n () => conversationListQueryKeys.history(scopeKey, filterKey, pageSize),\n [scopeKey, filterKey, pageSize]\n );\n\n // React Query merges per-query options OVER the client's defaultOptions with\n // Object.assign, which copies explicitly-`undefined` keys — so passing\n // `refetchOnWindowFocus: undefined` CLOBBERS a consumer's\n // `refetchOnWindowFocus: false` default and silently re-enables focus\n // refetching. Options the caller did not set must therefore be omitted, not\n // forwarded as undefined, so they fall through to the consuming app's client.\n const passthrough = {\n ...(enabled !== undefined ? { enabled } : {}),\n ...(refetchOnMount !== undefined ? { refetchOnMount } : {}),\n ...(refetchOnWindowFocus !== undefined ? { refetchOnWindowFocus } : {}),\n ...(retry !== undefined ? { retry } : {}),\n };\n\n const firstPage = useQuery({\n queryKey: firstPageKey,\n queryFn: ({ signal }) =>\n fetchPageRef.current({ limit: pageSize, offset: 0, filter: normalizedFilter, signal }),\n staleTime,\n gcTime,\n refetchInterval,\n ...passthrough,\n });\n\n const history = useInfiniteQuery({\n queryKey: historyKey,\n initialPageParam: pageSize,\n gcTime,\n queryFn: ({ pageParam, signal }) =>\n fetchPageRef.current({ limit: pageSize, offset: pageParam, filter: normalizedFilter, signal }),\n getNextPageParam: (lastPage, _allPages, lastOffset) =>\n lastPage.hasMore ? lastOffset + pageSize : undefined,\n ...passthrough,\n // fetchNextPage/refetch still perform explicit fetches for disabled\n // queries. Keeping this observer disabled prevents focus, invalidation,\n // and polling from replaying every retained historical page. This must\n // win over `passthrough.enabled`, so it is spread last.\n enabled: false,\n });\n\n const historyPages = history.data?.pages;\n const hasLoadedHistory = (historyPages?.length ?? 0) > 0;\n\n const conversations = useMemo(\n () =>\n mergeConversationPages([\n ...(firstPage.data ? [firstPage.data] : []),\n ...(historyPages ?? []),\n ]),\n [firstPage.data, historyPages]\n );\n\n const fetchNextHistoryPage = history.fetchNextPage;\n const refetchHistoryFirstPage = history.refetch;\n const fetchNextPage = useCallback(\n () => (hasLoadedHistory ? fetchNextHistoryPage() : refetchHistoryFirstPage()),\n [hasLoadedHistory, fetchNextHistoryPage, refetchHistoryFirstPage]\n );\n\n const refresh = useCallback(() => firstPage.refetch(), [firstPage.refetch]);\n\n const invalidate = useCallback(\n () => invalidateConversationListCaches(queryClient, { scopeKey }),\n [queryClient, scopeKey]\n );\n\n const prependConversation = useCallback(\n (item: ConversationSummary) => {\n queryClient.setQueryData<ConversationListPage>(firstPageKey, (page) =>\n page ? prependConversationToPage(page, item) : page\n );\n },\n [queryClient, firstPageKey]\n );\n\n const removeConversation = useCallback(\n (threadId: string) => {\n queryClient.setQueryData<ConversationListPage>(firstPageKey, (page) =>\n page ? removeConversationFromPage(page, threadId) : page\n );\n queryClient.setQueryData<InfiniteData<ConversationListPage, number>>(historyKey, (data) =>\n data\n ? { ...data, pages: data.pages.map((page) => removeConversationFromPage(page, threadId)) }\n : data\n );\n },\n [queryClient, firstPageKey, historyKey]\n );\n\n const patchConversation = useCallback(\n (threadId: string, patch: Partial<ConversationSummary>) => {\n const match = (item: ConversationSummary) => item.threadId === threadId;\n queryClient.setQueryData<ConversationListPage>(firstPageKey, (page) =>\n page ? patchConversationsInPage(page, match, patch) : page\n );\n queryClient.setQueryData<InfiniteData<ConversationListPage, number>>(historyKey, (data) =>\n data\n ? {\n ...data,\n pages: data.pages.map((page) => patchConversationsInPage(page, match, patch)),\n }\n : data\n );\n },\n [queryClient, firstPageKey, historyKey]\n );\n\n return {\n conversations,\n totalCount: firstPage.data?.totalCount ?? null,\n isLoading: firstPage.isLoading,\n isFetching: firstPage.isFetching || history.isFetching,\n hasResolvedFirstPage: firstPage.data !== undefined,\n hasNextPage: hasLoadedHistory\n ? (history.hasNextPage ?? false)\n : (firstPage.data?.hasMore ?? false),\n isFetchingNextPage: history.isFetchingNextPage || (!hasLoadedHistory && history.isFetching),\n fetchNextPage,\n refresh,\n invalidate,\n prependConversation,\n removeConversation,\n patchConversation,\n };\n}\n"],"names":["CONVERSATION_LIST_DEFAULT_SCOPE_KEY","useQueryClient","useRef","normalizeConversationListFilter","conversationListFilterKey","useMemo","conversationListQueryKeys","useQuery","useInfiniteQuery","mergeConversationPages","useCallback","invalidateConversationListCaches","prependConversationToPage","removeConversationFromPage","patchConversationsInPage"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-conversation-list.cjs","sources":["../../../../../agent-runtime/src/use-conversation-list.ts"],"sourcesContent":["import {\n type InfiniteData,\n useInfiniteQuery,\n useQuery,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { useCallback, useMemo, useRef } from 'react';\nimport {\n CONVERSATION_LIST_DEFAULT_SCOPE_KEY,\n type ConversationListFetcher,\n type ConversationListFilter,\n type ConversationListPage,\n type ConversationSummary,\n conversationListFilterKey,\n conversationListQueryKeys,\n invalidateConversationListCaches,\n mergeConversationPages,\n normalizeConversationListFilter,\n patchConversationsInPage,\n prependConversationToPage,\n removeConversationFromPage,\n} from './conversation-list';\n\nconst DEFAULT_PAGE_SIZE = 20;\nconst DEFAULT_STALE_TIME_MS = 30_000;\nconst DEFAULT_GC_TIME_MS = 10 * 60 * 1000;\n\nexport interface UseConversationListOptions {\n /**\n * Transport adapter for one page (GraphQL `listConversations`, the REST\n * thread list, …). Captured in a ref — identity changes do not re-key the\n * cache, so pair a changing fetcher with a changing `scopeKey`.\n */\n fetchPage: ConversationListFetcher;\n filter?: ConversationListFilter;\n pageSize?: number;\n /**\n * Cache identity beyond the filter. MUST include everything that changes\n * whose list this is — principal/user id, backend base URL — so a\n * credential swap can never serve another identity's rows from the cache.\n */\n scopeKey?: string;\n enabled?: boolean;\n staleTime?: number;\n gcTime?: number;\n refetchOnMount?: boolean | 'always';\n refetchOnWindowFocus?: boolean;\n /**\n * Newest-page freshness is push-based by default (the conversation-index\n * statewire invalidates these caches), so no timer runs unless asked.\n */\n refetchInterval?: number | false;\n retry?: boolean | number | ((failureCount: number, error: Error) => boolean);\n}\n\nexport interface ConversationListController {\n /** Merged newest-first rows: live first page + retained history pages. */\n conversations: ConversationSummary[];\n /** Advisory total from the live first page, when the transport counts. */\n totalCount: number | null;\n isLoading: boolean;\n isFetching: boolean;\n /** True once the live first page has resolved at least once. */\n hasResolvedFirstPage: boolean;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n /** True while the last next-page request failed (cleared by a successful one). */\n isFetchNextPageError: boolean;\n fetchNextPage: () => Promise<unknown>;\n /** Refetch the live first page (history pages stay frozen). */\n refresh: () => Promise<unknown>;\n /** Invalidate every conversation-list cache in this scope (all filters). */\n invalidate: () => Promise<void>;\n /** Optimistically show a new conversation at the top of THIS filter view. */\n prependConversation: (item: ConversationSummary) => void;\n /** Optimistically drop a conversation from THIS filter view. */\n removeConversation: (threadId: string) => void;\n /** Optimistically patch a conversation's row in THIS filter view. */\n patchConversation: (threadId: string, patch: Partial<ConversationSummary>) => void;\n}\n\n/**\n * The shared headless conversation-list pager (chat-stack unification —\n * thread-list-contract-convergence).\n *\n * Implements, once, the two-tier TanStack Query pattern Olympus and mobile\n * each hand-rolled:\n *\n * - a LIVE first-page query — the only observer that refetches on\n * invalidation/focus, so push-driven freshness costs one page, and\n * - a permanently-disabled infinite \"history\" query whose pages are fetched\n * only by explicit `fetchNextPage()` calls and retained without replay\n * (invalidation/polling never refetches every loaded page).\n *\n * Rows merge newest-first with the live page winning duplicate threads.\n */\nexport function useConversationList(options: UseConversationListOptions): ConversationListController {\n const {\n filter,\n pageSize = DEFAULT_PAGE_SIZE,\n scopeKey = CONVERSATION_LIST_DEFAULT_SCOPE_KEY,\n enabled,\n staleTime = DEFAULT_STALE_TIME_MS,\n gcTime = DEFAULT_GC_TIME_MS,\n refetchOnMount,\n refetchOnWindowFocus,\n refetchInterval = false,\n retry,\n } = options;\n const queryClient = useQueryClient();\n\n const fetchPageRef = useRef(options.fetchPage);\n fetchPageRef.current = options.fetchPage;\n\n // The normalized filter is both the cache identity (via the key) and what\n // queryFn closures fetch, so a cache entry holds exactly what it claims —\n // fresh-but-equal filter objects from the caller never re-key or refetch.\n // (Plain per-render values: only the serialized key participates in\n // identity, so object freshness here is irrelevant.)\n const normalizedFilter = normalizeConversationListFilter(filter ?? {});\n const filterKey = conversationListFilterKey(normalizedFilter);\n\n const firstPageKey = useMemo(\n () => conversationListQueryKeys.firstPage(scopeKey, filterKey, pageSize),\n [scopeKey, filterKey, pageSize]\n );\n const historyKey = useMemo(\n () => conversationListQueryKeys.history(scopeKey, filterKey, pageSize),\n [scopeKey, filterKey, pageSize]\n );\n\n // React Query merges per-query options OVER the client's defaultOptions with\n // Object.assign, which copies explicitly-`undefined` keys — so passing\n // `refetchOnWindowFocus: undefined` CLOBBERS a consumer's\n // `refetchOnWindowFocus: false` default and silently re-enables focus\n // refetching. Options the caller did not set must therefore be omitted, not\n // forwarded as undefined, so they fall through to the consuming app's client.\n const passthrough = {\n ...(enabled !== undefined ? { enabled } : {}),\n ...(refetchOnMount !== undefined ? { refetchOnMount } : {}),\n ...(refetchOnWindowFocus !== undefined ? { refetchOnWindowFocus } : {}),\n ...(retry !== undefined ? { retry } : {}),\n };\n\n const firstPage = useQuery({\n queryKey: firstPageKey,\n queryFn: ({ signal }) =>\n fetchPageRef.current({ limit: pageSize, offset: 0, filter: normalizedFilter, signal }),\n staleTime,\n gcTime,\n refetchInterval,\n ...passthrough,\n });\n\n const history = useInfiniteQuery({\n queryKey: historyKey,\n initialPageParam: pageSize,\n gcTime,\n queryFn: ({ pageParam, signal }) =>\n fetchPageRef.current({ limit: pageSize, offset: pageParam, filter: normalizedFilter, signal }),\n getNextPageParam: (lastPage, _allPages, lastOffset) =>\n lastPage.hasMore ? lastOffset + pageSize : undefined,\n ...passthrough,\n // fetchNextPage/refetch still perform explicit fetches for disabled\n // queries. Keeping this observer disabled prevents focus, invalidation,\n // and polling from replaying every retained historical page. This must\n // win over `passthrough.enabled`, so it is spread last.\n enabled: false,\n });\n\n const historyPages = history.data?.pages;\n const hasLoadedHistory = (historyPages?.length ?? 0) > 0;\n\n const conversations = useMemo(\n () =>\n mergeConversationPages([\n ...(firstPage.data ? [firstPage.data] : []),\n ...(historyPages ?? []),\n ]),\n [firstPage.data, historyPages]\n );\n\n const fetchNextHistoryPage = history.fetchNextPage;\n const refetchHistoryFirstPage = history.refetch;\n const fetchNextPage = useCallback(\n () => (hasLoadedHistory ? fetchNextHistoryPage() : refetchHistoryFirstPage()),\n [hasLoadedHistory, fetchNextHistoryPage, refetchHistoryFirstPage]\n );\n\n const refresh = useCallback(() => firstPage.refetch(), [firstPage.refetch]);\n\n const invalidate = useCallback(\n () => invalidateConversationListCaches(queryClient, { scopeKey }),\n [queryClient, scopeKey]\n );\n\n const prependConversation = useCallback(\n (item: ConversationSummary) => {\n queryClient.setQueryData<ConversationListPage>(firstPageKey, (page) =>\n page ? prependConversationToPage(page, item) : page\n );\n },\n [queryClient, firstPageKey]\n );\n\n const removeConversation = useCallback(\n (threadId: string) => {\n queryClient.setQueryData<ConversationListPage>(firstPageKey, (page) =>\n page ? removeConversationFromPage(page, threadId) : page\n );\n queryClient.setQueryData<InfiniteData<ConversationListPage, number>>(historyKey, (data) =>\n data\n ? { ...data, pages: data.pages.map((page) => removeConversationFromPage(page, threadId)) }\n : data\n );\n },\n [queryClient, firstPageKey, historyKey]\n );\n\n const patchConversation = useCallback(\n (threadId: string, patch: Partial<ConversationSummary>) => {\n const match = (item: ConversationSummary) => item.threadId === threadId;\n queryClient.setQueryData<ConversationListPage>(firstPageKey, (page) =>\n page ? patchConversationsInPage(page, match, patch) : page\n );\n queryClient.setQueryData<InfiniteData<ConversationListPage, number>>(historyKey, (data) =>\n data\n ? {\n ...data,\n pages: data.pages.map((page) => patchConversationsInPage(page, match, patch)),\n }\n : data\n );\n },\n [queryClient, firstPageKey, historyKey]\n );\n\n return {\n conversations,\n totalCount: firstPage.data?.totalCount ?? null,\n isLoading: firstPage.isLoading,\n isFetching: firstPage.isFetching || history.isFetching,\n hasResolvedFirstPage: firstPage.data !== undefined,\n hasNextPage: hasLoadedHistory\n ? (history.hasNextPage ?? false)\n : (firstPage.data?.hasMore ?? false),\n isFetchingNextPage: history.isFetchingNextPage || (!hasLoadedHistory && history.isFetching),\n isFetchNextPageError: history.isError,\n fetchNextPage,\n refresh,\n invalidate,\n prependConversation,\n removeConversation,\n patchConversation,\n };\n}\n"],"names":["CONVERSATION_LIST_DEFAULT_SCOPE_KEY","useQueryClient","useRef","normalizeConversationListFilter","conversationListFilterKey","useMemo","conversationListQueryKeys","useQuery","useInfiniteQuery","mergeConversationPages","useCallback","invalidateConversationListCaches","prependConversationToPage","removeConversationFromPage","patchConversationsInPage"],"mappings":"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"}
|
|
@@ -125,6 +125,7 @@ function useConversationList(options) {
|
|
|
125
125
|
hasResolvedFirstPage: firstPage.data !== void 0,
|
|
126
126
|
hasNextPage: hasLoadedHistory ? history.hasNextPage ?? false : ((_c = firstPage.data) == null ? void 0 : _c.hasMore) ?? false,
|
|
127
127
|
isFetchingNextPage: history.isFetchingNextPage || !hasLoadedHistory && history.isFetching,
|
|
128
|
+
isFetchNextPageError: history.isError,
|
|
128
129
|
fetchNextPage,
|
|
129
130
|
refresh,
|
|
130
131
|
invalidate,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-conversation-list.js","sources":["../../../../../agent-runtime/src/use-conversation-list.ts"],"sourcesContent":["import {\n type InfiniteData,\n useInfiniteQuery,\n useQuery,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { useCallback, useMemo, useRef } from 'react';\nimport {\n CONVERSATION_LIST_DEFAULT_SCOPE_KEY,\n type ConversationListFetcher,\n type ConversationListFilter,\n type ConversationListPage,\n type ConversationSummary,\n conversationListFilterKey,\n conversationListQueryKeys,\n invalidateConversationListCaches,\n mergeConversationPages,\n normalizeConversationListFilter,\n patchConversationsInPage,\n prependConversationToPage,\n removeConversationFromPage,\n} from './conversation-list';\n\nconst DEFAULT_PAGE_SIZE = 20;\nconst DEFAULT_STALE_TIME_MS = 30_000;\nconst DEFAULT_GC_TIME_MS = 10 * 60 * 1000;\n\nexport interface UseConversationListOptions {\n /**\n * Transport adapter for one page (GraphQL `listConversations`, the REST\n * thread list, …). Captured in a ref — identity changes do not re-key the\n * cache, so pair a changing fetcher with a changing `scopeKey`.\n */\n fetchPage: ConversationListFetcher;\n filter?: ConversationListFilter;\n pageSize?: number;\n /**\n * Cache identity beyond the filter. MUST include everything that changes\n * whose list this is — principal/user id, backend base URL — so a\n * credential swap can never serve another identity's rows from the cache.\n */\n scopeKey?: string;\n enabled?: boolean;\n staleTime?: number;\n gcTime?: number;\n refetchOnMount?: boolean | 'always';\n refetchOnWindowFocus?: boolean;\n /**\n * Newest-page freshness is push-based by default (the conversation-index\n * statewire invalidates these caches), so no timer runs unless asked.\n */\n refetchInterval?: number | false;\n retry?: boolean | number | ((failureCount: number, error: Error) => boolean);\n}\n\nexport interface ConversationListController {\n /** Merged newest-first rows: live first page + retained history pages. */\n conversations: ConversationSummary[];\n /** Advisory total from the live first page, when the transport counts. */\n totalCount: number | null;\n isLoading: boolean;\n isFetching: boolean;\n /** True once the live first page has resolved at least once. */\n hasResolvedFirstPage: boolean;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n fetchNextPage: () => Promise<unknown>;\n /** Refetch the live first page (history pages stay frozen). */\n refresh: () => Promise<unknown>;\n /** Invalidate every conversation-list cache in this scope (all filters). */\n invalidate: () => Promise<void>;\n /** Optimistically show a new conversation at the top of THIS filter view. */\n prependConversation: (item: ConversationSummary) => void;\n /** Optimistically drop a conversation from THIS filter view. */\n removeConversation: (threadId: string) => void;\n /** Optimistically patch a conversation's row in THIS filter view. */\n patchConversation: (threadId: string, patch: Partial<ConversationSummary>) => void;\n}\n\n/**\n * The shared headless conversation-list pager (chat-stack unification —\n * thread-list-contract-convergence).\n *\n * Implements, once, the two-tier TanStack Query pattern Olympus and mobile\n * each hand-rolled:\n *\n * - a LIVE first-page query — the only observer that refetches on\n * invalidation/focus, so push-driven freshness costs one page, and\n * - a permanently-disabled infinite \"history\" query whose pages are fetched\n * only by explicit `fetchNextPage()` calls and retained without replay\n * (invalidation/polling never refetches every loaded page).\n *\n * Rows merge newest-first with the live page winning duplicate threads.\n */\nexport function useConversationList(options: UseConversationListOptions): ConversationListController {\n const {\n filter,\n pageSize = DEFAULT_PAGE_SIZE,\n scopeKey = CONVERSATION_LIST_DEFAULT_SCOPE_KEY,\n enabled,\n staleTime = DEFAULT_STALE_TIME_MS,\n gcTime = DEFAULT_GC_TIME_MS,\n refetchOnMount,\n refetchOnWindowFocus,\n refetchInterval = false,\n retry,\n } = options;\n const queryClient = useQueryClient();\n\n const fetchPageRef = useRef(options.fetchPage);\n fetchPageRef.current = options.fetchPage;\n\n // The normalized filter is both the cache identity (via the key) and what\n // queryFn closures fetch, so a cache entry holds exactly what it claims —\n // fresh-but-equal filter objects from the caller never re-key or refetch.\n // (Plain per-render values: only the serialized key participates in\n // identity, so object freshness here is irrelevant.)\n const normalizedFilter = normalizeConversationListFilter(filter ?? {});\n const filterKey = conversationListFilterKey(normalizedFilter);\n\n const firstPageKey = useMemo(\n () => conversationListQueryKeys.firstPage(scopeKey, filterKey, pageSize),\n [scopeKey, filterKey, pageSize]\n );\n const historyKey = useMemo(\n () => conversationListQueryKeys.history(scopeKey, filterKey, pageSize),\n [scopeKey, filterKey, pageSize]\n );\n\n // React Query merges per-query options OVER the client's defaultOptions with\n // Object.assign, which copies explicitly-`undefined` keys — so passing\n // `refetchOnWindowFocus: undefined` CLOBBERS a consumer's\n // `refetchOnWindowFocus: false` default and silently re-enables focus\n // refetching. Options the caller did not set must therefore be omitted, not\n // forwarded as undefined, so they fall through to the consuming app's client.\n const passthrough = {\n ...(enabled !== undefined ? { enabled } : {}),\n ...(refetchOnMount !== undefined ? { refetchOnMount } : {}),\n ...(refetchOnWindowFocus !== undefined ? { refetchOnWindowFocus } : {}),\n ...(retry !== undefined ? { retry } : {}),\n };\n\n const firstPage = useQuery({\n queryKey: firstPageKey,\n queryFn: ({ signal }) =>\n fetchPageRef.current({ limit: pageSize, offset: 0, filter: normalizedFilter, signal }),\n staleTime,\n gcTime,\n refetchInterval,\n ...passthrough,\n });\n\n const history = useInfiniteQuery({\n queryKey: historyKey,\n initialPageParam: pageSize,\n gcTime,\n queryFn: ({ pageParam, signal }) =>\n fetchPageRef.current({ limit: pageSize, offset: pageParam, filter: normalizedFilter, signal }),\n getNextPageParam: (lastPage, _allPages, lastOffset) =>\n lastPage.hasMore ? lastOffset + pageSize : undefined,\n ...passthrough,\n // fetchNextPage/refetch still perform explicit fetches for disabled\n // queries. Keeping this observer disabled prevents focus, invalidation,\n // and polling from replaying every retained historical page. This must\n // win over `passthrough.enabled`, so it is spread last.\n enabled: false,\n });\n\n const historyPages = history.data?.pages;\n const hasLoadedHistory = (historyPages?.length ?? 0) > 0;\n\n const conversations = useMemo(\n () =>\n mergeConversationPages([\n ...(firstPage.data ? [firstPage.data] : []),\n ...(historyPages ?? []),\n ]),\n [firstPage.data, historyPages]\n );\n\n const fetchNextHistoryPage = history.fetchNextPage;\n const refetchHistoryFirstPage = history.refetch;\n const fetchNextPage = useCallback(\n () => (hasLoadedHistory ? fetchNextHistoryPage() : refetchHistoryFirstPage()),\n [hasLoadedHistory, fetchNextHistoryPage, refetchHistoryFirstPage]\n );\n\n const refresh = useCallback(() => firstPage.refetch(), [firstPage.refetch]);\n\n const invalidate = useCallback(\n () => invalidateConversationListCaches(queryClient, { scopeKey }),\n [queryClient, scopeKey]\n );\n\n const prependConversation = useCallback(\n (item: ConversationSummary) => {\n queryClient.setQueryData<ConversationListPage>(firstPageKey, (page) =>\n page ? prependConversationToPage(page, item) : page\n );\n },\n [queryClient, firstPageKey]\n );\n\n const removeConversation = useCallback(\n (threadId: string) => {\n queryClient.setQueryData<ConversationListPage>(firstPageKey, (page) =>\n page ? removeConversationFromPage(page, threadId) : page\n );\n queryClient.setQueryData<InfiniteData<ConversationListPage, number>>(historyKey, (data) =>\n data\n ? { ...data, pages: data.pages.map((page) => removeConversationFromPage(page, threadId)) }\n : data\n );\n },\n [queryClient, firstPageKey, historyKey]\n );\n\n const patchConversation = useCallback(\n (threadId: string, patch: Partial<ConversationSummary>) => {\n const match = (item: ConversationSummary) => item.threadId === threadId;\n queryClient.setQueryData<ConversationListPage>(firstPageKey, (page) =>\n page ? patchConversationsInPage(page, match, patch) : page\n );\n queryClient.setQueryData<InfiniteData<ConversationListPage, number>>(historyKey, (data) =>\n data\n ? {\n ...data,\n pages: data.pages.map((page) => patchConversationsInPage(page, match, patch)),\n }\n : data\n );\n },\n [queryClient, firstPageKey, historyKey]\n );\n\n return {\n conversations,\n totalCount: firstPage.data?.totalCount ?? null,\n isLoading: firstPage.isLoading,\n isFetching: firstPage.isFetching || history.isFetching,\n hasResolvedFirstPage: firstPage.data !== undefined,\n hasNextPage: hasLoadedHistory\n ? (history.hasNextPage ?? false)\n : (firstPage.data?.hasMore ?? false),\n isFetchingNextPage: history.isFetchingNextPage || (!hasLoadedHistory && history.isFetching),\n fetchNextPage,\n refresh,\n invalidate,\n prependConversation,\n removeConversation,\n patchConversation,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-conversation-list.js","sources":["../../../../../agent-runtime/src/use-conversation-list.ts"],"sourcesContent":["import {\n type InfiniteData,\n useInfiniteQuery,\n useQuery,\n useQueryClient,\n} from '@tanstack/react-query';\nimport { useCallback, useMemo, useRef } from 'react';\nimport {\n CONVERSATION_LIST_DEFAULT_SCOPE_KEY,\n type ConversationListFetcher,\n type ConversationListFilter,\n type ConversationListPage,\n type ConversationSummary,\n conversationListFilterKey,\n conversationListQueryKeys,\n invalidateConversationListCaches,\n mergeConversationPages,\n normalizeConversationListFilter,\n patchConversationsInPage,\n prependConversationToPage,\n removeConversationFromPage,\n} from './conversation-list';\n\nconst DEFAULT_PAGE_SIZE = 20;\nconst DEFAULT_STALE_TIME_MS = 30_000;\nconst DEFAULT_GC_TIME_MS = 10 * 60 * 1000;\n\nexport interface UseConversationListOptions {\n /**\n * Transport adapter for one page (GraphQL `listConversations`, the REST\n * thread list, …). Captured in a ref — identity changes do not re-key the\n * cache, so pair a changing fetcher with a changing `scopeKey`.\n */\n fetchPage: ConversationListFetcher;\n filter?: ConversationListFilter;\n pageSize?: number;\n /**\n * Cache identity beyond the filter. MUST include everything that changes\n * whose list this is — principal/user id, backend base URL — so a\n * credential swap can never serve another identity's rows from the cache.\n */\n scopeKey?: string;\n enabled?: boolean;\n staleTime?: number;\n gcTime?: number;\n refetchOnMount?: boolean | 'always';\n refetchOnWindowFocus?: boolean;\n /**\n * Newest-page freshness is push-based by default (the conversation-index\n * statewire invalidates these caches), so no timer runs unless asked.\n */\n refetchInterval?: number | false;\n retry?: boolean | number | ((failureCount: number, error: Error) => boolean);\n}\n\nexport interface ConversationListController {\n /** Merged newest-first rows: live first page + retained history pages. */\n conversations: ConversationSummary[];\n /** Advisory total from the live first page, when the transport counts. */\n totalCount: number | null;\n isLoading: boolean;\n isFetching: boolean;\n /** True once the live first page has resolved at least once. */\n hasResolvedFirstPage: boolean;\n hasNextPage: boolean;\n isFetchingNextPage: boolean;\n /** True while the last next-page request failed (cleared by a successful one). */\n isFetchNextPageError: boolean;\n fetchNextPage: () => Promise<unknown>;\n /** Refetch the live first page (history pages stay frozen). */\n refresh: () => Promise<unknown>;\n /** Invalidate every conversation-list cache in this scope (all filters). */\n invalidate: () => Promise<void>;\n /** Optimistically show a new conversation at the top of THIS filter view. */\n prependConversation: (item: ConversationSummary) => void;\n /** Optimistically drop a conversation from THIS filter view. */\n removeConversation: (threadId: string) => void;\n /** Optimistically patch a conversation's row in THIS filter view. */\n patchConversation: (threadId: string, patch: Partial<ConversationSummary>) => void;\n}\n\n/**\n * The shared headless conversation-list pager (chat-stack unification —\n * thread-list-contract-convergence).\n *\n * Implements, once, the two-tier TanStack Query pattern Olympus and mobile\n * each hand-rolled:\n *\n * - a LIVE first-page query — the only observer that refetches on\n * invalidation/focus, so push-driven freshness costs one page, and\n * - a permanently-disabled infinite \"history\" query whose pages are fetched\n * only by explicit `fetchNextPage()` calls and retained without replay\n * (invalidation/polling never refetches every loaded page).\n *\n * Rows merge newest-first with the live page winning duplicate threads.\n */\nexport function useConversationList(options: UseConversationListOptions): ConversationListController {\n const {\n filter,\n pageSize = DEFAULT_PAGE_SIZE,\n scopeKey = CONVERSATION_LIST_DEFAULT_SCOPE_KEY,\n enabled,\n staleTime = DEFAULT_STALE_TIME_MS,\n gcTime = DEFAULT_GC_TIME_MS,\n refetchOnMount,\n refetchOnWindowFocus,\n refetchInterval = false,\n retry,\n } = options;\n const queryClient = useQueryClient();\n\n const fetchPageRef = useRef(options.fetchPage);\n fetchPageRef.current = options.fetchPage;\n\n // The normalized filter is both the cache identity (via the key) and what\n // queryFn closures fetch, so a cache entry holds exactly what it claims —\n // fresh-but-equal filter objects from the caller never re-key or refetch.\n // (Plain per-render values: only the serialized key participates in\n // identity, so object freshness here is irrelevant.)\n const normalizedFilter = normalizeConversationListFilter(filter ?? {});\n const filterKey = conversationListFilterKey(normalizedFilter);\n\n const firstPageKey = useMemo(\n () => conversationListQueryKeys.firstPage(scopeKey, filterKey, pageSize),\n [scopeKey, filterKey, pageSize]\n );\n const historyKey = useMemo(\n () => conversationListQueryKeys.history(scopeKey, filterKey, pageSize),\n [scopeKey, filterKey, pageSize]\n );\n\n // React Query merges per-query options OVER the client's defaultOptions with\n // Object.assign, which copies explicitly-`undefined` keys — so passing\n // `refetchOnWindowFocus: undefined` CLOBBERS a consumer's\n // `refetchOnWindowFocus: false` default and silently re-enables focus\n // refetching. Options the caller did not set must therefore be omitted, not\n // forwarded as undefined, so they fall through to the consuming app's client.\n const passthrough = {\n ...(enabled !== undefined ? { enabled } : {}),\n ...(refetchOnMount !== undefined ? { refetchOnMount } : {}),\n ...(refetchOnWindowFocus !== undefined ? { refetchOnWindowFocus } : {}),\n ...(retry !== undefined ? { retry } : {}),\n };\n\n const firstPage = useQuery({\n queryKey: firstPageKey,\n queryFn: ({ signal }) =>\n fetchPageRef.current({ limit: pageSize, offset: 0, filter: normalizedFilter, signal }),\n staleTime,\n gcTime,\n refetchInterval,\n ...passthrough,\n });\n\n const history = useInfiniteQuery({\n queryKey: historyKey,\n initialPageParam: pageSize,\n gcTime,\n queryFn: ({ pageParam, signal }) =>\n fetchPageRef.current({ limit: pageSize, offset: pageParam, filter: normalizedFilter, signal }),\n getNextPageParam: (lastPage, _allPages, lastOffset) =>\n lastPage.hasMore ? lastOffset + pageSize : undefined,\n ...passthrough,\n // fetchNextPage/refetch still perform explicit fetches for disabled\n // queries. Keeping this observer disabled prevents focus, invalidation,\n // and polling from replaying every retained historical page. This must\n // win over `passthrough.enabled`, so it is spread last.\n enabled: false,\n });\n\n const historyPages = history.data?.pages;\n const hasLoadedHistory = (historyPages?.length ?? 0) > 0;\n\n const conversations = useMemo(\n () =>\n mergeConversationPages([\n ...(firstPage.data ? [firstPage.data] : []),\n ...(historyPages ?? []),\n ]),\n [firstPage.data, historyPages]\n );\n\n const fetchNextHistoryPage = history.fetchNextPage;\n const refetchHistoryFirstPage = history.refetch;\n const fetchNextPage = useCallback(\n () => (hasLoadedHistory ? fetchNextHistoryPage() : refetchHistoryFirstPage()),\n [hasLoadedHistory, fetchNextHistoryPage, refetchHistoryFirstPage]\n );\n\n const refresh = useCallback(() => firstPage.refetch(), [firstPage.refetch]);\n\n const invalidate = useCallback(\n () => invalidateConversationListCaches(queryClient, { scopeKey }),\n [queryClient, scopeKey]\n );\n\n const prependConversation = useCallback(\n (item: ConversationSummary) => {\n queryClient.setQueryData<ConversationListPage>(firstPageKey, (page) =>\n page ? prependConversationToPage(page, item) : page\n );\n },\n [queryClient, firstPageKey]\n );\n\n const removeConversation = useCallback(\n (threadId: string) => {\n queryClient.setQueryData<ConversationListPage>(firstPageKey, (page) =>\n page ? removeConversationFromPage(page, threadId) : page\n );\n queryClient.setQueryData<InfiniteData<ConversationListPage, number>>(historyKey, (data) =>\n data\n ? { ...data, pages: data.pages.map((page) => removeConversationFromPage(page, threadId)) }\n : data\n );\n },\n [queryClient, firstPageKey, historyKey]\n );\n\n const patchConversation = useCallback(\n (threadId: string, patch: Partial<ConversationSummary>) => {\n const match = (item: ConversationSummary) => item.threadId === threadId;\n queryClient.setQueryData<ConversationListPage>(firstPageKey, (page) =>\n page ? patchConversationsInPage(page, match, patch) : page\n );\n queryClient.setQueryData<InfiniteData<ConversationListPage, number>>(historyKey, (data) =>\n data\n ? {\n ...data,\n pages: data.pages.map((page) => patchConversationsInPage(page, match, patch)),\n }\n : data\n );\n },\n [queryClient, firstPageKey, historyKey]\n );\n\n return {\n conversations,\n totalCount: firstPage.data?.totalCount ?? null,\n isLoading: firstPage.isLoading,\n isFetching: firstPage.isFetching || history.isFetching,\n hasResolvedFirstPage: firstPage.data !== undefined,\n hasNextPage: hasLoadedHistory\n ? (history.hasNextPage ?? false)\n : (firstPage.data?.hasMore ?? false),\n isFetchingNextPage: history.isFetchingNextPage || (!hasLoadedHistory && history.isFetching),\n isFetchNextPageError: history.isError,\n fetchNextPage,\n refresh,\n invalidate,\n prependConversation,\n removeConversation,\n patchConversation,\n };\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AthenaContext.cjs","sources":["../../src/provider/AthenaContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport type { AthenaProviderConfig } from './config';\nimport type { AthenaCitationLinkOptions, AthenaLinkClickOptions } from './citation-links';\n\nexport interface AthenaConfig extends Pick<AthenaProviderConfig, 'apiKey' | 'token'> {\n backendUrl: string;\n
|
|
1
|
+
{"version":3,"file":"AthenaContext.cjs","sources":["../../src/provider/AthenaContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport type { AthenaProviderConfig } from './config';\nimport type { AthenaCitationLinkOptions, AthenaLinkClickOptions } from './citation-links';\n\nexport interface AthenaConfig extends Pick<AthenaProviderConfig, 'apiKey' | 'token'> {\n backendUrl: string;\n /**\n * The SDK's live token resolver, for SDK hooks that call agora's REST\n * surface directly. Every sign-in mode feeds it (the host's `getToken`, a\n * sign-in provider, the Marathon or parent-window bridge); pass\n * `{ force: true }` after a 401 to renew the token before one resend.\n * Undefined when there is no token to resolve (API key alone).\n */\n getToken?: AthenaStatewireTokenGetter;\n appUrl: string;\n enabledToolkits: string[];\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}\n\nexport const AthenaContext = createContext<AthenaConfig | null>(null);\n\nexport function useAthenaConfig(): AthenaConfig {\n const ctx = useContext(AthenaContext);\n if (!ctx) {\n throw new Error('[AthenaSDK] useAthenaConfig must be used within <AthenaProvider>');\n }\n return ctx;\n}\n"],"names":["createContext","useContext"],"mappings":";;;AAqBO,MAAM,gBAAgBA,MAAAA,cAAmC,IAAI;AAE7D,SAAS,kBAAgC;AAC9C,QAAM,MAAMC,MAAAA,WAAW,aAAa;AACpC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AACA,SAAO;AACT;;;"}
|
|
@@ -3,7 +3,13 @@ import type { AthenaProviderConfig } from './config';
|
|
|
3
3
|
import type { AthenaCitationLinkOptions, AthenaLinkClickOptions } from './citation-links';
|
|
4
4
|
export interface AthenaConfig extends Pick<AthenaProviderConfig, 'apiKey' | 'token'> {
|
|
5
5
|
backendUrl: string;
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* The SDK's live token resolver, for SDK hooks that call agora's REST
|
|
8
|
+
* surface directly. Every sign-in mode feeds it (the host's `getToken`, a
|
|
9
|
+
* sign-in provider, the Marathon or parent-window bridge); pass
|
|
10
|
+
* `{ force: true }` after a 401 to renew the token before one resend.
|
|
11
|
+
* Undefined when there is no token to resolve (API key alone).
|
|
12
|
+
*/
|
|
7
13
|
getToken?: AthenaStatewireTokenGetter;
|
|
8
14
|
appUrl: string;
|
|
9
15
|
enabledToolkits: string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AthenaContext.js","sources":["../../src/provider/AthenaContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport type { AthenaProviderConfig } from './config';\nimport type { AthenaCitationLinkOptions, AthenaLinkClickOptions } from './citation-links';\n\nexport interface AthenaConfig extends Pick<AthenaProviderConfig, 'apiKey' | 'token'> {\n backendUrl: string;\n
|
|
1
|
+
{"version":3,"file":"AthenaContext.js","sources":["../../src/provider/AthenaContext.ts"],"sourcesContent":["import { createContext, useContext } from 'react';\nimport type { AthenaStatewireTokenGetter } from '../runtime/statewire-auth-headers';\nimport type { AthenaProviderConfig } from './config';\nimport type { AthenaCitationLinkOptions, AthenaLinkClickOptions } from './citation-links';\n\nexport interface AthenaConfig extends Pick<AthenaProviderConfig, 'apiKey' | 'token'> {\n backendUrl: string;\n /**\n * The SDK's live token resolver, for SDK hooks that call agora's REST\n * surface directly. Every sign-in mode feeds it (the host's `getToken`, a\n * sign-in provider, the Marathon or parent-window bridge); pass\n * `{ force: true }` after a 401 to renew the token before one resend.\n * Undefined when there is no token to resolve (API key alone).\n */\n getToken?: AthenaStatewireTokenGetter;\n appUrl: string;\n enabledToolkits: string[];\n linkClicks?: AthenaLinkClickOptions;\n citationLinks?: AthenaCitationLinkOptions;\n}\n\nexport const AthenaContext = createContext<AthenaConfig | null>(null);\n\nexport function useAthenaConfig(): AthenaConfig {\n const ctx = useContext(AthenaContext);\n if (!ctx) {\n throw new Error('[AthenaSDK] useAthenaConfig must be used within <AthenaProvider>');\n }\n return ctx;\n}\n"],"names":[],"mappings":";AAqBO,MAAM,gBAAgB,cAAmC,IAAI;AAE7D,SAAS,kBAAgC;AAC9C,QAAM,MAAM,WAAW,aAAa;AACpC,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,kEAAkE;AAAA,EACpF;AACA,SAAO;AACT;"}
|
|
@@ -7,6 +7,9 @@ const athenaUrls = require("../lib/athena-urls.cjs");
|
|
|
7
7
|
const mint = require("../collab/mint.cjs");
|
|
8
8
|
const auth = require("../runtime/auth.cjs");
|
|
9
9
|
const AthenaAuthContext = require("../auth/AthenaAuthContext.cjs");
|
|
10
|
+
const AthenaCredentialSourceContext = require("../auth/AthenaCredentialSourceContext.cjs");
|
|
11
|
+
const credentialSource = require("../auth/credential-source.cjs");
|
|
12
|
+
const authRefusalRestart = require("../runtime/auth-refusal-restart.cjs");
|
|
10
13
|
const useAthenaStatewireRuntime = require("../runtime/useAthenaStatewireRuntime.cjs");
|
|
11
14
|
const statewireLifecycle = require("../runtime/statewire-lifecycle.cjs");
|
|
12
15
|
const statewireRunConfig = require("../runtime/statewire-run-config.cjs");
|
|
@@ -150,6 +153,10 @@ function AthenaStatewireRuntimeMount({
|
|
|
150
153
|
dispatchLifecycle({ type: "raw-connection", reconnect: connection.reconnect });
|
|
151
154
|
}
|
|
152
155
|
});
|
|
156
|
+
authRefusalRestart.useRestartAfterAuthRefusal({
|
|
157
|
+
connection: lifecycle.connection,
|
|
158
|
+
reconnect: lifecycle.reconnect
|
|
159
|
+
});
|
|
153
160
|
const dismissError = react.useCallback(
|
|
154
161
|
() => dispatchLifecycle({ type: "error", error: null }),
|
|
155
162
|
[]
|
|
@@ -414,6 +421,20 @@ function AthenaProvider({
|
|
|
414
421
|
[composerHandoff$1]
|
|
415
422
|
);
|
|
416
423
|
const effectiveToken = configuredToken !== void 0 ? configuredToken : authProviderToken ?? bridge.token;
|
|
424
|
+
const authProviderGetToken = authContext == null ? void 0 : authContext.getToken;
|
|
425
|
+
const credentialInputsRef = react.useRef({ token: null });
|
|
426
|
+
credentialInputsRef.current = {
|
|
427
|
+
hostGetToken: configuredGetToken,
|
|
428
|
+
token: effectiveToken,
|
|
429
|
+
renew: configuredToken !== void 0 ? void 0 : authProviderToken !== null ? authProviderGetToken ? async ({ force }) => await authProviderGetToken({ force }) ?? null : void 0 : bridge.token !== null ? bridge.renewToken : void 0
|
|
430
|
+
};
|
|
431
|
+
const [credentials] = react.useState(
|
|
432
|
+
() => credentialSource.createAthenaCredentialSource(() => credentialInputsRef.current)
|
|
433
|
+
);
|
|
434
|
+
react.useEffect(() => {
|
|
435
|
+
credentials.notifyTokenChanged();
|
|
436
|
+
}, [credentials, effectiveToken]);
|
|
437
|
+
const credentialGetToken = configuredGetToken !== void 0 || effectiveToken ? credentials.getToken : void 0;
|
|
417
438
|
const effectiveApiUrl = configuredApiUrl ?? environmentUrls.apiUrl;
|
|
418
439
|
const effectiveBackendUrl = mint.getAthenaApiBaseUrl(
|
|
419
440
|
configuredBackendUrl ?? bridge.backendBaseUrl ?? environmentUrls.backendUrl
|
|
@@ -439,7 +460,7 @@ function AthenaProvider({
|
|
|
439
460
|
appUrl: effectiveAppUrl,
|
|
440
461
|
apiKey: configuredApiKey,
|
|
441
462
|
token: effectiveToken,
|
|
442
|
-
getToken:
|
|
463
|
+
getToken: credentialGetToken,
|
|
443
464
|
model,
|
|
444
465
|
agent,
|
|
445
466
|
channel,
|
|
@@ -470,7 +491,7 @@ function AthenaProvider({
|
|
|
470
491
|
{
|
|
471
492
|
className: themeStyleVars ? "athena-sdk athena-themed" : "athena-sdk",
|
|
472
493
|
style: themeStyleVars,
|
|
473
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(PostHogProvider.PostHogProvider, { config: posthogConfig, children: /* @__PURE__ */ jsxRuntime.jsx(composerHandoff.ComposerHandoffContext.Provider, { value: composerHandoff$1, children: /* @__PURE__ */ jsxRuntime.jsx(themeStyleContext.AthenaThemeStyleContext.Provider, { value: themeStyleVars, children: inner }) }) })
|
|
494
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(PostHogProvider.PostHogProvider, { config: posthogConfig, children: /* @__PURE__ */ jsxRuntime.jsx(composerHandoff.ComposerHandoffContext.Provider, { value: composerHandoff$1, children: /* @__PURE__ */ jsxRuntime.jsx(themeStyleContext.AthenaThemeStyleContext.Provider, { value: themeStyleVars, children: /* @__PURE__ */ jsxRuntime.jsx(AthenaCredentialSourceContext.AthenaCredentialSourceContext.Provider, { value: credentials, children: inner }) }) }) })
|
|
474
495
|
}
|
|
475
496
|
);
|
|
476
497
|
}
|