shortcutxl 0.3.77 → 0.3.78
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/BINARY-INVENTORY.json +9 -9
- package/CHANGELOG.md +8 -0
- package/dist/app/agent-session.d.ts +0 -15
- package/dist/app/agent-session.js +0 -37
- package/dist/app/extensions/slash-commands.js +1 -3
- package/dist/app/modes/action/agent.js +4 -5
- package/dist/app/modes/ask/agent.js +4 -6
- package/dist/app/modes/index.js +20 -10
- package/dist/app/modes/installation/agent.js +4 -5
- package/dist/app/modes/manage/agent.js +3 -4
- package/dist/app/modes/manage/prompt.js +1 -2
- package/dist/app/modes/metadata.d.ts +31 -0
- package/dist/app/modes/metadata.js +35 -0
- package/dist/app/modes/plan/agent.js +5 -8
- package/dist/app/modes/plan/prompt.js +3 -3
- package/dist/app/prompts/com-api.js +1 -1
- package/dist/app/prompts/shared-guidelines.js +6 -2
- package/dist/app/providers/register-shortcut-provider.js +4 -0
- package/dist/app/tools/bash.js +3 -3
- package/dist/app/tools/switch-mode.js +2 -2
- package/dist/app/tools/web-search.js +12 -2
- package/dist/cli.js +871 -2144
- package/dist/constants.d.ts +0 -2
- package/dist/constants.js +0 -3
- package/dist/contracts/model-call.d.ts +0 -1
- package/dist/contracts/model-call.js +1 -2
- package/dist/contracts/wire.d.ts +8 -1
- package/dist/contracts/wire.js +8 -0
- package/dist/embedded-agent/ai-invoke.d.ts +1 -2
- package/dist/embedded-agent/ai-invoke.js +0 -70
- package/dist/embedded-agent/anthropic-messages-transport.d.ts +1 -2
- package/dist/embedded-agent/google-vertex-transport.d.ts +1 -2
- package/dist/embedded-agent/host-tools/invoke-llm/contract.d.ts +1 -1
- package/dist/embedded-agent/host-tools/invoke-llm/contract.js +1 -1
- package/dist/embedded-agent/host-tools/shared/index.d.ts +1 -1
- package/dist/embedded-agent/host-tools/shared/index.js +1 -1
- package/dist/embedded-agent/host-tools/shared/llm-stream-error.d.ts +7 -0
- package/dist/embedded-agent/host-tools/shared/llm-stream-error.js +10 -0
- package/dist/embedded-agent/index.d.ts +3 -4
- package/dist/embedded-agent/index.js +2 -3
- package/dist/embedded-agent/openai-completions-transport.d.ts +1 -2
- package/dist/embedded-agent/openai-responses-transport.d.ts +1 -2
- package/dist/embedded-agent/prompt/sections.d.ts +1 -1
- package/dist/embedded-agent/prompt/sections.js +2 -0
- package/dist/embedded-agent/provider-native-request.d.ts +5 -0
- package/dist/embedded-agent/provider-native-request.js +3 -2
- package/dist/embedded-agent/stream.d.ts +8 -88
- package/dist/embedded-agent/stream.js +20 -537
- package/dist/embedded-agent/suggestions.d.ts +1 -1
- package/dist/embedded-agent/suggestions.js +1 -1
- package/dist/embedded-agent/worker-bridge/host-client.d.ts +7 -0
- package/dist/embedded-agent/worker-bridge/host-client.js +15 -0
- package/dist/embedded-agent/worker-bridge/worker-port.js +17 -1
- package/dist/main.js +16 -1
- package/dist/rpc/index.d.ts +1 -1
- package/dist/rpc/rpc-host.d.ts +4 -0
- package/dist/rpc/rpc-host.js +13 -24
- package/dist/rpc/rpc-types.d.ts +6 -17
- package/dist/shared/platform/open.d.ts +4 -1
- package/dist/shared/platform/open.js +14 -2
- package/dist/shell/interactive/interactive-mode-options.d.ts +10 -0
- package/dist/shell/interactive/interactive-mode.d.ts +6 -12
- package/dist/shell/interactive/interactive-mode.js +36 -157
- package/dist/shell/interactive/slash-commands.d.ts +0 -34
- package/dist/shell/interactive/slash-commands.js +0 -2
- package/dist/shell/links/local-file-link-input.d.ts +15 -0
- package/dist/shell/links/local-file-link-input.js +38 -0
- package/dist/shell/links/local-file-link.d.ts +7 -0
- package/dist/shell/links/local-file-link.js +35 -0
- package/dist/shell/links/local-file-opener.d.ts +16 -0
- package/dist/shell/links/local-file-opener.js +90 -0
- package/dist/shell/session-client.d.ts +0 -1
- package/dist/shell/session-client.js +0 -6
- package/dist/shell/status/update-check-scheduler.d.ts +30 -0
- package/dist/shell/status/update-check-scheduler.js +71 -0
- package/dist/shell/status/update-reminder-controller.d.ts +22 -0
- package/dist/shell/status/update-reminder-controller.js +40 -0
- package/dist/shell/status/update-reminder.d.ts +6 -0
- package/dist/shell/status/update-reminder.js +4 -0
- package/dist/shell/theme/dark.json +1 -2
- package/dist/shell/theme/light.json +1 -2
- package/dist/shell/theme/runtime.d.ts +1 -2
- package/dist/shell/theme/runtime.js +1 -6
- package/dist/shell/theme/theme-schema.json +1 -6
- package/dist/shortcut-model-catalog.js +12 -5
- package/dist/startup/update-manager.d.ts +6 -6
- package/dist/startup/update-manager.js +23 -38
- package/dist/startup/update-prompt.d.ts +1 -0
- package/dist/startup/update-prompt.js +2 -2
- package/dist/tui/components/markdown.js +15 -6
- package/dist/tui/index.d.ts +7 -1
- package/dist/tui/index.js +7 -1
- package/dist/tui/tui.d.ts +2 -0
- package/dist/tui/tui.js +16 -1
- package/dist/tui/utils.d.ts +7 -0
- package/dist/tui/utils.js +58 -8
- package/native-app/main/index.js +1 -1
- package/native-app/package.json +1 -1
- package/native-app/renderer/assets/{index-CtherCML.js → index-B4jz6epR.js} +594 -151
- package/native-app/renderer/assets/{index-B9UxxO8s.css → index-C__g36ft.css} +408 -160
- package/native-app/renderer/assets/shortcutagent-DxFsGSkw.png +0 -0
- package/native-app/renderer/index.html +2 -2
- package/package.json +2 -1
- package/user-docs/dist/index.html +1 -1
- package/user-docs/dist/shortcutxl-docs.pdf +0 -0
- package/xll/ShortcutXL.xll +0 -0
- package/xll/modules/shortcut_xl/_managed.py +26 -7
- package/xll/modules/shortcut_xl/_tracking.py +141 -251
- package/xll/modules/shortcut_xl/api/__init__.py +60 -0
- package/xll/modules/shortcut_xl/api/workbook.py +9 -1
- package/xll/modules/shortcut_xl/api/worksheet.py +4 -1
- package/xll/python/Lib/site-packages/httpx-0.28.1.dist-info/RECORD +1 -1
- package/xll/python/Lib/site-packages/idna-3.18.dist-info/RECORD +1 -1
- package/xll/python/Lib/site-packages/pip/__init__.py +1 -1
- package/xll/python/Lib/site-packages/pip/_internal/build_env/__init__.py +25 -0
- package/xll/python/Lib/site-packages/pip/_internal/build_env/base.py +103 -0
- package/xll/python/Lib/site-packages/pip/_internal/build_env/installer.py +333 -0
- package/xll/python/Lib/site-packages/pip/_internal/build_env/noop.py +42 -0
- package/xll/python/Lib/site-packages/pip/_internal/build_env/venv.py +145 -0
- package/xll/python/Lib/site-packages/pip/_internal/build_env/virtual.py +139 -0
- package/xll/python/Lib/site-packages/pip/_internal/cache.py +4 -1
- package/xll/python/Lib/site-packages/pip/_internal/cli/autocompletion.py +4 -1
- package/xll/python/Lib/site-packages/pip/_internal/cli/base_command.py +11 -14
- package/xll/python/Lib/site-packages/pip/_internal/cli/cmdoptions.py +133 -22
- package/xll/python/Lib/site-packages/pip/_internal/cli/index_command.py +11 -6
- package/xll/python/Lib/site-packages/pip/_internal/cli/main.py +2 -1
- package/xll/python/Lib/site-packages/pip/_internal/cli/main_parser.py +1 -2
- package/xll/python/Lib/site-packages/pip/_internal/cli/parser.py +10 -2
- package/xll/python/Lib/site-packages/pip/_internal/cli/progress_bars.py +2 -2
- package/xll/python/Lib/site-packages/pip/_internal/cli/req_command.py +57 -25
- package/xll/python/Lib/site-packages/pip/_internal/cli/status_codes.py +1 -0
- package/xll/python/Lib/site-packages/pip/_internal/commands/cache.py +7 -6
- package/xll/python/Lib/site-packages/pip/_internal/commands/configuration.py +2 -1
- package/xll/python/Lib/site-packages/pip/_internal/commands/debug.py +4 -5
- package/xll/python/Lib/site-packages/pip/_internal/commands/download.py +4 -0
- package/xll/python/Lib/site-packages/pip/_internal/commands/freeze.py +1 -1
- package/xll/python/Lib/site-packages/pip/_internal/commands/index.py +10 -3
- package/xll/python/Lib/site-packages/pip/_internal/commands/inspect.py +1 -1
- package/xll/python/Lib/site-packages/pip/_internal/commands/install.py +6 -6
- package/xll/python/Lib/site-packages/pip/_internal/commands/list.py +11 -6
- package/xll/python/Lib/site-packages/pip/_internal/commands/lock.py +4 -6
- package/xll/python/Lib/site-packages/pip/_internal/commands/show.py +14 -8
- package/xll/python/Lib/site-packages/pip/_internal/commands/wheel.py +7 -1
- package/xll/python/Lib/site-packages/pip/_internal/configuration.py +2 -3
- package/xll/python/Lib/site-packages/pip/_internal/distributions/base.py +5 -3
- package/xll/python/Lib/site-packages/pip/_internal/distributions/installed.py +3 -2
- package/xll/python/Lib/site-packages/pip/_internal/distributions/sdist.py +45 -20
- package/xll/python/Lib/site-packages/pip/_internal/distributions/wheel.py +3 -2
- package/xll/python/Lib/site-packages/pip/_internal/exceptions.py +174 -0
- package/xll/python/Lib/site-packages/pip/_internal/index/collector.py +70 -48
- package/xll/python/Lib/site-packages/pip/_internal/index/package_finder.py +46 -7
- package/xll/python/Lib/site-packages/pip/_internal/index/sources.py +1 -2
- package/xll/python/Lib/site-packages/pip/_internal/locations/_sysconfig.py +1 -1
- package/xll/python/Lib/site-packages/pip/_internal/locations/base.py +1 -1
- package/xll/python/Lib/site-packages/pip/_internal/metadata/base.py +10 -5
- package/xll/python/Lib/site-packages/pip/_internal/metadata/importlib/_dists.py +1 -1
- package/xll/python/Lib/site-packages/pip/_internal/metadata/importlib/_envs.py +8 -3
- package/xll/python/Lib/site-packages/pip/_internal/models/candidate.py +5 -1
- package/xll/python/Lib/site-packages/pip/_internal/models/link.py +53 -13
- package/xll/python/Lib/site-packages/pip/_internal/network/auth.py +38 -21
- package/xll/python/Lib/site-packages/pip/_internal/network/cache.py +2 -2
- package/xll/python/Lib/site-packages/pip/_internal/network/download.py +58 -11
- package/xll/python/Lib/site-packages/pip/_internal/network/session.py +35 -40
- package/xll/python/Lib/site-packages/pip/_internal/network/utils.py +109 -1
- package/xll/python/Lib/site-packages/pip/_internal/operations/check.py +2 -3
- package/xll/python/Lib/site-packages/pip/_internal/operations/install/wheel.py +23 -18
- package/xll/python/Lib/site-packages/pip/_internal/operations/prepare.py +152 -7
- package/xll/python/Lib/site-packages/pip/_internal/req/__init__.py +2 -0
- package/xll/python/Lib/site-packages/pip/_internal/req/constructors.py +54 -69
- package/xll/python/Lib/site-packages/pip/_internal/req/req_file.py +6 -6
- package/xll/python/Lib/site-packages/pip/_internal/req/req_install.py +25 -21
- package/xll/python/Lib/site-packages/pip/_internal/req/req_uninstall.py +13 -8
- package/xll/python/Lib/site-packages/pip/_internal/resolution/base.py +2 -2
- package/xll/python/Lib/site-packages/pip/_internal/resolution/legacy/resolver.py +2 -2
- package/xll/python/Lib/site-packages/pip/_internal/resolution/resolvelib/base.py +1 -1
- package/xll/python/Lib/site-packages/pip/_internal/resolution/resolvelib/candidates.py +0 -1
- package/xll/python/Lib/site-packages/pip/_internal/resolution/resolvelib/factory.py +39 -52
- package/xll/python/Lib/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py +3 -3
- package/xll/python/Lib/site-packages/pip/_internal/resolution/resolvelib/provider.py +3 -0
- package/xll/python/Lib/site-packages/pip/_internal/resolution/resolvelib/resolver.py +9 -0
- package/xll/python/Lib/site-packages/pip/_internal/utils/compat.py +15 -9
- package/xll/python/Lib/site-packages/pip/_internal/utils/deprecation.py +6 -1
- package/xll/python/Lib/site-packages/pip/_internal/utils/filesystem.py +2 -2
- package/xll/python/Lib/site-packages/pip/_internal/utils/logging.py +11 -3
- package/xll/python/Lib/site-packages/pip/_internal/utils/misc.py +48 -4
- package/xll/python/Lib/site-packages/pip/_internal/utils/pylock.py +18 -2
- package/xll/python/Lib/site-packages/pip/_internal/utils/retry.py +2 -1
- package/xll/python/Lib/site-packages/pip/_internal/utils/subprocess.py +4 -3
- package/xll/python/Lib/site-packages/pip/_internal/utils/temp_dir.py +1 -2
- package/xll/python/Lib/site-packages/pip/_internal/utils/unpacking.py +30 -4
- package/xll/python/Lib/site-packages/pip/_internal/utils/urls.py +5 -2
- package/xll/python/Lib/site-packages/pip/_internal/utils/virtualenv.py +2 -36
- package/xll/python/Lib/site-packages/pip/_internal/vcs/git.py +8 -5
- package/xll/python/Lib/site-packages/pip/_internal/vcs/versioncontrol.py +1 -2
- package/xll/python/Lib/site-packages/pip/_internal/wheel_builder.py +5 -1
- package/xll/python/Lib/site-packages/pip/_vendor/bom.cdx.json +231 -0
- package/xll/python/Lib/site-packages/pip/_vendor/certifi/__init__.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/certifi/cacert.pem +0 -631
- package/xll/python/Lib/site-packages/pip/_vendor/distlib/__init__.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/distlib/compat.py +34 -64
- package/xll/python/Lib/site-packages/pip/_vendor/distlib/resources.py +28 -14
- package/xll/python/Lib/site-packages/pip/_vendor/distlib/scripts.py +7 -3
- package/xll/python/Lib/site-packages/pip/_vendor/distlib/util.py +48 -11
- package/xll/python/Lib/site-packages/pip/_vendor/idna/LICENSE.md +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/idna/__main__.py +6 -0
- package/xll/python/Lib/site-packages/pip/_vendor/idna/cli.py +128 -0
- package/xll/python/Lib/site-packages/pip/_vendor/idna/codec.py +50 -13
- package/xll/python/Lib/site-packages/pip/_vendor/idna/compat.py +26 -0
- package/xll/python/Lib/site-packages/pip/_vendor/idna/core.py +352 -141
- package/xll/python/Lib/site-packages/pip/_vendor/idna/idnadata.py +571 -2983
- package/xll/python/Lib/site-packages/pip/_vendor/idna/intranges.py +5 -7
- package/xll/python/Lib/site-packages/pip/_vendor/idna/package_data.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/idna/uts46data.py +16887 -8832
- package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/__init__.py +352 -66
- package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/__main__.py +11 -0
- package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/_xdg.py +171 -0
- package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/android.py +92 -41
- package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/api.py +213 -49
- package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/macos.py +128 -51
- package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/unix.py +176 -127
- package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/version.py +8 -18
- package/xll/python/Lib/site-packages/pip/_vendor/platformdirs/windows.py +185 -68
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/__init__.py +2 -2
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/__main__.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/console.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/filter.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/filters/__init__.py +10 -8
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/formatter.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/formatters/__init__.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/lexer.py +7 -5
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/lexers/__init__.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/lexers/_mapping.py +9 -8
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/lexers/python.py +35 -32
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/modeline.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/plugin.py +3 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/regexopt.py +13 -2
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/scanner.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/sphinxext.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/style.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/styles/__init__.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/token.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/unistring.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/pygments/util.py +2 -2
- package/xll/python/Lib/site-packages/pip/_vendor/requests/__init__.py +52 -16
- package/xll/python/Lib/site-packages/pip/_vendor/requests/__version__.py +2 -2
- package/xll/python/Lib/site-packages/pip/_vendor/requests/_internal_utils.py +2 -2
- package/xll/python/Lib/site-packages/pip/_vendor/requests/_types.py +183 -0
- package/xll/python/Lib/site-packages/pip/_vendor/requests/adapters.py +101 -50
- package/xll/python/Lib/site-packages/pip/_vendor/requests/api.py +31 -8
- package/xll/python/Lib/site-packages/pip/_vendor/requests/auth.py +80 -40
- package/xll/python/Lib/site-packages/pip/_vendor/requests/compat.py +9 -3
- package/xll/python/Lib/site-packages/pip/_vendor/requests/cookies.py +143 -79
- package/xll/python/Lib/site-packages/pip/_vendor/requests/exceptions.py +15 -5
- package/xll/python/Lib/site-packages/pip/_vendor/requests/help.py +13 -10
- package/xll/python/Lib/site-packages/pip/_vendor/requests/hooks.py +23 -9
- package/xll/python/Lib/site-packages/pip/_vendor/requests/models.py +265 -126
- package/xll/python/Lib/site-packages/pip/_vendor/requests/py.typed +0 -0
- package/xll/python/Lib/site-packages/pip/_vendor/requests/sessions.py +164 -78
- package/xll/python/Lib/site-packages/pip/_vendor/requests/status_codes.py +2 -2
- package/xll/python/Lib/site-packages/pip/_vendor/requests/structures.py +51 -20
- package/xll/python/Lib/site-packages/pip/_vendor/requests/utils.py +161 -89
- package/xll/python/Lib/site-packages/pip/_vendor/tomli/__init__.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/tomli/_parser.py +9 -4
- package/xll/python/Lib/site-packages/pip/_vendor/tomli/_re.py +13 -9
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/_base_connection.py +3 -1
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/_collections.py +0 -1
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/_version.py +8 -18
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/connection.py +4 -4
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/connectionpool.py +23 -10
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/contrib/emscripten/response.py +5 -1
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/contrib/pyopenssl.py +7 -8
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/contrib/socks.py +1 -1
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/exceptions.py +2 -2
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/fields.py +14 -14
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/poolmanager.py +8 -6
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/response.py +35 -22
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/util/retry.py +8 -0
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/util/ssl_.py +11 -61
- package/xll/python/Lib/site-packages/pip/_vendor/urllib3/util/ssl_match_hostname.py +5 -11
- package/xll/python/Lib/site-packages/pip/_vendor/vendor.txt +8 -8
- package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/METADATA +3 -2
- package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/RECORD +208 -188
- package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/AUTHORS.txt +20 -0
- package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/idna/LICENSE.md +1 -1
- package/xll/python/Lib/site-packages/pywin32-311.dist-info/RECORD +2 -2
- package/xll/python/Scripts/httpx.exe +0 -0
- package/xll/python/Scripts/idna.exe +0 -0
- package/xll/python/Scripts/pip.exe +0 -0
- package/xll/python/Scripts/pip3.13.exe +0 -0
- package/xll/python/Scripts/pip3.exe +0 -0
- package/xll/python/Scripts/pywin32_postinstall.exe +0 -0
- package/xll/python/Scripts/pywin32_testall.exe +0 -0
- package/dist/app/collab/awareness.d.ts +0 -32
- package/dist/app/collab/awareness.js +0 -52
- package/dist/app/collab/collab-client.d.ts +0 -37
- package/dist/app/collab/collab-client.js +0 -208
- package/dist/app/collab/collab-manager.d.ts +0 -91
- package/dist/app/collab/collab-manager.js +0 -218
- package/dist/app/collab/collab-sync.d.ts +0 -62
- package/dist/app/collab/collab-sync.js +0 -215
- package/dist/app/collab/index.d.ts +0 -9
- package/dist/app/collab/index.js +0 -6
- package/dist/app/collab/super-fight.d.ts +0 -90
- package/dist/app/collab/super-fight.js +0 -310
- package/dist/app/collab/sync-bridge.d.ts +0 -35
- package/dist/app/collab/sync-bridge.js +0 -109
- package/dist/app/collab/types.d.ts +0 -75
- package/dist/app/collab/types.js +0 -5
- package/dist/embedded-agent/ai-content.d.ts +0 -52
- package/dist/embedded-agent/ai-content.js +0 -101
- package/dist/embedded-agent/host-tools/shared/llm-stream.d.ts +0 -31
- package/dist/embedded-agent/host-tools/shared/llm-stream.js +0 -136
- package/dist/embedded-agent/model-call-orchestrator.d.ts +0 -22
- package/dist/embedded-agent/model-call-orchestrator.js +0 -22
- package/dist/embedded-agent/stream-errors.d.ts +0 -10
- package/dist/embedded-agent/stream-errors.js +0 -73
- package/dist/embedded-agent/stream-message-state.d.ts +0 -14
- package/dist/embedded-agent/stream-message-state.js +0 -271
- package/dist/embedded-agent/stream-sse.d.ts +0 -78
- package/dist/embedded-agent/stream-sse.js +0 -73
- package/dist/shell/interactive/collab-command.d.ts +0 -9
- package/dist/shell/interactive/collab-command.js +0 -115
- package/dist/shell/interactive/super-fight-ui.d.ts +0 -80
- package/dist/shell/interactive/super-fight-ui.js +0 -484
- package/dist/shell/status/collab-status.d.ts +0 -18
- package/dist/shell/status/collab-status.js +0 -46
- package/xll/python/Lib/site-packages/pip/_internal/build_env.py +0 -606
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/INSTALLER +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/REQUESTED +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/WHEEL +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/entry_points.txt +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/LICENSE.txt +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/certifi/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/distlib/LICENSE.txt +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/distro/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/msgpack/COPYING +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE.BSD +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/pkg_resources/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/platformdirs/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/pygments/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/requests/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/resolvelib/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/rich/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/tomli/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/tomli_w/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/truststore/LICENSE +0 -0
- /package/xll/python/Lib/site-packages/{pip-26.1.2.dist-info → pip-26.2.dist-info}/licenses/src/pip/_vendor/urllib3/LICENSE.txt +0 -0
|
@@ -1,30 +1,11 @@
|
|
|
1
|
-
/**
|
|
2
|
-
|
|
3
|
-
* Builds the request, parses the event stream, accumulates partial assistant
|
|
4
|
-
* state, and emits runtime stream events to the host.
|
|
5
|
-
*/
|
|
6
|
-
import { createAssistantMessageEventStream } from '../ai/event-stream.js';
|
|
7
|
-
import { modelStreamErrorDetailsFromThrown, networkErrorDetails, safeModelStreamErrorMessage, ShortcutXLHostAuthUnavailableError, ShortcutXLModelStreamEventKind, ShortcutXLModelStreamFetchStage, ShortcutXLModelStreamMessageRole, ShortcutXLModelStreamStopReason, ShortcutXLModelStreamThinkingType } from '../contracts/model-stream.js';
|
|
1
|
+
/** Provider-neutral request tracing helpers shared by embedded transports. */
|
|
2
|
+
import { ShortcutXLModelStreamMessageRole, ShortcutXLModelStreamThinkingType } from '../contracts/model-stream.js';
|
|
8
3
|
import { resolveShortcutSpeedForContext } from '../fast-mode.js';
|
|
9
|
-
import { buildHttpStreamError, computeRetryDelayMs, isRetryableStreamError, streamErrorDetails } from './stream-errors.js';
|
|
10
|
-
import { pushShortcutXLModelStreamEvent } from './stream-events.js';
|
|
11
|
-
import { createAssistantMessageSnapshot, createInitialAssistantMessage, processStreamEvent } from './stream-message-state.js';
|
|
12
|
-
import { readShortcutStream } from './stream-sse.js';
|
|
13
4
|
export function toShortcutEffortLevel(effort) {
|
|
14
5
|
if (effort === undefined || effort === 'off')
|
|
15
6
|
return undefined;
|
|
16
7
|
return effort === 'minimal' ? 'low' : effort;
|
|
17
8
|
}
|
|
18
|
-
const SHORTCUT_STREAM_MAX_RETRIES = 2;
|
|
19
|
-
const SHORTCUT_STREAM_RETRY_BASE_DELAY_MS = 500;
|
|
20
|
-
const SHORTCUT_STREAM_RETRY_MAX_DELAY_MS = 2_000;
|
|
21
|
-
/**
|
|
22
|
-
* Ceiling for *server-directed* delays (`Retry-After` / `retry_after_ms`).
|
|
23
|
-
* Kept separate from the client backoff cap: that bound exists to limit our
|
|
24
|
-
* own guesses, not to override an explicit hint from a recovering provider.
|
|
25
|
-
* Still capped so a misbehaving server can't pin clients for minutes.
|
|
26
|
-
*/
|
|
27
|
-
const SHORTCUT_STREAM_RETRY_SERVER_MAX_DELAY_MS = 30_000;
|
|
28
9
|
function createShortcutXLAgentBrowserStreamUuid() {
|
|
29
10
|
if (typeof globalThis.crypto?.randomUUID === 'function') {
|
|
30
11
|
return globalThis.crypto.randomUUID();
|
|
@@ -38,67 +19,10 @@ function isUuid(value) {
|
|
|
38
19
|
function resolveShortcutXLUserMessageId(value) {
|
|
39
20
|
return isUuid(value) ? value : createShortcutXLAgentBrowserStreamUuid();
|
|
40
21
|
}
|
|
41
|
-
function createShortcutXLAgentRequestHeaders(apiKey, clientPlatform, sessionId, request, workspaceContext) {
|
|
42
|
-
return {
|
|
43
|
-
'Content-Type': 'application/json',
|
|
44
|
-
'X-Agent-Runtime': 'shortcutxl_embedded',
|
|
45
|
-
'X-Client-Platform': clientPlatform,
|
|
46
|
-
'X-Request-Id': request.requestId,
|
|
47
|
-
...(request.agentMode ? { 'X-Agent-Mode': request.agentMode } : {}),
|
|
48
|
-
...(request.interactionMode ? { 'X-Interaction-Mode': request.interactionMode } : {}),
|
|
49
|
-
...(request.llmOperation ? { 'X-LLM-Operation': request.llmOperation } : {}),
|
|
50
|
-
...(sessionId ? { 'X-Session-Id': sessionId } : {}),
|
|
51
|
-
...(workspaceContext?.workspaceId ? { 'X-Workspace-Id': workspaceContext.workspaceId } : {}),
|
|
52
|
-
...(request.initialFileId ? { 'X-Initial-File-Id': request.initialFileId } : {}),
|
|
53
|
-
...(request.fileAttachmentIds?.length
|
|
54
|
-
? { 'X-File-Attachment-Ids': request.fileAttachmentIds.join(',') }
|
|
55
|
-
: {}),
|
|
56
|
-
...(workspaceContext?.workspaceType
|
|
57
|
-
? { 'X-Workspace-Type': workspaceContext.workspaceType }
|
|
58
|
-
: {}),
|
|
59
|
-
...(apiKey ? { Authorization: `Bearer ${apiKey}` } : {})
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
function getShortcutXLModelStreamUrl(baseUrl, streamBaseUrl) {
|
|
63
|
-
const requestBaseUrl = streamBaseUrl ?? baseUrl;
|
|
64
|
-
if (!requestBaseUrl) {
|
|
65
|
-
throw new Error('ShortcutXL runtime stream requires a baseUrl.');
|
|
66
|
-
}
|
|
67
|
-
return `${requestBaseUrl}/api/llm/stream`;
|
|
68
|
-
}
|
|
69
|
-
function resolveShortcutXLClientPlatform(clientPlatform) {
|
|
70
|
-
const platform = clientPlatform?.trim();
|
|
71
|
-
if (!platform) {
|
|
72
|
-
throw new Error('ShortcutXL runtime stream requires clientPlatform.');
|
|
73
|
-
}
|
|
74
|
-
return platform;
|
|
75
|
-
}
|
|
76
|
-
/**
|
|
77
|
-
* Sleep `ms`, exiting early on abort. Resolves (rather than rejects) on
|
|
78
|
-
* abort because the *next* fetch attempt sees the aborted signal and throws
|
|
79
|
-
* `AbortError`, which the retry loop already classifies as non-retryable.
|
|
80
|
-
* Keeping sleep non-throwing avoids a second abort code path.
|
|
81
|
-
*/
|
|
82
|
-
async function sleep(ms, signal) {
|
|
83
|
-
if (ms <= 0)
|
|
84
|
-
return;
|
|
85
|
-
if (signal?.aborted)
|
|
86
|
-
return;
|
|
87
|
-
await new Promise((resolve) => {
|
|
88
|
-
const timeout = setTimeout(resolve, ms);
|
|
89
|
-
signal?.addEventListener('abort', () => {
|
|
90
|
-
clearTimeout(timeout);
|
|
91
|
-
resolve();
|
|
92
|
-
}, { once: true });
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
22
|
function convertMessages(context) {
|
|
96
23
|
const messages = [];
|
|
97
24
|
if (context.systemPrompt) {
|
|
98
|
-
messages.push({
|
|
99
|
-
role: ShortcutXLModelStreamMessageRole.System,
|
|
100
|
-
content: context.systemPrompt
|
|
101
|
-
});
|
|
25
|
+
messages.push({ role: ShortcutXLModelStreamMessageRole.System, content: context.systemPrompt });
|
|
102
26
|
}
|
|
103
27
|
for (const message of context.messages) {
|
|
104
28
|
if (message.role === 'user') {
|
|
@@ -118,14 +42,11 @@ function convertMessages(context) {
|
|
|
118
42
|
let thinkingSignature;
|
|
119
43
|
const toolCalls = [];
|
|
120
44
|
for (const item of message.content) {
|
|
121
|
-
if (item.type === 'text')
|
|
45
|
+
if (item.type === 'text')
|
|
122
46
|
content += item.text;
|
|
123
|
-
continue;
|
|
124
|
-
}
|
|
125
47
|
if (item.type === 'thinking') {
|
|
126
48
|
thinking = item.thinking;
|
|
127
49
|
thinkingSignature = item.thinkingSignature;
|
|
128
|
-
continue;
|
|
129
50
|
}
|
|
130
51
|
if (item.type === 'toolCall') {
|
|
131
52
|
toolCalls.push({
|
|
@@ -155,53 +76,44 @@ function convertMessages(context) {
|
|
|
155
76
|
return messages;
|
|
156
77
|
}
|
|
157
78
|
function convertTools(context) {
|
|
158
|
-
if (!context.tools || context.tools.length === 0)
|
|
79
|
+
if (!context.tools || context.tools.length === 0)
|
|
159
80
|
return undefined;
|
|
160
|
-
}
|
|
161
81
|
return context.tools.map((tool) => ({
|
|
162
82
|
name: tool.name,
|
|
163
83
|
description: tool.description,
|
|
164
84
|
parameters: tool.parameters
|
|
165
85
|
}));
|
|
166
86
|
}
|
|
167
|
-
/** Convert owned AI
|
|
87
|
+
/** Convert owned AI context into the stable request-trace shape. */
|
|
168
88
|
export function createShortcutXLModelStreamRequest(options) {
|
|
169
|
-
|
|
170
|
-
// owned AI's stock options surface doesn't have it. Read defensively as an
|
|
171
|
-
// optional extension field.
|
|
172
|
-
const speed = options.options?.speed;
|
|
173
|
-
const initialFileId = options.options?.initialFileId;
|
|
174
|
-
const userMessageId = resolveShortcutXLUserMessageId(options.options?.userMessageId);
|
|
175
|
-
const fileAttachmentIds = options.options?.fileAttachmentIds;
|
|
176
|
-
const metadataOptions = options.options;
|
|
177
|
-
const messages = convertMessages(options.context);
|
|
89
|
+
const extendedOptions = options.options;
|
|
178
90
|
const tools = convertTools(options.context);
|
|
179
|
-
const resolvedSpeed = resolveShortcutSpeedForContext(options.model.id, speed, options.context);
|
|
180
91
|
return {
|
|
181
|
-
...(
|
|
92
|
+
...(extendedOptions?.agentMode ? { agentMode: extendedOptions.agentMode } : {}),
|
|
182
93
|
effortLevel: toShortcutEffortLevel(options.options?.reasoning),
|
|
183
|
-
...(fileAttachmentIds
|
|
184
|
-
|
|
185
|
-
...(metadataOptions?.interactionMode
|
|
186
|
-
? { interactionMode: metadataOptions.interactionMode }
|
|
94
|
+
...(extendedOptions?.fileAttachmentIds?.length
|
|
95
|
+
? { fileAttachmentIds: extendedOptions.fileAttachmentIds }
|
|
187
96
|
: {}),
|
|
188
|
-
...(
|
|
97
|
+
...(extendedOptions?.initialFileId ? { initialFileId: extendedOptions.initialFileId } : {}),
|
|
98
|
+
...(extendedOptions?.interactionMode
|
|
99
|
+
? { interactionMode: extendedOptions.interactionMode }
|
|
100
|
+
: {}),
|
|
101
|
+
...(extendedOptions?.llmOperation ? { llmOperation: extendedOptions.llmOperation } : {}),
|
|
189
102
|
maxTokens: options.options?.maxTokens,
|
|
190
|
-
messages,
|
|
103
|
+
messages: convertMessages(options.context),
|
|
191
104
|
model: options.model.id,
|
|
192
105
|
requestId: options.requestId,
|
|
193
|
-
speed:
|
|
106
|
+
speed: resolveShortcutSpeedForContext(options.model.id, extendedOptions?.speed, options.context),
|
|
194
107
|
thinkingType: options.options?.reasoning === undefined
|
|
195
108
|
? undefined
|
|
196
109
|
: options.options.reasoning === 'off'
|
|
197
110
|
? ShortcutXLModelStreamThinkingType.Off
|
|
198
111
|
: ShortcutXLModelStreamThinkingType.Adaptive,
|
|
199
112
|
tools,
|
|
200
|
-
userMessageId
|
|
113
|
+
userMessageId: resolveShortcutXLUserMessageId(extendedOptions?.userMessageId)
|
|
201
114
|
};
|
|
202
115
|
}
|
|
203
116
|
export function buildShortcutRuntimeRequestBody(request) {
|
|
204
|
-
const userMessageId = resolveShortcutXLUserMessageId(request.userMessageId);
|
|
205
117
|
return {
|
|
206
118
|
effort_level: request.effortLevel,
|
|
207
119
|
max_tokens: request.maxTokens,
|
|
@@ -220,441 +132,12 @@ export function buildShortcutRuntimeRequestBody(request) {
|
|
|
220
132
|
model: request.model,
|
|
221
133
|
...(request.speed !== undefined ? { speed: request.speed } : {}),
|
|
222
134
|
thinking_type: request.thinkingType,
|
|
223
|
-
user_message_id: userMessageId,
|
|
224
135
|
tools: request.tools?.map((tool) => ({
|
|
225
136
|
description: tool.description,
|
|
226
137
|
name: tool.name,
|
|
227
138
|
parameters: tool.parameters
|
|
228
|
-
}))
|
|
229
|
-
|
|
230
|
-
}
|
|
231
|
-
function emitModelRequestTrace(hook, request, body) {
|
|
232
|
-
if (!hook)
|
|
233
|
-
return;
|
|
234
|
-
try {
|
|
235
|
-
hook(request, body);
|
|
236
|
-
}
|
|
237
|
-
catch (error) {
|
|
238
|
-
console.warn('[ShortcutXL] model request trace hook failed:', error instanceof Error ? error.message : String(error));
|
|
239
|
-
}
|
|
240
|
-
}
|
|
241
|
-
function emitRuntimeStreamEvent(onEvent, event) {
|
|
242
|
-
onEvent(event);
|
|
243
|
-
}
|
|
244
|
-
function getRequestOrigin(baseUrl) {
|
|
245
|
-
if (!baseUrl)
|
|
246
|
-
return undefined;
|
|
247
|
-
try {
|
|
248
|
-
return new URL(baseUrl).origin;
|
|
249
|
-
}
|
|
250
|
-
catch {
|
|
251
|
-
return undefined;
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
function getUtf8ByteLength(value) {
|
|
255
|
-
if (typeof TextEncoder !== 'undefined') {
|
|
256
|
-
return new TextEncoder().encode(value).byteLength;
|
|
257
|
-
}
|
|
258
|
-
return value.length;
|
|
259
|
-
}
|
|
260
|
-
/**
|
|
261
|
-
* Drive a single fetch+stream attempt. Returns:
|
|
262
|
-
* - `success` if the stream completed with a terminal `done`/`error` event,
|
|
263
|
-
* - `retry` if the attempt failed in a retryable way and another attempt is allowed,
|
|
264
|
-
* - `failure` with the partial we accumulated so the caller can format the
|
|
265
|
-
* terminal Error event.
|
|
266
|
-
*
|
|
267
|
-
* Handles the in-attempt 401→refresh→retry-once dance internally; cross-attempt
|
|
268
|
-
* retries are the outer loop's job.
|
|
269
|
-
*/
|
|
270
|
-
async function runSingleStreamAttempt(deps) {
|
|
271
|
-
const { attempt, maxAttempts, request, body, startedWithBearer, sessionId, workspaceContext, options, fetchImpl, retryBaseDelayMs, retryMaxDelayMs, retryServerMaxDelayMs } = deps;
|
|
272
|
-
let apiKey = deps.apiKey;
|
|
273
|
-
const partial = createInitialAssistantMessage(request.model);
|
|
274
|
-
const toolCallArguments = new Map();
|
|
275
|
-
const thinkingText = new Map();
|
|
276
|
-
let hasEmittedVisibleEvent = false;
|
|
277
|
-
let hasEmittedTerminalEvent = false;
|
|
278
|
-
let startEmitted = false;
|
|
279
|
-
let fetchAnchorAt = Date.now();
|
|
280
|
-
let afterAuthRefresh = false;
|
|
281
|
-
let lastRequestHeaders;
|
|
282
|
-
let streamBytesReceived = 0;
|
|
283
|
-
let streamEventsReceived = 0;
|
|
284
|
-
let firstStreamByteAt;
|
|
285
|
-
let lastStreamByteAt;
|
|
286
|
-
let firstStreamEventAt;
|
|
287
|
-
let lastStreamEventAt;
|
|
288
|
-
const requestOrigin = getRequestOrigin(options.streamBaseUrl ?? options.baseUrl);
|
|
289
|
-
const requestBodyJson = JSON.stringify(body);
|
|
290
|
-
const requestBodyBytes = getUtf8ByteLength(requestBodyJson);
|
|
291
|
-
const emitFetchTrace = (stage, error, status, retry) => {
|
|
292
|
-
if (!options.onFetchTrace)
|
|
293
|
-
return;
|
|
294
|
-
const aborted = options.signal?.aborted === true || (error instanceof Error && error.name === 'AbortError');
|
|
295
|
-
const errorName = error instanceof Error ? error.name : undefined;
|
|
296
|
-
const errorMessage = error instanceof Error ? error.message : error !== undefined ? String(error) : '';
|
|
297
|
-
const details = streamErrorDetails(error);
|
|
298
|
-
try {
|
|
299
|
-
options.onFetchTrace({
|
|
300
|
-
stage,
|
|
301
|
-
requestId: request.requestId,
|
|
302
|
-
...(requestOrigin !== undefined ? { requestOrigin } : {}),
|
|
303
|
-
requestBodyBytes,
|
|
304
|
-
...(request.agentMode !== undefined ? { agentMode: request.agentMode } : {}),
|
|
305
|
-
...(request.interactionMode !== undefined
|
|
306
|
-
? { interactionMode: request.interactionMode }
|
|
307
|
-
: {}),
|
|
308
|
-
...(request.llmOperation !== undefined ? { llmOperation: request.llmOperation } : {}),
|
|
309
|
-
model: request.model,
|
|
310
|
-
...(request.effortLevel !== undefined ? { effortLevel: request.effortLevel } : {}),
|
|
311
|
-
...(request.speed !== undefined ? { speed: request.speed } : {}),
|
|
312
|
-
...(request.thinkingType !== undefined ? { thinkingType: request.thinkingType } : {}),
|
|
313
|
-
...(sessionId !== undefined ? { sessionId } : {}),
|
|
314
|
-
...(request.userMessageId !== undefined ? { userMessageId: request.userMessageId } : {}),
|
|
315
|
-
messageCount: request.messages.length,
|
|
316
|
-
toolCount: request.tools?.length ?? 0,
|
|
317
|
-
clientPlatform: options.clientPlatform,
|
|
318
|
-
fetchContext: 'model_stream_worker',
|
|
319
|
-
...(lastRequestHeaders !== undefined
|
|
320
|
-
? {
|
|
321
|
-
requestHeaderNames: Object.keys(lastRequestHeaders).sort(),
|
|
322
|
-
hasAuthorizationHeader: lastRequestHeaders.Authorization !== undefined,
|
|
323
|
-
hasSessionHeader: lastRequestHeaders['X-Session-Id'] !== undefined,
|
|
324
|
-
hasWorkspaceHeader: lastRequestHeaders['X-Workspace-Id'] !== undefined
|
|
325
|
-
}
|
|
326
|
-
: {}),
|
|
327
|
-
attempt,
|
|
328
|
-
maxAttempts,
|
|
329
|
-
willRetry: retry.willRetry,
|
|
330
|
-
...(retry.delayMs !== undefined ? { retryDelayMs: retry.delayMs } : {}),
|
|
331
|
-
timeToErrorMs: Date.now() - fetchAnchorAt,
|
|
332
|
-
...(stage === ShortcutXLModelStreamFetchStage.ResponseBody
|
|
333
|
-
? {
|
|
334
|
-
streamBytesReceived,
|
|
335
|
-
streamEventsReceived,
|
|
336
|
-
...(firstStreamByteAt !== undefined
|
|
337
|
-
? { timeToFirstByteMs: firstStreamByteAt - fetchAnchorAt }
|
|
338
|
-
: {}),
|
|
339
|
-
...(firstStreamEventAt !== undefined
|
|
340
|
-
? { timeToFirstEventMs: firstStreamEventAt - fetchAnchorAt }
|
|
341
|
-
: {}),
|
|
342
|
-
...(lastStreamByteAt !== undefined
|
|
343
|
-
? { timeSinceLastByteMs: Date.now() - lastStreamByteAt }
|
|
344
|
-
: {}),
|
|
345
|
-
...(lastStreamEventAt !== undefined
|
|
346
|
-
? { timeSinceLastEventMs: Date.now() - lastStreamEventAt }
|
|
347
|
-
: {})
|
|
348
|
-
}
|
|
349
|
-
: {}),
|
|
350
|
-
...(errorName !== undefined ? { errorName } : {}),
|
|
351
|
-
errorMessage,
|
|
352
|
-
...(details?.code !== undefined ? { code: details.code } : {}),
|
|
353
|
-
...(details?.providerErrorType !== undefined
|
|
354
|
-
? { providerErrorType: details.providerErrorType }
|
|
355
|
-
: {}),
|
|
356
|
-
...(details?.failureStage !== undefined ? { failureStage: details.failureStage } : {}),
|
|
357
|
-
...(details?.requestedModel !== undefined
|
|
358
|
-
? { requestedModel: details.requestedModel }
|
|
359
|
-
: {}),
|
|
360
|
-
...(details?.credentialMode !== undefined
|
|
361
|
-
? { credentialMode: details.credentialMode }
|
|
362
|
-
: {}),
|
|
363
|
-
...(status !== undefined ? { status } : {}),
|
|
364
|
-
...(details?.retryable !== undefined ? { retryable: details.retryable } : {}),
|
|
365
|
-
...(details?.retryAfterMs !== undefined ? { retryAfterMs: details.retryAfterMs } : {}),
|
|
366
|
-
aborted,
|
|
367
|
-
afterAuthRefresh
|
|
368
|
-
});
|
|
369
|
-
}
|
|
370
|
-
catch {
|
|
371
|
-
// Telemetry must never break the stream. Swallow.
|
|
372
|
-
}
|
|
373
|
-
};
|
|
374
|
-
const executeFetch = (token) => {
|
|
375
|
-
const headers = createShortcutXLAgentRequestHeaders(token, options.clientPlatform, sessionId, request, workspaceContext);
|
|
376
|
-
lastRequestHeaders = headers;
|
|
377
|
-
return fetchImpl(getShortcutXLModelStreamUrl(options.baseUrl, options.streamBaseUrl), {
|
|
378
|
-
method: 'POST',
|
|
379
|
-
credentials: 'include',
|
|
380
|
-
headers,
|
|
381
|
-
body: requestBodyJson,
|
|
382
|
-
signal: options.signal
|
|
383
|
-
});
|
|
384
|
-
};
|
|
385
|
-
const classifyFailure = (stage, error, status) => {
|
|
386
|
-
const aborted = options.signal?.aborted === true || (error instanceof Error && error.name === 'AbortError');
|
|
387
|
-
const canRetry = stage === ShortcutXLModelStreamFetchStage.BeforeResponse &&
|
|
388
|
-
!aborted &&
|
|
389
|
-
!hasEmittedVisibleEvent &&
|
|
390
|
-
attempt < maxAttempts &&
|
|
391
|
-
isRetryableStreamError(error);
|
|
392
|
-
const delayMs = canRetry
|
|
393
|
-
? computeRetryDelayMs(error, attempt, retryBaseDelayMs, retryMaxDelayMs, retryServerMaxDelayMs)
|
|
394
|
-
: undefined;
|
|
395
|
-
emitFetchTrace(stage, error, status, { willRetry: canRetry, delayMs });
|
|
396
|
-
if (canRetry) {
|
|
397
|
-
return { kind: 'retry', delayMs: delayMs ?? 0, partial };
|
|
398
|
-
}
|
|
399
|
-
return { kind: 'failure', partial, error, stage };
|
|
400
|
-
};
|
|
401
|
-
const eventState = {
|
|
402
|
-
partial,
|
|
403
|
-
toolCallArguments,
|
|
404
|
-
thinkingText,
|
|
405
|
-
emitStartIfNeeded() {
|
|
406
|
-
if (startEmitted)
|
|
407
|
-
return;
|
|
408
|
-
startEmitted = true;
|
|
409
|
-
hasEmittedVisibleEvent = true;
|
|
410
|
-
emitRuntimeStreamEvent(options.onEvent, {
|
|
411
|
-
kind: ShortcutXLModelStreamEventKind.Start,
|
|
412
|
-
partial: createAssistantMessageSnapshot(partial)
|
|
413
|
-
});
|
|
414
|
-
},
|
|
415
|
-
markTerminal() {
|
|
416
|
-
hasEmittedTerminalEvent = true;
|
|
417
|
-
}
|
|
418
|
-
};
|
|
419
|
-
let response;
|
|
420
|
-
try {
|
|
421
|
-
response = await executeFetch(apiKey);
|
|
422
|
-
}
|
|
423
|
-
catch (error) {
|
|
424
|
-
return classifyFailure(ShortcutXLModelStreamFetchStage.BeforeResponse, error, undefined);
|
|
425
|
-
}
|
|
426
|
-
if (response.status === 401 && options.refreshAccessToken && !options.signal?.aborted) {
|
|
427
|
-
await response.text().catch(() => undefined);
|
|
428
|
-
try {
|
|
429
|
-
apiKey = await options.refreshAccessToken();
|
|
430
|
-
}
|
|
431
|
-
catch (error) {
|
|
432
|
-
// A host throwing from refreshAccessToken is a hard auth failure — no
|
|
433
|
-
// point retrying with the same flow. Convert to a non-retryable failure
|
|
434
|
-
// so the outer loop emits a terminal Error rather than an unhandled
|
|
435
|
-
// rejection.
|
|
436
|
-
return {
|
|
437
|
-
kind: 'failure',
|
|
438
|
-
partial,
|
|
439
|
-
error,
|
|
440
|
-
stage: ShortcutXLModelStreamFetchStage.NonOkResponse
|
|
441
|
-
};
|
|
442
|
-
}
|
|
443
|
-
deps.onApiKeyRefreshed(apiKey);
|
|
444
|
-
// Host swallows refresh errors and replies undefined to avoid hanging the
|
|
445
|
-
// worker on AuthTokenResponse. If this request needs a bearer (not a
|
|
446
|
-
// cookie-auth flow) and the refresh returned none, surface a terminal
|
|
447
|
-
// failure so the UI sees a clear sign-in prompt instead of a raw 401.
|
|
448
|
-
if (startedWithBearer && !apiKey) {
|
|
449
|
-
return {
|
|
450
|
-
kind: 'failure',
|
|
451
|
-
partial,
|
|
452
|
-
error: new ShortcutXLHostAuthUnavailableError(),
|
|
453
|
-
stage: ShortcutXLModelStreamFetchStage.NonOkResponse
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
afterAuthRefresh = true;
|
|
457
|
-
try {
|
|
458
|
-
response = await executeFetch(apiKey);
|
|
459
|
-
}
|
|
460
|
-
catch (error) {
|
|
461
|
-
return classifyFailure(ShortcutXLModelStreamFetchStage.BeforeResponse, error, undefined);
|
|
462
|
-
}
|
|
463
|
-
}
|
|
464
|
-
if (!response.ok) {
|
|
465
|
-
let httpError;
|
|
466
|
-
try {
|
|
467
|
-
httpError = await buildHttpStreamError(response);
|
|
468
|
-
}
|
|
469
|
-
catch (error) {
|
|
470
|
-
// Body read failed (network reset mid-error-body, etc.). Treat as a
|
|
471
|
-
// non-OK response with an unknown body so we still classify, emit the
|
|
472
|
-
// trace, and avoid an unhandled rejection.
|
|
473
|
-
return classifyFailure(ShortcutXLModelStreamFetchStage.NonOkResponse, error, response.status);
|
|
474
|
-
}
|
|
475
|
-
return classifyFailure(ShortcutXLModelStreamFetchStage.NonOkResponse, httpError, response.status);
|
|
476
|
-
}
|
|
477
|
-
// Re-anchor so `response_body` traces report time spent *reading*, not the
|
|
478
|
-
// (already-recorded) time spent connecting.
|
|
479
|
-
fetchAnchorAt = Date.now();
|
|
480
|
-
try {
|
|
481
|
-
await readShortcutStream(response, (event) => processStreamEvent(event, eventState, (streamEvent) => emitRuntimeStreamEvent(options.onEvent, streamEvent), () => !hasEmittedVisibleEvent && attempt < maxAttempts), options.streamIdleTimeoutMs, {
|
|
482
|
-
onBytes(length) {
|
|
483
|
-
const now = Date.now();
|
|
484
|
-
streamBytesReceived += length;
|
|
485
|
-
firstStreamByteAt ??= now;
|
|
486
|
-
lastStreamByteAt = now;
|
|
487
|
-
},
|
|
488
|
-
onEvent() {
|
|
489
|
-
const now = Date.now();
|
|
490
|
-
streamEventsReceived += 1;
|
|
491
|
-
firstStreamEventAt ??= now;
|
|
492
|
-
lastStreamEventAt = now;
|
|
493
|
-
}
|
|
494
|
-
});
|
|
495
|
-
if (!hasEmittedTerminalEvent) {
|
|
496
|
-
throw new Error('ShortcutXL runtime stream closed before done.');
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
catch (error) {
|
|
500
|
-
return classifyFailure(ShortcutXLModelStreamFetchStage.ResponseBody, error, undefined);
|
|
501
|
-
}
|
|
502
|
-
return { kind: 'success' };
|
|
503
|
-
}
|
|
504
|
-
/**
|
|
505
|
-
* Drive one stream request to completion. Emits Start/Delta/.../Done|Error
|
|
506
|
-
* events through `onEvent`. Always emits a terminal Error event on abort or
|
|
507
|
-
* failure so consumers never need to time out.
|
|
508
|
-
*/
|
|
509
|
-
export async function runShortcutXLModelStreamRequest(request, options) {
|
|
510
|
-
const fetchImpl = options.fetchImpl ?? fetch;
|
|
511
|
-
const clientPlatform = resolveShortcutXLClientPlatform(options.clientPlatform);
|
|
512
|
-
const resolvedOptions = {
|
|
513
|
-
...options,
|
|
514
|
-
clientPlatform
|
|
515
|
-
};
|
|
516
|
-
const body = buildShortcutRuntimeRequestBody(request);
|
|
517
|
-
const maxRetries = Math.max(0, options.maxStreamRetries ?? SHORTCUT_STREAM_MAX_RETRIES);
|
|
518
|
-
const maxAttempts = maxRetries + 1;
|
|
519
|
-
const retryBaseDelayMs = options.streamRetryBaseDelayMs ?? SHORTCUT_STREAM_RETRY_BASE_DELAY_MS;
|
|
520
|
-
const retryMaxDelayMs = options.streamRetryMaxDelayMs ?? SHORTCUT_STREAM_RETRY_MAX_DELAY_MS;
|
|
521
|
-
const retryServerMaxDelayMs = options.streamRetryServerMaxDelayMs ?? SHORTCUT_STREAM_RETRY_SERVER_MAX_DELAY_MS;
|
|
522
|
-
emitModelRequestTrace(resolvedOptions.onRequest, request, body);
|
|
523
|
-
// `outcome.partial` from the last attempt; used to format the terminal Error
|
|
524
|
-
// event if every attempt fails. Carries whatever content the failing attempt
|
|
525
|
-
// accumulated before failing (typically empty for transport errors, but may
|
|
526
|
-
// contain a chunk of text before a peer-closed mid-stream).
|
|
527
|
-
let lastAttemptPartial = createInitialAssistantMessage(request.model);
|
|
528
|
-
let lastError;
|
|
529
|
-
let lastFailureStage;
|
|
530
|
-
try {
|
|
531
|
-
const sessionId = resolvedOptions.getSessionId?.();
|
|
532
|
-
const workspaceContext = resolvedOptions.getWorkspaceContext?.();
|
|
533
|
-
let apiKey = resolvedOptions.apiKey ?? (await resolvedOptions.getAccessToken?.());
|
|
534
|
-
// Track whether this request started authenticated by a bearer token (vs.
|
|
535
|
-
// cookie auth, where apiKey is intentionally undefined). On a 401 retry
|
|
536
|
-
// we use this to distinguish "refresh returned no token" (real auth
|
|
537
|
-
// failure for bearer flows) from "no bearer needed" (cookie flow).
|
|
538
|
-
const startedWithBearer = apiKey !== undefined;
|
|
539
|
-
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
|
|
540
|
-
const outcome = await runSingleStreamAttempt({
|
|
541
|
-
attempt,
|
|
542
|
-
maxAttempts,
|
|
543
|
-
request,
|
|
544
|
-
body,
|
|
545
|
-
apiKey,
|
|
546
|
-
startedWithBearer,
|
|
547
|
-
sessionId,
|
|
548
|
-
workspaceContext,
|
|
549
|
-
options: resolvedOptions,
|
|
550
|
-
fetchImpl,
|
|
551
|
-
retryBaseDelayMs,
|
|
552
|
-
retryMaxDelayMs,
|
|
553
|
-
retryServerMaxDelayMs,
|
|
554
|
-
onApiKeyRefreshed: (refreshed) => {
|
|
555
|
-
apiKey = refreshed;
|
|
556
|
-
}
|
|
557
|
-
});
|
|
558
|
-
if (outcome.kind === 'success')
|
|
559
|
-
return;
|
|
560
|
-
lastAttemptPartial = outcome.partial;
|
|
561
|
-
if (outcome.kind === 'failure') {
|
|
562
|
-
lastError = outcome.error;
|
|
563
|
-
lastFailureStage = outcome.stage;
|
|
564
|
-
break;
|
|
565
|
-
}
|
|
566
|
-
await sleep(outcome.delayMs, options.signal);
|
|
567
|
-
}
|
|
568
|
-
}
|
|
569
|
-
catch (error) {
|
|
570
|
-
// Belt-and-suspenders: catch anything the attempt loop didn't already
|
|
571
|
-
// convert into a `failure` outcome — host hooks (`getAccessToken`,
|
|
572
|
-
// `getSessionId`, `getWorkspaceContext`, `refreshAccessToken`) that
|
|
573
|
-
// throw, `buildHttpStreamError` reading a poisoned response body, or
|
|
574
|
-
// anything else that escapes. Without this, the caller (which fires
|
|
575
|
-
// `runShortcutXLModelStreamRequest` as a void promise) would see an
|
|
576
|
-
// unhandled rejection and stream consumers would wait forever.
|
|
577
|
-
lastError = error;
|
|
578
|
-
}
|
|
579
|
-
// Format terminal Error event from the last attempt's partial. Treat both
|
|
580
|
-
// an externally aborted signal and a thrown AbortError as a user
|
|
581
|
-
// cancellation rather than a stream error so the caller can react.
|
|
582
|
-
const aborted = options.signal?.aborted === true ||
|
|
583
|
-
(lastError instanceof Error && lastError.name === 'AbortError');
|
|
584
|
-
lastAttemptPartial.stopReason = aborted
|
|
585
|
-
? ShortcutXLModelStreamStopReason.Aborted
|
|
586
|
-
: ShortcutXLModelStreamStopReason.Error;
|
|
587
|
-
const structuredDetails = modelStreamErrorDetailsFromThrown(lastError);
|
|
588
|
-
if (structuredDetails) {
|
|
589
|
-
lastAttemptPartial.errorMessage = safeModelStreamErrorMessage(structuredDetails);
|
|
590
|
-
lastAttemptPartial.errorDetails = structuredDetails;
|
|
591
|
-
}
|
|
592
|
-
else if (!aborted) {
|
|
593
|
-
lastAttemptPartial.errorMessage =
|
|
594
|
-
lastError instanceof Error ? lastError.message : String(lastError);
|
|
595
|
-
// The fetch itself rejected before any HTTP response (DNS failure,
|
|
596
|
-
// offline, captive portal, WKWebView "Load failed", etc.) or the SSE
|
|
597
|
-
// reader hit the idle timeout. The stream retry loop only retries before a
|
|
598
|
-
// response starts; `response_body` retryable metadata means the outer
|
|
599
|
-
// session recovery layer may retry the turn as `server_error`, not that
|
|
600
|
-
// this layer will retry the same response.
|
|
601
|
-
lastAttemptPartial.errorDetails =
|
|
602
|
-
lastFailureStage === ShortcutXLModelStreamFetchStage.BeforeResponse ||
|
|
603
|
-
lastFailureStage === ShortcutXLModelStreamFetchStage.ResponseBody
|
|
604
|
-
? networkErrorDetails(lastFailureStage)
|
|
605
|
-
: {
|
|
606
|
-
providerErrorType: 'network',
|
|
607
|
-
retryable: false,
|
|
608
|
-
...(lastFailureStage !== undefined ? { transportFailureStage: lastFailureStage } : {})
|
|
609
|
-
};
|
|
610
|
-
}
|
|
611
|
-
else {
|
|
612
|
-
lastAttemptPartial.errorMessage =
|
|
613
|
-
lastError instanceof Error ? lastError.message : String(lastError);
|
|
614
|
-
}
|
|
615
|
-
emitRuntimeStreamEvent(options.onEvent, {
|
|
616
|
-
kind: ShortcutXLModelStreamEventKind.Error,
|
|
617
|
-
error: createAssistantMessageSnapshot(lastAttemptPartial),
|
|
618
|
-
partial: createAssistantMessageSnapshot(lastAttemptPartial),
|
|
619
|
-
reason: aborted
|
|
620
|
-
? ShortcutXLModelStreamStopReason.Aborted
|
|
621
|
-
: ShortcutXLModelStreamStopReason.Error
|
|
622
|
-
});
|
|
623
|
-
}
|
|
624
|
-
/**
|
|
625
|
-
* Build a owned AI-compatible `streamFn` bound to the given host. The returned
|
|
626
|
-
* function fires off one request per call and pushes events into a fresh
|
|
627
|
-
* assistant-message event stream.
|
|
628
|
-
*/
|
|
629
|
-
export function createShortcutXLModelStream(hostOptions) {
|
|
630
|
-
return function shortcutBrowserStream(model, context, options) {
|
|
631
|
-
const stream = createAssistantMessageEventStream();
|
|
632
|
-
const request = createShortcutXLModelStreamRequest({
|
|
633
|
-
context,
|
|
634
|
-
model,
|
|
635
|
-
options,
|
|
636
|
-
requestId: createShortcutXLAgentBrowserStreamUuid()
|
|
637
|
-
});
|
|
638
|
-
void runShortcutXLModelStreamRequest(request, {
|
|
639
|
-
...hostOptions,
|
|
640
|
-
apiKey: options?.apiKey,
|
|
641
|
-
onEvent(event) {
|
|
642
|
-
pushShortcutXLModelStreamEvent(stream, event);
|
|
643
|
-
},
|
|
644
|
-
signal: options?.signal
|
|
645
|
-
}).catch((error) => {
|
|
646
|
-
const partial = createInitialAssistantMessage(request.model);
|
|
647
|
-
partial.stopReason = ShortcutXLModelStreamStopReason.Error;
|
|
648
|
-
partial.errorMessage = error instanceof Error ? error.message : String(error);
|
|
649
|
-
partial.errorDetails = networkErrorDetails(ShortcutXLModelStreamFetchStage.BeforeResponse);
|
|
650
|
-
pushShortcutXLModelStreamEvent(stream, {
|
|
651
|
-
kind: ShortcutXLModelStreamEventKind.Error,
|
|
652
|
-
error: createAssistantMessageSnapshot(partial),
|
|
653
|
-
partial: createAssistantMessageSnapshot(partial),
|
|
654
|
-
reason: ShortcutXLModelStreamStopReason.Error
|
|
655
|
-
});
|
|
656
|
-
});
|
|
657
|
-
return stream;
|
|
139
|
+
})),
|
|
140
|
+
user_message_id: resolveShortcutXLUserMessageId(request.userMessageId)
|
|
658
141
|
};
|
|
659
142
|
}
|
|
660
143
|
//# sourceMappingURL=stream.js.map
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Follow-up suggestion runner for the embedded (web) runtime.
|
|
3
3
|
*
|
|
4
4
|
* Owns prompt assembly + response parsing in the runtime. The actual
|
|
5
|
-
*
|
|
5
|
+
* provider-native API v2 call is dispatched through `bridge.request(...)`
|
|
6
6
|
* and handled by the client side — same pattern as `exa_web_search` etc. The
|
|
7
7
|
* runtime never touches `fetch`, `baseUrl`, or `apiKey`.
|
|
8
8
|
*
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Follow-up suggestion runner for the embedded (web) runtime.
|
|
3
3
|
*
|
|
4
4
|
* Owns prompt assembly + response parsing in the runtime. The actual
|
|
5
|
-
*
|
|
5
|
+
* provider-native API v2 call is dispatched through `bridge.request(...)`
|
|
6
6
|
* and handled by the client side — same pattern as `exa_web_search` etc. The
|
|
7
7
|
* runtime never touches `fetch`, `baseUrl`, or `apiKey`.
|
|
8
8
|
*
|
|
@@ -55,6 +55,12 @@ export declare const ShortcutXLModelStreamTraceKind: {
|
|
|
55
55
|
readonly RequestReceived: "requestReceived";
|
|
56
56
|
};
|
|
57
57
|
export type ShortcutXLModelStreamTraceKind = (typeof ShortcutXLModelStreamTraceKind)[keyof typeof ShortcutXLModelStreamTraceKind];
|
|
58
|
+
/** Best-effort confirmation that an initial submit crossed the worker boundary. */
|
|
59
|
+
export interface ShortcutXLInitialSubmitReceipt {
|
|
60
|
+
readonly commandId: string;
|
|
61
|
+
readonly receivedAt: number;
|
|
62
|
+
readonly userMessageId: string;
|
|
63
|
+
}
|
|
58
64
|
/** One observability entry emitted while bridging requests across the port. */
|
|
59
65
|
export interface ShortcutXLModelStreamTraceEntry {
|
|
60
66
|
readonly eventKind?: ShortcutXLModelStreamEvent['kind'];
|
|
@@ -82,6 +88,7 @@ export interface ShortcutXLModelStreamBridgeMetrics {
|
|
|
82
88
|
export interface CreateEmbeddedAgentPortClientOptions {
|
|
83
89
|
hostToolExecutor: HostToolExecutor;
|
|
84
90
|
modelStreamRequestHandler?: ShortcutXLModelStreamRequestHandler;
|
|
91
|
+
onInitialSubmitReceived?: (receipt: ShortcutXLInitialSubmitReceipt) => void;
|
|
85
92
|
onModelStreamTrace?: (entry: ShortcutXLModelStreamTraceEntry) => void;
|
|
86
93
|
registry: ToolRegistry;
|
|
87
94
|
}
|