@athenaintel/react 0.25.0 → 0.26.1
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 +10 -0
- package/dist/assets/AssetPanel.cjs +1 -1
- package/dist/assets/AssetPanel.cjs.map +1 -1
- package/dist/assets/AssetPanel.js +1 -1
- package/dist/assets/AssetPanel.js.map +1 -1
- package/dist/assets/AthenaAssetEmbed.cjs +1 -1
- package/dist/assets/AthenaAssetEmbed.cjs.map +1 -1
- package/dist/assets/AthenaAssetEmbed.js +1 -1
- package/dist/assets/AthenaAssetEmbed.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/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/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/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/styles.css +1 -1
- package/dist/threads/use-rest-conversation-history.d.ts +1 -0
- package/dist/threads/use-statewire-conversation-history.d.ts +2 -0
- 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/package.json +13 -16
|
@@ -27,7 +27,6 @@ const RUN_CONFIG_CUSTOM_KEYS = [
|
|
|
27
27
|
"enabled_toolkits",
|
|
28
28
|
"enabled_tools",
|
|
29
29
|
"environment",
|
|
30
|
-
"environment_asset_id",
|
|
31
30
|
"environment_id",
|
|
32
31
|
"environment_name",
|
|
33
32
|
"excluded_middleware",
|
|
@@ -54,6 +53,7 @@ const RUN_CONFIG_CUSTOM_KEYS = [
|
|
|
54
53
|
"muses_enabled",
|
|
55
54
|
"muses_recall_enabled",
|
|
56
55
|
"office_context",
|
|
56
|
+
"outbound_approval_allowlist",
|
|
57
57
|
"panel_config",
|
|
58
58
|
"permissions",
|
|
59
59
|
"project_id",
|
|
@@ -138,7 +138,6 @@ const THREAD_CONFIG_CUSTOM_KEYS = [
|
|
|
138
138
|
"enabled_toolkits",
|
|
139
139
|
"enabled_tools",
|
|
140
140
|
"environment",
|
|
141
|
-
"environment_asset_id",
|
|
142
141
|
"environment_id",
|
|
143
142
|
"environment_name",
|
|
144
143
|
"excluded_middleware",
|
|
@@ -160,6 +159,7 @@ const THREAD_CONFIG_CUSTOM_KEYS = [
|
|
|
160
159
|
"memory",
|
|
161
160
|
"middleware",
|
|
162
161
|
"model",
|
|
162
|
+
"outbound_approval_allowlist",
|
|
163
163
|
"permissions",
|
|
164
164
|
"recursion_limit",
|
|
165
165
|
"run_label",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runconfig-contract.cjs","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.cjs","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;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -25,7 +25,6 @@ const RUN_CONFIG_CUSTOM_KEYS = [
|
|
|
25
25
|
"enabled_toolkits",
|
|
26
26
|
"enabled_tools",
|
|
27
27
|
"environment",
|
|
28
|
-
"environment_asset_id",
|
|
29
28
|
"environment_id",
|
|
30
29
|
"environment_name",
|
|
31
30
|
"excluded_middleware",
|
|
@@ -52,6 +51,7 @@ const RUN_CONFIG_CUSTOM_KEYS = [
|
|
|
52
51
|
"muses_enabled",
|
|
53
52
|
"muses_recall_enabled",
|
|
54
53
|
"office_context",
|
|
54
|
+
"outbound_approval_allowlist",
|
|
55
55
|
"panel_config",
|
|
56
56
|
"permissions",
|
|
57
57
|
"project_id",
|
|
@@ -136,7 +136,6 @@ const THREAD_CONFIG_CUSTOM_KEYS = [
|
|
|
136
136
|
"enabled_toolkits",
|
|
137
137
|
"enabled_tools",
|
|
138
138
|
"environment",
|
|
139
|
-
"environment_asset_id",
|
|
140
139
|
"environment_id",
|
|
141
140
|
"environment_name",
|
|
142
141
|
"excluded_middleware",
|
|
@@ -158,6 +157,7 @@ const THREAD_CONFIG_CUSTOM_KEYS = [
|
|
|
158
157
|
"memory",
|
|
159
158
|
"middleware",
|
|
160
159
|
"model",
|
|
160
|
+
"outbound_approval_allowlist",
|
|
161
161
|
"permissions",
|
|
162
162
|
"recursion_limit",
|
|
163
163
|
"run_label",
|
|
@@ -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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"}
|
|
@@ -3,7 +3,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
|
3
3
|
const DEEP_AGENT_RUNTIME_MARKER = "athena_deep_agent";
|
|
4
4
|
const STATEWIRE_START_CHANNEL = "web";
|
|
5
5
|
const STATEWIRE_RUN_LABEL = "Athena SDK";
|
|
6
|
-
const DEFAULT_STATEWIRE_MODEL = "claude-sonnet-5";
|
|
6
|
+
const DEFAULT_STATEWIRE_MODEL = "claude-sonnet-5-5";
|
|
7
7
|
const COLLAB_AGENT_REF_PREFIX = "collab_agent:";
|
|
8
8
|
const COLLAB_AGENT_REF_SHAPE = "collab_agent:<asset_id>";
|
|
9
9
|
function parseCollabAgentRef(agent) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statewire-run-config.cjs","sources":["../../src/runtime/statewire-run-config.ts"],"sourcesContent":["/** Runtime marker the deep-agent session substrate stamps on sessions. */\nconst DEEP_AGENT_RUNTIME_MARKER = 'athena_deep_agent';\n\n/** Session-origin channel. The backend clamps unknown values to 'web', which\n * is how every SDK-started session has always classified. */\nconst STATEWIRE_START_CHANNEL = 'web';\n\n/** Session label persisted in the thread's panel config (mirrors\n * 'Athena Chrome' / 'Athena mobile' in the sibling statewire hosts). */\nconst STATEWIRE_RUN_LABEL = 'Athena SDK';\n\n/** Deep-agent default model — matches the Olympus and mobile statewire hosts. */\nexport const DEFAULT_STATEWIRE_MODEL = 'claude-sonnet-5';\n\n/** Agent-id namespace for collab agents (`collab_agent:<asset_id>`). */\nexport const COLLAB_AGENT_REF_PREFIX = 'collab_agent:';\n\n/** The only shape the `agent` prop accepts, for error messages and docs. */\nexport const COLLAB_AGENT_REF_SHAPE = 'collab_agent:<asset_id>';\n\n/** The asset id when `agent` is a `collab_agent:<asset_id>` ref, else null. */\nexport function parseCollabAgentRef(agent: string | undefined | null): string | null {\n if (typeof agent !== 'string' || !agent.startsWith(COLLAB_AGENT_REF_PREFIX)) return null;\n const assetId = agent.slice(COLLAB_AGENT_REF_PREFIX.length).trim();\n return assetId || null;\n}\n\n/**\n * Resolve the provider's `agent` prop to a collab-agent asset id.\n *\n * An omitted or blank `agent` means \"no agent selected\" — the thread runs the\n * Athena deep agent — and resolves to `null`. A `collab_agent:<asset_id>` ref\n * resolves to the asset id. Any other non-blank value throws: the statewire\n * host cannot honour it, and a selector that is silently dropped would let a\n * misconfigured deployment ship answers from the wrong agent.\n */\nexport function resolveAgentProp({ agent }: { agent: string | undefined | null }): string | null {\n if (agent === undefined || agent === null || agent.trim() === '') return null;\n const assetId = parseCollabAgentRef(agent.trim());\n if (assetId) return assetId;\n throw new Error(\n `[AthenaSDK] Unsupported \\`agent\\` prop ${JSON.stringify(agent)}. The only accepted shape is '${COLLAB_AGENT_REF_SHAPE}' (the asset id of a published collab agent). Named agents are not supported — the statewire host always runs the Athena deep agent; omit \\`agent\\` to use it.`,\n );\n}\n\nexport interface StatewireRunConfigOptions {\n /** LLM model identifier. Defaults to the deep-agent default model — unless a\n * collab agent is selected and its author set one (the backend overlay\n * applies the agent's model when the run sends none), in which case no\n * model is sent so the agent's choice wins. */\n model?: string;\n /** Agent selector. Only the `collab_agent:<asset_id>` shape is accepted: the\n * run executes AS that published collab agent (prompt, tools, model\n * default). Any other non-empty value throws (see {@link resolveAgentProp}). */\n agent?: string;\n /** Collab-agent channel id (built-in like `email`/`sms`, or a user-defined\n * custom channel id) selecting that channel's configuration overrides.\n * Sent as `collab_channel_id`; only meaningful with a collab `agent`. */\n channel?: string;\n /** Backend toolkit IDs to enable. */\n tools?: string[];\n /** Frontend tool IDs to include in enabled_tools. */\n frontendToolIds?: string[];\n /** Asset IDs to include in the workbench. */\n workbench?: string[];\n /** Knowledge base IDs for RAG context. */\n knowledgeBase?: string[];\n /** System prompt override. */\n systemPrompt?: string;\n /** Client app identifier, passed through as app_id. */\n appId?: string;\n /** Client-executed tool declarations, passed through as client_tools. The\n * deep-agent runtime binds each as an interrupt-backed tool the client\n * answers via the statewire client-tool bridge. */\n clientTools?: Record<string, unknown>[];\n /** Additional fields merged into runConfig.custom. */\n extraRunConfig?: Record<string, unknown>;\n}\n\n/**\n * Build the `runConfig` a deep-agent statewire run is driven by. Commands\n * travel bare on the statewire channel, so this payload rides the ambient\n * model context (`config.runConfig`) instead of the request body.\n *\n * The flattened `custom` fields drive the run, while `panel_config` carries a\n * minimal panel state the backend persists per thread and replays on the\n * statewire snapshot — so a session started from the SDK stays configured\n * when reopened elsewhere.\n */\nexport function buildStatewireRunConfig(\n options: StatewireRunConfigOptions = {},\n): Record<string, unknown> {\n const collabAgentId = resolveAgentProp({ agent: options.agent });\n const collabChannelId =\n collabAgentId && options.channel?.trim() ? options.channel.trim() : undefined;\n // With a collab agent selected and no explicit model, send NO model: the\n // backend overlay then applies the model the agent's author configured\n // instead of the SDK default overriding it.\n const model = options.model ?? (collabAgentId ? undefined : DEFAULT_STATEWIRE_MODEL);\n const panelModel = model ?? DEFAULT_STATEWIRE_MODEL;\n const enabledTools = Array.from(\n new Set([...(options.tools ?? []), ...(options.frontendToolIds ?? [])]),\n );\n const systemPrompt = options.systemPrompt?.trim() ?? '';\n\n return {\n custom: {\n runtime: DEEP_AGENT_RUNTIME_MARKER,\n // With a collab channel selected, omit the SDK's own 'web' stamp: the\n // request's explicit start_channel would win over the backend overlay's\n // kind-mapped provenance (a custom SMS channel must stamp 'sms').\n ...(collabChannelId ? {} : { start_channel: STATEWIRE_START_CHANNEL }),\n ...(model ? { model } : {}),\n // An empty list is behavior-identical to an absent key for the parser\n // (both coerce to []), but the collab-agent overlay merges request keys\n // OVER the agent definition — so an explicit empty list would erase the\n // agent's configured tools. Omit it when empty.\n ...(enabledTools.length > 0 ? { enabled_tools: enabledTools } : {}),\n panel_config: {\n model: panelModel,\n enabled_tools: enabledTools,\n system_prompt: systemPrompt,\n run_label: STATEWIRE_RUN_LABEL,\n },\n ...(collabAgentId ? { collab_agent_id: collabAgentId } : {}),\n ...(collabChannelId ? { collab_channel_id: collabChannelId } : {}),\n ...(systemPrompt ? { system_prompt: systemPrompt } : {}),\n ...(options.workbench?.length ? { workbench: options.workbench } : {}),\n ...(options.knowledgeBase?.length\n ? { knowledge_base: options.knowledgeBase }\n : {}),\n ...(options.appId ? { app_id: options.appId } : {}),\n ...(options.clientTools?.length ? { client_tools: options.clientTools } : {}),\n ...(options.extraRunConfig ?? {}),\n },\n };\n}\n"],"names":[],"mappings":";;AACA,MAAM,4BAA4B;AAIlC,MAAM,0BAA0B;AAIhC,MAAM,sBAAsB;AAGrB,MAAM,0BAA0B;AAGhC,MAAM,0BAA0B;AAGhC,MAAM,yBAAyB;AAG/B,SAAS,oBAAoB,OAAiD;AACnF,MAAI,OAAO,UAAU,YAAY,CAAC,MAAM,WAAW,uBAAuB,EAAG,QAAO;AACpF,QAAM,UAAU,MAAM,MAAM,wBAAwB,MAAM,EAAE,KAAA;AAC5D,SAAO,WAAW;AACpB;AAWO,SAAS,iBAAiB,EAAE,SAA8D;AAC/F,MAAI,UAAU,UAAa,UAAU,QAAQ,MAAM,KAAA,MAAW,GAAI,QAAO;AACzE,QAAM,UAAU,oBAAoB,MAAM,KAAA,CAAM;AAChD,MAAI,QAAS,QAAO;AACpB,QAAM,IAAI;AAAA,IACR,0CAA0C,KAAK,UAAU,KAAK,CAAC,iCAAiC,sBAAsB;AAAA,EAAA;AAE1H;AA8CO,SAAS,wBACd,UAAqC,IACZ;;AACzB,QAAM,gBAAgB,iBAAiB,EAAE,OAAO,QAAQ,OAAO;AAC/D,QAAM,kBACJ,mBAAiB,aAAQ,YAAR,mBAAiB,UAAS,QAAQ,QAAQ,KAAA,IAAS;AAItE,QAAM,QAAQ,QAAQ,UAAU,gBAAgB,SAAY;AAC5D,QAAM,aAAa,SAAS;AAC5B,QAAM,eAAe,MAAM;AAAA,IACzB,oBAAI,IAAI,CAAC,GAAI,QAAQ,SAAS,CAAA,GAAK,GAAI,QAAQ,mBAAmB,EAAG,CAAC;AAAA,EAAA;AAExE,QAAM,iBAAe,aAAQ,iBAAR,mBAAsB,WAAU;AAErD,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,SAAS;AAAA;AAAA;AAAA;AAAA,MAIT,GAAI,kBAAkB,CAAA,IAAK,EAAE,eAAe,wBAAA;AAAA,MAC5C,GAAI,QAAQ,EAAE,MAAA,IAAU,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAKxB,GAAI,aAAa,SAAS,IAAI,EAAE,eAAe,aAAA,IAAiB,CAAA;AAAA,MAChE,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,eAAe;AAAA,QACf,eAAe;AAAA,QACf,WAAW;AAAA,MAAA;AAAA,MAEb,GAAI,gBAAgB,EAAE,iBAAiB,cAAA,IAAkB,CAAA;AAAA,MACzD,GAAI,kBAAkB,EAAE,mBAAmB,gBAAA,IAAoB,CAAA;AAAA,MAC/D,GAAI,eAAe,EAAE,eAAe,aAAA,IAAiB,CAAA;AAAA,MACrD,KAAI,aAAQ,cAAR,mBAAmB,UAAS,EAAE,WAAW,QAAQ,UAAA,IAAc,CAAA;AAAA,MACnE,KAAI,aAAQ,kBAAR,mBAAuB,UACvB,EAAE,gBAAgB,QAAQ,cAAA,IAC1B,CAAA;AAAA,MACJ,GAAI,QAAQ,QAAQ,EAAE,QAAQ,QAAQ,MAAA,IAAU,CAAA;AAAA,MAChD,KAAI,aAAQ,gBAAR,mBAAqB,UAAS,EAAE,cAAc,QAAQ,YAAA,IAAgB,CAAA;AAAA,MAC1E,GAAI,QAAQ,kBAAkB,CAAA;AAAA,IAAC;AAAA,EACjC;AAEJ;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"statewire-run-config.cjs","sources":["../../src/runtime/statewire-run-config.ts"],"sourcesContent":["/** Runtime marker the deep-agent session substrate stamps on sessions. */\nconst DEEP_AGENT_RUNTIME_MARKER = 'athena_deep_agent';\n\n/** Session-origin channel. The backend clamps unknown values to 'web', which\n * is how every SDK-started session has always classified. */\nconst STATEWIRE_START_CHANNEL = 'web';\n\n/** Session label persisted in the thread's panel config (mirrors\n * 'Athena Chrome' / 'Athena mobile' in the sibling statewire hosts). */\nconst STATEWIRE_RUN_LABEL = 'Athena SDK';\n\n/** Deep-agent default model — matches the Olympus and mobile statewire hosts. */\nexport const DEFAULT_STATEWIRE_MODEL = 'claude-sonnet-5-5';\n\n/** Agent-id namespace for collab agents (`collab_agent:<asset_id>`). */\nexport const COLLAB_AGENT_REF_PREFIX = 'collab_agent:';\n\n/** The only shape the `agent` prop accepts, for error messages and docs. */\nexport const COLLAB_AGENT_REF_SHAPE = 'collab_agent:<asset_id>';\n\n/** The asset id when `agent` is a `collab_agent:<asset_id>` ref, else null. */\nexport function parseCollabAgentRef(agent: string | undefined | null): string | null {\n if (typeof agent !== 'string' || !agent.startsWith(COLLAB_AGENT_REF_PREFIX)) return null;\n const assetId = agent.slice(COLLAB_AGENT_REF_PREFIX.length).trim();\n return assetId || null;\n}\n\n/**\n * Resolve the provider's `agent` prop to a collab-agent asset id.\n *\n * An omitted or blank `agent` means \"no agent selected\" — the thread runs the\n * Athena deep agent — and resolves to `null`. A `collab_agent:<asset_id>` ref\n * resolves to the asset id. Any other non-blank value throws: the statewire\n * host cannot honour it, and a selector that is silently dropped would let a\n * misconfigured deployment ship answers from the wrong agent.\n */\nexport function resolveAgentProp({ agent }: { agent: string | undefined | null }): string | null {\n if (agent === undefined || agent === null || agent.trim() === '') return null;\n const assetId = parseCollabAgentRef(agent.trim());\n if (assetId) return assetId;\n throw new Error(\n `[AthenaSDK] Unsupported \\`agent\\` prop ${JSON.stringify(agent)}. The only accepted shape is '${COLLAB_AGENT_REF_SHAPE}' (the asset id of a published collab agent). Named agents are not supported — the statewire host always runs the Athena deep agent; omit \\`agent\\` to use it.`,\n );\n}\n\nexport interface StatewireRunConfigOptions {\n /** LLM model identifier. Defaults to the deep-agent default model — unless a\n * collab agent is selected and its author set one (the backend overlay\n * applies the agent's model when the run sends none), in which case no\n * model is sent so the agent's choice wins. */\n model?: string;\n /** Agent selector. Only the `collab_agent:<asset_id>` shape is accepted: the\n * run executes AS that published collab agent (prompt, tools, model\n * default). Any other non-empty value throws (see {@link resolveAgentProp}). */\n agent?: string;\n /** Collab-agent channel id (built-in like `email`/`sms`, or a user-defined\n * custom channel id) selecting that channel's configuration overrides.\n * Sent as `collab_channel_id`; only meaningful with a collab `agent`. */\n channel?: string;\n /** Backend toolkit IDs to enable. */\n tools?: string[];\n /** Frontend tool IDs to include in enabled_tools. */\n frontendToolIds?: string[];\n /** Asset IDs to include in the workbench. */\n workbench?: string[];\n /** Knowledge base IDs for RAG context. */\n knowledgeBase?: string[];\n /** System prompt override. */\n systemPrompt?: string;\n /** Client app identifier, passed through as app_id. */\n appId?: string;\n /** Client-executed tool declarations, passed through as client_tools. The\n * deep-agent runtime binds each as an interrupt-backed tool the client\n * answers via the statewire client-tool bridge. */\n clientTools?: Record<string, unknown>[];\n /** Additional fields merged into runConfig.custom. */\n extraRunConfig?: Record<string, unknown>;\n}\n\n/**\n * Build the `runConfig` a deep-agent statewire run is driven by. Commands\n * travel bare on the statewire channel, so this payload rides the ambient\n * model context (`config.runConfig`) instead of the request body.\n *\n * The flattened `custom` fields drive the run, while `panel_config` carries a\n * minimal panel state the backend persists per thread and replays on the\n * statewire snapshot — so a session started from the SDK stays configured\n * when reopened elsewhere.\n */\nexport function buildStatewireRunConfig(\n options: StatewireRunConfigOptions = {},\n): Record<string, unknown> {\n const collabAgentId = resolveAgentProp({ agent: options.agent });\n const collabChannelId =\n collabAgentId && options.channel?.trim() ? options.channel.trim() : undefined;\n // With a collab agent selected and no explicit model, send NO model: the\n // backend overlay then applies the model the agent's author configured\n // instead of the SDK default overriding it.\n const model = options.model ?? (collabAgentId ? undefined : DEFAULT_STATEWIRE_MODEL);\n const panelModel = model ?? DEFAULT_STATEWIRE_MODEL;\n const enabledTools = Array.from(\n new Set([...(options.tools ?? []), ...(options.frontendToolIds ?? [])]),\n );\n const systemPrompt = options.systemPrompt?.trim() ?? '';\n\n return {\n custom: {\n runtime: DEEP_AGENT_RUNTIME_MARKER,\n // With a collab channel selected, omit the SDK's own 'web' stamp: the\n // request's explicit start_channel would win over the backend overlay's\n // kind-mapped provenance (a custom SMS channel must stamp 'sms').\n ...(collabChannelId ? {} : { start_channel: STATEWIRE_START_CHANNEL }),\n ...(model ? { model } : {}),\n // An empty list is behavior-identical to an absent key for the parser\n // (both coerce to []), but the collab-agent overlay merges request keys\n // OVER the agent definition — so an explicit empty list would erase the\n // agent's configured tools. Omit it when empty.\n ...(enabledTools.length > 0 ? { enabled_tools: enabledTools } : {}),\n panel_config: {\n model: panelModel,\n enabled_tools: enabledTools,\n system_prompt: systemPrompt,\n run_label: STATEWIRE_RUN_LABEL,\n },\n ...(collabAgentId ? { collab_agent_id: collabAgentId } : {}),\n ...(collabChannelId ? { collab_channel_id: collabChannelId } : {}),\n ...(systemPrompt ? { system_prompt: systemPrompt } : {}),\n ...(options.workbench?.length ? { workbench: options.workbench } : {}),\n ...(options.knowledgeBase?.length\n ? { knowledge_base: options.knowledgeBase }\n : {}),\n ...(options.appId ? { app_id: options.appId } : {}),\n ...(options.clientTools?.length ? { client_tools: options.clientTools } : {}),\n ...(options.extraRunConfig ?? {}),\n },\n };\n}\n"],"names":[],"mappings":";;AACA,MAAM,4BAA4B;AAIlC,MAAM,0BAA0B;AAIhC,MAAM,sBAAsB;AAGrB,MAAM,0BAA0B;AAGhC,MAAM,0BAA0B;AAGhC,MAAM,yBAAyB;AAG/B,SAAS,oBAAoB,OAAiD;AACnF,MAAI,OAAO,UAAU,YAAY,CAAC,MAAM,WAAW,uBAAuB,EAAG,QAAO;AACpF,QAAM,UAAU,MAAM,MAAM,wBAAwB,MAAM,EAAE,KAAA;AAC5D,SAAO,WAAW;AACpB;AAWO,SAAS,iBAAiB,EAAE,SAA8D;AAC/F,MAAI,UAAU,UAAa,UAAU,QAAQ,MAAM,KAAA,MAAW,GAAI,QAAO;AACzE,QAAM,UAAU,oBAAoB,MAAM,KAAA,CAAM;AAChD,MAAI,QAAS,QAAO;AACpB,QAAM,IAAI;AAAA,IACR,0CAA0C,KAAK,UAAU,KAAK,CAAC,iCAAiC,sBAAsB;AAAA,EAAA;AAE1H;AA8CO,SAAS,wBACd,UAAqC,IACZ;;AACzB,QAAM,gBAAgB,iBAAiB,EAAE,OAAO,QAAQ,OAAO;AAC/D,QAAM,kBACJ,mBAAiB,aAAQ,YAAR,mBAAiB,UAAS,QAAQ,QAAQ,KAAA,IAAS;AAItE,QAAM,QAAQ,QAAQ,UAAU,gBAAgB,SAAY;AAC5D,QAAM,aAAa,SAAS;AAC5B,QAAM,eAAe,MAAM;AAAA,IACzB,oBAAI,IAAI,CAAC,GAAI,QAAQ,SAAS,CAAA,GAAK,GAAI,QAAQ,mBAAmB,EAAG,CAAC;AAAA,EAAA;AAExE,QAAM,iBAAe,aAAQ,iBAAR,mBAAsB,WAAU;AAErD,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,SAAS;AAAA;AAAA;AAAA;AAAA,MAIT,GAAI,kBAAkB,CAAA,IAAK,EAAE,eAAe,wBAAA;AAAA,MAC5C,GAAI,QAAQ,EAAE,MAAA,IAAU,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAKxB,GAAI,aAAa,SAAS,IAAI,EAAE,eAAe,aAAA,IAAiB,CAAA;AAAA,MAChE,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,eAAe;AAAA,QACf,eAAe;AAAA,QACf,WAAW;AAAA,MAAA;AAAA,MAEb,GAAI,gBAAgB,EAAE,iBAAiB,cAAA,IAAkB,CAAA;AAAA,MACzD,GAAI,kBAAkB,EAAE,mBAAmB,gBAAA,IAAoB,CAAA;AAAA,MAC/D,GAAI,eAAe,EAAE,eAAe,aAAA,IAAiB,CAAA;AAAA,MACrD,KAAI,aAAQ,cAAR,mBAAmB,UAAS,EAAE,WAAW,QAAQ,UAAA,IAAc,CAAA;AAAA,MACnE,KAAI,aAAQ,kBAAR,mBAAuB,UACvB,EAAE,gBAAgB,QAAQ,cAAA,IAC1B,CAAA;AAAA,MACJ,GAAI,QAAQ,QAAQ,EAAE,QAAQ,QAAQ,MAAA,IAAU,CAAA;AAAA,MAChD,KAAI,aAAQ,gBAAR,mBAAqB,UAAS,EAAE,cAAc,QAAQ,YAAA,IAAgB,CAAA;AAAA,MAC1E,GAAI,QAAQ,kBAAkB,CAAA;AAAA,IAAC;AAAA,EACjC;AAEJ;;;;;;;"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/** Deep-agent default model — matches the Olympus and mobile statewire hosts. */
|
|
2
|
-
export declare const DEFAULT_STATEWIRE_MODEL = "claude-sonnet-5";
|
|
2
|
+
export declare const DEFAULT_STATEWIRE_MODEL = "claude-sonnet-5-5";
|
|
3
3
|
/** Agent-id namespace for collab agents (`collab_agent:<asset_id>`). */
|
|
4
4
|
export declare const COLLAB_AGENT_REF_PREFIX = "collab_agent:";
|
|
5
5
|
/** The only shape the `agent` prop accepts, for error messages and docs. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const DEEP_AGENT_RUNTIME_MARKER = "athena_deep_agent";
|
|
2
2
|
const STATEWIRE_START_CHANNEL = "web";
|
|
3
3
|
const STATEWIRE_RUN_LABEL = "Athena SDK";
|
|
4
|
-
const DEFAULT_STATEWIRE_MODEL = "claude-sonnet-5";
|
|
4
|
+
const DEFAULT_STATEWIRE_MODEL = "claude-sonnet-5-5";
|
|
5
5
|
const COLLAB_AGENT_REF_PREFIX = "collab_agent:";
|
|
6
6
|
const COLLAB_AGENT_REF_SHAPE = "collab_agent:<asset_id>";
|
|
7
7
|
function parseCollabAgentRef(agent) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"statewire-run-config.js","sources":["../../src/runtime/statewire-run-config.ts"],"sourcesContent":["/** Runtime marker the deep-agent session substrate stamps on sessions. */\nconst DEEP_AGENT_RUNTIME_MARKER = 'athena_deep_agent';\n\n/** Session-origin channel. The backend clamps unknown values to 'web', which\n * is how every SDK-started session has always classified. */\nconst STATEWIRE_START_CHANNEL = 'web';\n\n/** Session label persisted in the thread's panel config (mirrors\n * 'Athena Chrome' / 'Athena mobile' in the sibling statewire hosts). */\nconst STATEWIRE_RUN_LABEL = 'Athena SDK';\n\n/** Deep-agent default model — matches the Olympus and mobile statewire hosts. */\nexport const DEFAULT_STATEWIRE_MODEL = 'claude-sonnet-5';\n\n/** Agent-id namespace for collab agents (`collab_agent:<asset_id>`). */\nexport const COLLAB_AGENT_REF_PREFIX = 'collab_agent:';\n\n/** The only shape the `agent` prop accepts, for error messages and docs. */\nexport const COLLAB_AGENT_REF_SHAPE = 'collab_agent:<asset_id>';\n\n/** The asset id when `agent` is a `collab_agent:<asset_id>` ref, else null. */\nexport function parseCollabAgentRef(agent: string | undefined | null): string | null {\n if (typeof agent !== 'string' || !agent.startsWith(COLLAB_AGENT_REF_PREFIX)) return null;\n const assetId = agent.slice(COLLAB_AGENT_REF_PREFIX.length).trim();\n return assetId || null;\n}\n\n/**\n * Resolve the provider's `agent` prop to a collab-agent asset id.\n *\n * An omitted or blank `agent` means \"no agent selected\" — the thread runs the\n * Athena deep agent — and resolves to `null`. A `collab_agent:<asset_id>` ref\n * resolves to the asset id. Any other non-blank value throws: the statewire\n * host cannot honour it, and a selector that is silently dropped would let a\n * misconfigured deployment ship answers from the wrong agent.\n */\nexport function resolveAgentProp({ agent }: { agent: string | undefined | null }): string | null {\n if (agent === undefined || agent === null || agent.trim() === '') return null;\n const assetId = parseCollabAgentRef(agent.trim());\n if (assetId) return assetId;\n throw new Error(\n `[AthenaSDK] Unsupported \\`agent\\` prop ${JSON.stringify(agent)}. The only accepted shape is '${COLLAB_AGENT_REF_SHAPE}' (the asset id of a published collab agent). Named agents are not supported — the statewire host always runs the Athena deep agent; omit \\`agent\\` to use it.`,\n );\n}\n\nexport interface StatewireRunConfigOptions {\n /** LLM model identifier. Defaults to the deep-agent default model — unless a\n * collab agent is selected and its author set one (the backend overlay\n * applies the agent's model when the run sends none), in which case no\n * model is sent so the agent's choice wins. */\n model?: string;\n /** Agent selector. Only the `collab_agent:<asset_id>` shape is accepted: the\n * run executes AS that published collab agent (prompt, tools, model\n * default). Any other non-empty value throws (see {@link resolveAgentProp}). */\n agent?: string;\n /** Collab-agent channel id (built-in like `email`/`sms`, or a user-defined\n * custom channel id) selecting that channel's configuration overrides.\n * Sent as `collab_channel_id`; only meaningful with a collab `agent`. */\n channel?: string;\n /** Backend toolkit IDs to enable. */\n tools?: string[];\n /** Frontend tool IDs to include in enabled_tools. */\n frontendToolIds?: string[];\n /** Asset IDs to include in the workbench. */\n workbench?: string[];\n /** Knowledge base IDs for RAG context. */\n knowledgeBase?: string[];\n /** System prompt override. */\n systemPrompt?: string;\n /** Client app identifier, passed through as app_id. */\n appId?: string;\n /** Client-executed tool declarations, passed through as client_tools. The\n * deep-agent runtime binds each as an interrupt-backed tool the client\n * answers via the statewire client-tool bridge. */\n clientTools?: Record<string, unknown>[];\n /** Additional fields merged into runConfig.custom. */\n extraRunConfig?: Record<string, unknown>;\n}\n\n/**\n * Build the `runConfig` a deep-agent statewire run is driven by. Commands\n * travel bare on the statewire channel, so this payload rides the ambient\n * model context (`config.runConfig`) instead of the request body.\n *\n * The flattened `custom` fields drive the run, while `panel_config` carries a\n * minimal panel state the backend persists per thread and replays on the\n * statewire snapshot — so a session started from the SDK stays configured\n * when reopened elsewhere.\n */\nexport function buildStatewireRunConfig(\n options: StatewireRunConfigOptions = {},\n): Record<string, unknown> {\n const collabAgentId = resolveAgentProp({ agent: options.agent });\n const collabChannelId =\n collabAgentId && options.channel?.trim() ? options.channel.trim() : undefined;\n // With a collab agent selected and no explicit model, send NO model: the\n // backend overlay then applies the model the agent's author configured\n // instead of the SDK default overriding it.\n const model = options.model ?? (collabAgentId ? undefined : DEFAULT_STATEWIRE_MODEL);\n const panelModel = model ?? DEFAULT_STATEWIRE_MODEL;\n const enabledTools = Array.from(\n new Set([...(options.tools ?? []), ...(options.frontendToolIds ?? [])]),\n );\n const systemPrompt = options.systemPrompt?.trim() ?? '';\n\n return {\n custom: {\n runtime: DEEP_AGENT_RUNTIME_MARKER,\n // With a collab channel selected, omit the SDK's own 'web' stamp: the\n // request's explicit start_channel would win over the backend overlay's\n // kind-mapped provenance (a custom SMS channel must stamp 'sms').\n ...(collabChannelId ? {} : { start_channel: STATEWIRE_START_CHANNEL }),\n ...(model ? { model } : {}),\n // An empty list is behavior-identical to an absent key for the parser\n // (both coerce to []), but the collab-agent overlay merges request keys\n // OVER the agent definition — so an explicit empty list would erase the\n // agent's configured tools. Omit it when empty.\n ...(enabledTools.length > 0 ? { enabled_tools: enabledTools } : {}),\n panel_config: {\n model: panelModel,\n enabled_tools: enabledTools,\n system_prompt: systemPrompt,\n run_label: STATEWIRE_RUN_LABEL,\n },\n ...(collabAgentId ? { collab_agent_id: collabAgentId } : {}),\n ...(collabChannelId ? { collab_channel_id: collabChannelId } : {}),\n ...(systemPrompt ? { system_prompt: systemPrompt } : {}),\n ...(options.workbench?.length ? { workbench: options.workbench } : {}),\n ...(options.knowledgeBase?.length\n ? { knowledge_base: options.knowledgeBase }\n : {}),\n ...(options.appId ? { app_id: options.appId } : {}),\n ...(options.clientTools?.length ? { client_tools: options.clientTools } : {}),\n ...(options.extraRunConfig ?? {}),\n },\n };\n}\n"],"names":[],"mappings":"AACA,MAAM,4BAA4B;AAIlC,MAAM,0BAA0B;AAIhC,MAAM,sBAAsB;AAGrB,MAAM,0BAA0B;AAGhC,MAAM,0BAA0B;AAGhC,MAAM,yBAAyB;AAG/B,SAAS,oBAAoB,OAAiD;AACnF,MAAI,OAAO,UAAU,YAAY,CAAC,MAAM,WAAW,uBAAuB,EAAG,QAAO;AACpF,QAAM,UAAU,MAAM,MAAM,wBAAwB,MAAM,EAAE,KAAA;AAC5D,SAAO,WAAW;AACpB;AAWO,SAAS,iBAAiB,EAAE,SAA8D;AAC/F,MAAI,UAAU,UAAa,UAAU,QAAQ,MAAM,KAAA,MAAW,GAAI,QAAO;AACzE,QAAM,UAAU,oBAAoB,MAAM,KAAA,CAAM;AAChD,MAAI,QAAS,QAAO;AACpB,QAAM,IAAI;AAAA,IACR,0CAA0C,KAAK,UAAU,KAAK,CAAC,iCAAiC,sBAAsB;AAAA,EAAA;AAE1H;AA8CO,SAAS,wBACd,UAAqC,IACZ;AA1F3B;AA2FE,QAAM,gBAAgB,iBAAiB,EAAE,OAAO,QAAQ,OAAO;AAC/D,QAAM,kBACJ,mBAAiB,aAAQ,YAAR,mBAAiB,UAAS,QAAQ,QAAQ,KAAA,IAAS;AAItE,QAAM,QAAQ,QAAQ,UAAU,gBAAgB,SAAY;AAC5D,QAAM,aAAa,SAAS;AAC5B,QAAM,eAAe,MAAM;AAAA,IACzB,oBAAI,IAAI,CAAC,GAAI,QAAQ,SAAS,CAAA,GAAK,GAAI,QAAQ,mBAAmB,EAAG,CAAC;AAAA,EAAA;AAExE,QAAM,iBAAe,aAAQ,iBAAR,mBAAsB,WAAU;AAErD,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,SAAS;AAAA;AAAA;AAAA;AAAA,MAIT,GAAI,kBAAkB,CAAA,IAAK,EAAE,eAAe,wBAAA;AAAA,MAC5C,GAAI,QAAQ,EAAE,MAAA,IAAU,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAKxB,GAAI,aAAa,SAAS,IAAI,EAAE,eAAe,aAAA,IAAiB,CAAA;AAAA,MAChE,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,eAAe;AAAA,QACf,eAAe;AAAA,QACf,WAAW;AAAA,MAAA;AAAA,MAEb,GAAI,gBAAgB,EAAE,iBAAiB,cAAA,IAAkB,CAAA;AAAA,MACzD,GAAI,kBAAkB,EAAE,mBAAmB,gBAAA,IAAoB,CAAA;AAAA,MAC/D,GAAI,eAAe,EAAE,eAAe,aAAA,IAAiB,CAAA;AAAA,MACrD,KAAI,aAAQ,cAAR,mBAAmB,UAAS,EAAE,WAAW,QAAQ,UAAA,IAAc,CAAA;AAAA,MACnE,KAAI,aAAQ,kBAAR,mBAAuB,UACvB,EAAE,gBAAgB,QAAQ,cAAA,IAC1B,CAAA;AAAA,MACJ,GAAI,QAAQ,QAAQ,EAAE,QAAQ,QAAQ,MAAA,IAAU,CAAA;AAAA,MAChD,KAAI,aAAQ,gBAAR,mBAAqB,UAAS,EAAE,cAAc,QAAQ,YAAA,IAAgB,CAAA;AAAA,MAC1E,GAAI,QAAQ,kBAAkB,CAAA;AAAA,IAAC;AAAA,EACjC;AAEJ;"}
|
|
1
|
+
{"version":3,"file":"statewire-run-config.js","sources":["../../src/runtime/statewire-run-config.ts"],"sourcesContent":["/** Runtime marker the deep-agent session substrate stamps on sessions. */\nconst DEEP_AGENT_RUNTIME_MARKER = 'athena_deep_agent';\n\n/** Session-origin channel. The backend clamps unknown values to 'web', which\n * is how every SDK-started session has always classified. */\nconst STATEWIRE_START_CHANNEL = 'web';\n\n/** Session label persisted in the thread's panel config (mirrors\n * 'Athena Chrome' / 'Athena mobile' in the sibling statewire hosts). */\nconst STATEWIRE_RUN_LABEL = 'Athena SDK';\n\n/** Deep-agent default model — matches the Olympus and mobile statewire hosts. */\nexport const DEFAULT_STATEWIRE_MODEL = 'claude-sonnet-5-5';\n\n/** Agent-id namespace for collab agents (`collab_agent:<asset_id>`). */\nexport const COLLAB_AGENT_REF_PREFIX = 'collab_agent:';\n\n/** The only shape the `agent` prop accepts, for error messages and docs. */\nexport const COLLAB_AGENT_REF_SHAPE = 'collab_agent:<asset_id>';\n\n/** The asset id when `agent` is a `collab_agent:<asset_id>` ref, else null. */\nexport function parseCollabAgentRef(agent: string | undefined | null): string | null {\n if (typeof agent !== 'string' || !agent.startsWith(COLLAB_AGENT_REF_PREFIX)) return null;\n const assetId = agent.slice(COLLAB_AGENT_REF_PREFIX.length).trim();\n return assetId || null;\n}\n\n/**\n * Resolve the provider's `agent` prop to a collab-agent asset id.\n *\n * An omitted or blank `agent` means \"no agent selected\" — the thread runs the\n * Athena deep agent — and resolves to `null`. A `collab_agent:<asset_id>` ref\n * resolves to the asset id. Any other non-blank value throws: the statewire\n * host cannot honour it, and a selector that is silently dropped would let a\n * misconfigured deployment ship answers from the wrong agent.\n */\nexport function resolveAgentProp({ agent }: { agent: string | undefined | null }): string | null {\n if (agent === undefined || agent === null || agent.trim() === '') return null;\n const assetId = parseCollabAgentRef(agent.trim());\n if (assetId) return assetId;\n throw new Error(\n `[AthenaSDK] Unsupported \\`agent\\` prop ${JSON.stringify(agent)}. The only accepted shape is '${COLLAB_AGENT_REF_SHAPE}' (the asset id of a published collab agent). Named agents are not supported — the statewire host always runs the Athena deep agent; omit \\`agent\\` to use it.`,\n );\n}\n\nexport interface StatewireRunConfigOptions {\n /** LLM model identifier. Defaults to the deep-agent default model — unless a\n * collab agent is selected and its author set one (the backend overlay\n * applies the agent's model when the run sends none), in which case no\n * model is sent so the agent's choice wins. */\n model?: string;\n /** Agent selector. Only the `collab_agent:<asset_id>` shape is accepted: the\n * run executes AS that published collab agent (prompt, tools, model\n * default). Any other non-empty value throws (see {@link resolveAgentProp}). */\n agent?: string;\n /** Collab-agent channel id (built-in like `email`/`sms`, or a user-defined\n * custom channel id) selecting that channel's configuration overrides.\n * Sent as `collab_channel_id`; only meaningful with a collab `agent`. */\n channel?: string;\n /** Backend toolkit IDs to enable. */\n tools?: string[];\n /** Frontend tool IDs to include in enabled_tools. */\n frontendToolIds?: string[];\n /** Asset IDs to include in the workbench. */\n workbench?: string[];\n /** Knowledge base IDs for RAG context. */\n knowledgeBase?: string[];\n /** System prompt override. */\n systemPrompt?: string;\n /** Client app identifier, passed through as app_id. */\n appId?: string;\n /** Client-executed tool declarations, passed through as client_tools. The\n * deep-agent runtime binds each as an interrupt-backed tool the client\n * answers via the statewire client-tool bridge. */\n clientTools?: Record<string, unknown>[];\n /** Additional fields merged into runConfig.custom. */\n extraRunConfig?: Record<string, unknown>;\n}\n\n/**\n * Build the `runConfig` a deep-agent statewire run is driven by. Commands\n * travel bare on the statewire channel, so this payload rides the ambient\n * model context (`config.runConfig`) instead of the request body.\n *\n * The flattened `custom` fields drive the run, while `panel_config` carries a\n * minimal panel state the backend persists per thread and replays on the\n * statewire snapshot — so a session started from the SDK stays configured\n * when reopened elsewhere.\n */\nexport function buildStatewireRunConfig(\n options: StatewireRunConfigOptions = {},\n): Record<string, unknown> {\n const collabAgentId = resolveAgentProp({ agent: options.agent });\n const collabChannelId =\n collabAgentId && options.channel?.trim() ? options.channel.trim() : undefined;\n // With a collab agent selected and no explicit model, send NO model: the\n // backend overlay then applies the model the agent's author configured\n // instead of the SDK default overriding it.\n const model = options.model ?? (collabAgentId ? undefined : DEFAULT_STATEWIRE_MODEL);\n const panelModel = model ?? DEFAULT_STATEWIRE_MODEL;\n const enabledTools = Array.from(\n new Set([...(options.tools ?? []), ...(options.frontendToolIds ?? [])]),\n );\n const systemPrompt = options.systemPrompt?.trim() ?? '';\n\n return {\n custom: {\n runtime: DEEP_AGENT_RUNTIME_MARKER,\n // With a collab channel selected, omit the SDK's own 'web' stamp: the\n // request's explicit start_channel would win over the backend overlay's\n // kind-mapped provenance (a custom SMS channel must stamp 'sms').\n ...(collabChannelId ? {} : { start_channel: STATEWIRE_START_CHANNEL }),\n ...(model ? { model } : {}),\n // An empty list is behavior-identical to an absent key for the parser\n // (both coerce to []), but the collab-agent overlay merges request keys\n // OVER the agent definition — so an explicit empty list would erase the\n // agent's configured tools. Omit it when empty.\n ...(enabledTools.length > 0 ? { enabled_tools: enabledTools } : {}),\n panel_config: {\n model: panelModel,\n enabled_tools: enabledTools,\n system_prompt: systemPrompt,\n run_label: STATEWIRE_RUN_LABEL,\n },\n ...(collabAgentId ? { collab_agent_id: collabAgentId } : {}),\n ...(collabChannelId ? { collab_channel_id: collabChannelId } : {}),\n ...(systemPrompt ? { system_prompt: systemPrompt } : {}),\n ...(options.workbench?.length ? { workbench: options.workbench } : {}),\n ...(options.knowledgeBase?.length\n ? { knowledge_base: options.knowledgeBase }\n : {}),\n ...(options.appId ? { app_id: options.appId } : {}),\n ...(options.clientTools?.length ? { client_tools: options.clientTools } : {}),\n ...(options.extraRunConfig ?? {}),\n },\n };\n}\n"],"names":[],"mappings":"AACA,MAAM,4BAA4B;AAIlC,MAAM,0BAA0B;AAIhC,MAAM,sBAAsB;AAGrB,MAAM,0BAA0B;AAGhC,MAAM,0BAA0B;AAGhC,MAAM,yBAAyB;AAG/B,SAAS,oBAAoB,OAAiD;AACnF,MAAI,OAAO,UAAU,YAAY,CAAC,MAAM,WAAW,uBAAuB,EAAG,QAAO;AACpF,QAAM,UAAU,MAAM,MAAM,wBAAwB,MAAM,EAAE,KAAA;AAC5D,SAAO,WAAW;AACpB;AAWO,SAAS,iBAAiB,EAAE,SAA8D;AAC/F,MAAI,UAAU,UAAa,UAAU,QAAQ,MAAM,KAAA,MAAW,GAAI,QAAO;AACzE,QAAM,UAAU,oBAAoB,MAAM,KAAA,CAAM;AAChD,MAAI,QAAS,QAAO;AACpB,QAAM,IAAI;AAAA,IACR,0CAA0C,KAAK,UAAU,KAAK,CAAC,iCAAiC,sBAAsB;AAAA,EAAA;AAE1H;AA8CO,SAAS,wBACd,UAAqC,IACZ;AA1F3B;AA2FE,QAAM,gBAAgB,iBAAiB,EAAE,OAAO,QAAQ,OAAO;AAC/D,QAAM,kBACJ,mBAAiB,aAAQ,YAAR,mBAAiB,UAAS,QAAQ,QAAQ,KAAA,IAAS;AAItE,QAAM,QAAQ,QAAQ,UAAU,gBAAgB,SAAY;AAC5D,QAAM,aAAa,SAAS;AAC5B,QAAM,eAAe,MAAM;AAAA,IACzB,oBAAI,IAAI,CAAC,GAAI,QAAQ,SAAS,CAAA,GAAK,GAAI,QAAQ,mBAAmB,EAAG,CAAC;AAAA,EAAA;AAExE,QAAM,iBAAe,aAAQ,iBAAR,mBAAsB,WAAU;AAErD,SAAO;AAAA,IACL,QAAQ;AAAA,MACN,SAAS;AAAA;AAAA;AAAA;AAAA,MAIT,GAAI,kBAAkB,CAAA,IAAK,EAAE,eAAe,wBAAA;AAAA,MAC5C,GAAI,QAAQ,EAAE,MAAA,IAAU,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAKxB,GAAI,aAAa,SAAS,IAAI,EAAE,eAAe,aAAA,IAAiB,CAAA;AAAA,MAChE,cAAc;AAAA,QACZ,OAAO;AAAA,QACP,eAAe;AAAA,QACf,eAAe;AAAA,QACf,WAAW;AAAA,MAAA;AAAA,MAEb,GAAI,gBAAgB,EAAE,iBAAiB,cAAA,IAAkB,CAAA;AAAA,MACzD,GAAI,kBAAkB,EAAE,mBAAmB,gBAAA,IAAoB,CAAA;AAAA,MAC/D,GAAI,eAAe,EAAE,eAAe,aAAA,IAAiB,CAAA;AAAA,MACrD,KAAI,aAAQ,cAAR,mBAAmB,UAAS,EAAE,WAAW,QAAQ,UAAA,IAAc,CAAA;AAAA,MACnE,KAAI,aAAQ,kBAAR,mBAAuB,UACvB,EAAE,gBAAgB,QAAQ,cAAA,IAC1B,CAAA;AAAA,MACJ,GAAI,QAAQ,QAAQ,EAAE,QAAQ,QAAQ,MAAA,IAAU,CAAA;AAAA,MAChD,KAAI,aAAQ,gBAAR,mBAAqB,UAAS,EAAE,cAAc,QAAQ,YAAA,IAAgB,CAAA;AAAA,MAC1E,GAAI,QAAQ,kBAAkB,CAAA;AAAA,IAAC;AAAA,EACjC;AAEJ;"}
|