@clawpump/claw-agent 0.1.5 → 0.1.6
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/agent/.dockerignore +67 -0
- package/agent/.envrc +1 -1
- package/agent/.gitattributes +8 -0
- package/agent/AGENTS.md +216 -4
- package/agent/CONTRIBUTING.md +46 -8
- package/agent/Dockerfile +78 -35
- package/agent/MANIFEST.in +2 -0
- package/agent/README.md +12 -5
- package/agent/README.ur-pk.md +261 -0
- package/agent/README.zh-CN.md +11 -8
- package/agent/SECURITY.md +5 -4
- package/agent/acp_adapter/provenance.py +127 -0
- package/agent/acp_adapter/server.py +112 -5
- package/agent/acp_adapter/session.py +1 -6
- package/agent/acp_registry/agent.json +2 -2
- package/agent/agent/account_usage.py +313 -1
- package/agent/agent/agent_init.py +140 -37
- package/agent/agent/agent_runtime_helpers.py +342 -83
- package/agent/agent/anthropic_adapter.py +320 -33
- package/agent/agent/auxiliary_client.py +525 -105
- package/agent/agent/background_review.py +157 -19
- package/agent/agent/bedrock_adapter.py +71 -6
- package/agent/agent/billing_view.py +295 -0
- package/agent/agent/chat_completion_helpers.py +229 -4
- package/agent/agent/codex_responses_adapter.py +86 -10
- package/agent/agent/codex_runtime.py +153 -1
- package/agent/agent/coding_context.py +738 -0
- package/agent/agent/context_compressor.py +392 -44
- package/agent/agent/context_references.py +34 -1
- package/agent/agent/conversation_compression.py +159 -22
- package/agent/agent/conversation_loop.py +643 -908
- package/agent/agent/copilot_acp_client.py +4 -11
- package/agent/agent/credential_pool.py +5 -3
- package/agent/agent/credits_tracker.py +794 -0
- package/agent/agent/curator.py +91 -18
- package/agent/agent/curator_backup.py +26 -10
- package/agent/agent/display.py +42 -1
- package/agent/agent/error_classifier.py +52 -3
- package/agent/agent/errors.py +3 -0
- package/agent/agent/file_safety.py +0 -17
- package/agent/agent/gemini_native_adapter.py +31 -1
- package/agent/agent/i18n.py +48 -4
- package/agent/agent/image_gen_provider.py +74 -5
- package/agent/agent/image_routing.py +29 -0
- package/agent/agent/insights.py +8 -17
- package/agent/agent/lsp/install.py +3 -0
- package/agent/agent/memory_manager.py +326 -31
- package/agent/agent/message_content.py +50 -0
- package/agent/agent/model_metadata.py +214 -3
- package/agent/agent/moonshot_schema.py +8 -1
- package/agent/agent/onboarding.py +60 -0
- package/agent/agent/prompt_builder.py +327 -37
- package/agent/agent/redact.py +1 -0
- package/agent/agent/runtime_cwd.py +34 -5
- package/agent/agent/secret_scope.py +205 -0
- package/agent/agent/secret_sources/bitwarden.py +34 -2
- package/agent/agent/skill_commands.py +90 -1
- package/agent/agent/skill_preprocessing.py +1 -0
- package/agent/agent/skill_utils.py +209 -36
- package/agent/agent/ssl_guard.py +94 -0
- package/agent/agent/system_prompt.py +133 -5
- package/agent/agent/tool_executor.py +496 -70
- package/agent/agent/transports/anthropic.py +83 -21
- package/agent/agent/transports/chat_completions.py +94 -5
- package/agent/agent/transports/codex.py +67 -2
- package/agent/agent/transports/codex_app_server.py +1 -0
- package/agent/agent/transports/codex_app_server_session.py +30 -0
- package/agent/agent/transports/types.py +12 -0
- package/agent/agent/turn_context.py +408 -0
- package/agent/agent/turn_finalizer.py +428 -0
- package/agent/agent/turn_retry_state.py +68 -0
- package/agent/agent/usage_pricing.py +3 -0
- package/agent/apps/bootstrap-installer/package.json +6 -5
- package/agent/apps/bootstrap-installer/src/routes/failure.tsx +12 -5
- package/agent/apps/bootstrap-installer/src/routes/progress.tsx +1 -3
- package/agent/apps/bootstrap-installer/src/store.ts +3 -2
- package/agent/apps/bootstrap-installer/src-tauri/src/bootstrap.rs +172 -7
- package/agent/apps/bootstrap-installer/src-tauri/src/events.rs +14 -1
- package/agent/apps/bootstrap-installer/src-tauri/src/paths.rs +29 -0
- package/agent/apps/bootstrap-installer/src-tauri/src/powershell.rs +93 -3
- package/agent/apps/bootstrap-installer/src-tauri/src/update.rs +695 -39
- package/agent/apps/bootstrap-installer/tsconfig.json +3 -4
- package/agent/apps/desktop/DESIGN.md +167 -0
- package/agent/apps/desktop/README.md +20 -16
- package/agent/apps/desktop/assets/icon.icns +0 -0
- package/agent/apps/desktop/assets/icon.ico +0 -0
- package/agent/apps/desktop/assets/icon.png +0 -0
- package/agent/apps/desktop/electron/backend-env.cjs +112 -0
- package/agent/apps/desktop/electron/backend-env.test.cjs +111 -0
- package/agent/apps/desktop/electron/backend-probes.test.cjs +3 -1
- package/agent/apps/desktop/electron/backend-ready.cjs +66 -0
- package/agent/apps/desktop/electron/bootstrap-platform.cjs +52 -0
- package/agent/apps/desktop/electron/bootstrap-platform.test.cjs +59 -1
- package/agent/apps/desktop/electron/bootstrap-runner.cjs +176 -38
- package/agent/apps/desktop/electron/bootstrap-runner.test.cjs +112 -1
- package/agent/apps/desktop/electron/connection-config.cjs +288 -0
- package/agent/apps/desktop/electron/connection-config.test.cjs +396 -0
- package/agent/apps/desktop/electron/dashboard-token.cjs +99 -0
- package/agent/apps/desktop/electron/dashboard-token.test.cjs +142 -0
- package/agent/apps/desktop/electron/desktop-uninstall.cjs +232 -0
- package/agent/apps/desktop/electron/desktop-uninstall.test.cjs +246 -0
- package/agent/apps/desktop/electron/entitlements.mac.inherit.plist +2 -0
- package/agent/apps/desktop/electron/fs-read-dir.cjs +109 -0
- package/agent/apps/desktop/electron/fs-read-dir.test.cjs +364 -0
- package/agent/apps/desktop/electron/gateway-ws-probe.cjs +188 -0
- package/agent/apps/desktop/electron/gateway-ws-probe.test.cjs +122 -0
- package/agent/apps/desktop/electron/git-root.cjs +54 -0
- package/agent/apps/desktop/electron/git-root.test.cjs +40 -0
- package/agent/apps/desktop/electron/git-worktrees.cjs +174 -0
- package/agent/apps/desktop/electron/hardening.cjs +123 -28
- package/agent/apps/desktop/electron/hardening.test.cjs +163 -0
- package/agent/apps/desktop/electron/main.cjs +3121 -331
- package/agent/apps/desktop/electron/oauth-net-request.cjs +20 -0
- package/agent/apps/desktop/electron/oauth-net-request.test.cjs +34 -0
- package/agent/apps/desktop/electron/preload.cjs +52 -2
- package/agent/apps/desktop/electron/session-windows.cjs +124 -0
- package/agent/apps/desktop/electron/session-windows.test.cjs +199 -0
- package/agent/apps/desktop/electron/update-rebuild.cjs +29 -0
- package/agent/apps/desktop/electron/update-rebuild.test.cjs +55 -0
- package/agent/apps/desktop/electron/update-remote.cjs +56 -0
- package/agent/apps/desktop/electron/update-remote.test.cjs +78 -0
- package/agent/apps/desktop/electron/vscode-marketplace.cjs +331 -0
- package/agent/apps/desktop/electron/vscode-marketplace.test.cjs +113 -0
- package/agent/apps/desktop/electron/windows-child-process.test.cjs +57 -0
- package/agent/apps/desktop/electron/windows-user-env.cjs +76 -0
- package/agent/apps/desktop/electron/windows-user-env.test.cjs +90 -0
- package/agent/apps/desktop/electron/workspace-cwd.cjs +38 -0
- package/agent/apps/desktop/electron/workspace-cwd.test.cjs +45 -0
- package/agent/apps/desktop/eslint.config.mjs +0 -3
- package/agent/apps/desktop/index.html +27 -2
- package/agent/apps/desktop/package.json +31 -11
- package/agent/apps/desktop/pr-assets/session-source-folders.png +0 -0
- package/agent/apps/desktop/public/apple-touch-icon.png +0 -0
- package/agent/apps/desktop/public/nous-girl.jpg +0 -0
- package/agent/apps/desktop/scripts/assert-dist-built.cjs +70 -0
- package/agent/apps/desktop/scripts/assert-dist-built.test.cjs +84 -0
- package/agent/apps/desktop/scripts/before-pack.cjs +78 -0
- package/agent/apps/desktop/scripts/before-pack.test.cjs +53 -0
- package/agent/apps/desktop/scripts/diag-scroll-reset.mjs +229 -0
- package/agent/apps/desktop/scripts/patch-electron-builder-mac-binary.cjs +64 -0
- package/agent/apps/desktop/scripts/run-electron-builder.cjs +57 -0
- package/agent/apps/desktop/src/app/agents/index.tsx +53 -45
- package/agent/apps/desktop/src/app/artifacts/index.tsx +102 -83
- package/agent/apps/desktop/src/app/chat/chat-drop-overlay.tsx +29 -8
- package/agent/apps/desktop/src/app/chat/chat-swap-overlay.tsx +47 -0
- package/agent/apps/desktop/src/app/chat/composer/attachments.tsx +81 -45
- package/agent/apps/desktop/src/app/chat/composer/completion-drawer.tsx +13 -24
- package/agent/apps/desktop/src/app/chat/composer/context-menu.tsx +138 -88
- package/agent/apps/desktop/src/app/chat/composer/controls.tsx +138 -90
- package/agent/apps/desktop/src/app/chat/composer/enter-submit-dom-race.test.tsx +218 -0
- package/agent/apps/desktop/src/app/chat/composer/focus.ts +32 -0
- package/agent/apps/desktop/src/app/chat/composer/help-hint.tsx +38 -25
- package/agent/apps/desktop/src/app/chat/composer/hooks/use-live-completion-adapter.ts +7 -0
- package/agent/apps/desktop/src/app/chat/composer/hooks/use-mic-recorder.ts +22 -12
- package/agent/apps/desktop/src/app/chat/composer/hooks/use-slash-completions.ts +142 -14
- package/agent/apps/desktop/src/app/chat/composer/hooks/use-voice-conversation.ts +14 -11
- package/agent/apps/desktop/src/app/chat/composer/hooks/use-voice-recorder.ts +9 -6
- package/agent/apps/desktop/src/app/chat/composer/ime-composition-dom-repro.test.tsx +108 -0
- package/agent/apps/desktop/src/app/chat/composer/index.tsx +930 -180
- package/agent/apps/desktop/src/app/chat/composer/inline-refs.ts +136 -32
- package/agent/apps/desktop/src/app/chat/composer/model-pill.tsx +86 -0
- package/agent/apps/desktop/src/app/chat/composer/queue-panel.tsx +54 -75
- package/agent/apps/desktop/src/app/chat/composer/rich-editor.test.ts +117 -1
- package/agent/apps/desktop/src/app/chat/composer/rich-editor.ts +117 -6
- package/agent/apps/desktop/src/app/chat/composer/slash-nav-dom-repro.test.tsx +186 -0
- package/agent/apps/desktop/src/app/chat/composer/status-stack/index.tsx +202 -0
- package/agent/apps/desktop/src/app/chat/composer/status-stack/status-row.tsx +155 -0
- package/agent/apps/desktop/src/app/chat/composer/text-utils.test.ts +104 -0
- package/agent/apps/desktop/src/app/chat/composer/text-utils.ts +37 -9
- package/agent/apps/desktop/src/app/chat/composer/trigger-popover.test.tsx +50 -0
- package/agent/apps/desktop/src/app/chat/composer/trigger-popover.tsx +105 -40
- package/agent/apps/desktop/src/app/chat/composer/types.ts +5 -0
- package/agent/apps/desktop/src/app/chat/composer/url-dialog.tsx +11 -15
- package/agent/apps/desktop/src/app/chat/composer/voice-activity.tsx +8 -4
- package/agent/apps/desktop/src/app/chat/hooks/use-composer-actions.test.ts +57 -0
- package/agent/apps/desktop/src/app/chat/hooks/use-composer-actions.ts +70 -16
- package/agent/apps/desktop/src/app/chat/hooks/use-file-drop-zone.ts +52 -16
- package/agent/apps/desktop/src/app/chat/index.tsx +234 -81
- package/agent/apps/desktop/src/app/chat/perf-probe.tsx +69 -21
- package/agent/apps/desktop/src/app/chat/right-rail/preview-console.tsx +44 -40
- package/agent/apps/desktop/src/app/chat/right-rail/preview-file.tsx +71 -25
- package/agent/apps/desktop/src/app/chat/right-rail/preview-pane.test.tsx +40 -1
- package/agent/apps/desktop/src/app/chat/right-rail/preview-pane.tsx +55 -53
- package/agent/apps/desktop/src/app/chat/right-rail/preview.tsx +35 -17
- package/agent/apps/desktop/src/app/chat/scroll-to-bottom-button.test.tsx +67 -0
- package/agent/apps/desktop/src/app/chat/scroll-to-bottom-button.tsx +74 -0
- package/agent/apps/desktop/src/app/chat/sidebar/cron-jobs-section.tsx +356 -0
- package/agent/apps/desktop/src/app/chat/sidebar/index.tsx +1189 -364
- package/agent/apps/desktop/src/app/chat/sidebar/load-more-row.tsx +30 -0
- package/agent/apps/desktop/src/app/chat/sidebar/order.test.ts +21 -0
- package/agent/apps/desktop/src/app/chat/sidebar/order.ts +17 -0
- package/agent/apps/desktop/src/app/chat/sidebar/profile-switcher.tsx +524 -0
- package/agent/apps/desktop/src/app/chat/sidebar/session-actions-menu.tsx +80 -45
- package/agent/apps/desktop/src/app/chat/sidebar/session-row.tsx +120 -25
- package/agent/apps/desktop/src/app/chat/sidebar/virtual-session-list.tsx +7 -13
- package/agent/apps/desktop/src/app/chat/sidebar/workspace-groups.test.ts +149 -0
- package/agent/apps/desktop/src/app/chat/sidebar/workspace-groups.ts +326 -0
- package/agent/apps/desktop/src/app/chat/thread-loading.ts +7 -2
- package/agent/apps/desktop/src/app/command-center/index.tsx +320 -581
- package/agent/apps/desktop/src/app/command-palette/index.tsx +681 -0
- package/agent/apps/desktop/src/app/command-palette/marketplace-theme-page.tsx +157 -0
- package/agent/apps/desktop/src/app/cron/index.tsx +392 -324
- package/agent/apps/desktop/src/app/cron/job-state.ts +29 -0
- package/agent/apps/desktop/src/app/desktop-controller.tsx +618 -123
- package/agent/apps/desktop/src/app/floating-hud.ts +22 -0
- package/agent/apps/desktop/src/app/gateway/hooks/use-gateway-boot.test.tsx +265 -0
- package/agent/apps/desktop/src/app/gateway/hooks/use-gateway-boot.ts +260 -14
- package/agent/apps/desktop/src/app/gateway/hooks/use-gateway-request.ts +48 -4
- package/agent/apps/desktop/src/app/hooks/use-keybinds.ts +270 -0
- package/agent/apps/desktop/src/app/hooks/use-refresh-hotkey.ts +45 -0
- package/agent/apps/desktop/src/app/layout-constants.ts +19 -0
- package/agent/apps/desktop/src/app/messaging/index.tsx +136 -241
- package/agent/apps/desktop/src/app/messaging/platform-icon.tsx +95 -0
- package/agent/apps/desktop/src/app/model-visibility-overlay.tsx +31 -0
- package/agent/apps/desktop/src/app/overlays/overlay-search-input.tsx +18 -62
- package/agent/apps/desktop/src/app/overlays/overlay-split-layout.tsx +59 -7
- package/agent/apps/desktop/src/app/overlays/overlay-view.tsx +9 -5
- package/agent/apps/desktop/src/app/page-search-shell.tsx +42 -20
- package/agent/apps/desktop/src/app/profiles/create-profile-dialog.tsx +165 -0
- package/agent/apps/desktop/src/app/profiles/delete-profile-dialog.tsx +65 -0
- package/agent/apps/desktop/src/app/profiles/index.tsx +174 -199
- package/agent/apps/desktop/src/app/profiles/rename-profile-dialog.tsx +125 -0
- package/agent/apps/desktop/src/app/right-sidebar/files/dnd-manager.ts +27 -0
- package/agent/apps/desktop/src/app/right-sidebar/files/ipc.test.ts +100 -0
- package/agent/apps/desktop/src/app/right-sidebar/files/ipc.ts +12 -18
- package/agent/apps/desktop/src/app/right-sidebar/files/remote-picker.tsx +177 -0
- package/agent/apps/desktop/src/app/right-sidebar/files/tree.tsx +35 -21
- package/agent/apps/desktop/src/app/right-sidebar/files/use-project-tree.test.ts +75 -3
- package/agent/apps/desktop/src/app/right-sidebar/files/use-project-tree.ts +152 -5
- package/agent/apps/desktop/src/app/right-sidebar/index.test.tsx +75 -0
- package/agent/apps/desktop/src/app/right-sidebar/index.tsx +166 -129
- package/agent/apps/desktop/src/app/right-sidebar/store.ts +19 -4
- package/agent/apps/desktop/src/app/right-sidebar/terminal/buffer.ts +65 -0
- package/agent/apps/desktop/src/app/right-sidebar/terminal/index.tsx +29 -34
- package/agent/apps/desktop/src/app/right-sidebar/terminal/persistent.tsx +18 -6
- package/agent/apps/desktop/src/app/right-sidebar/terminal/selection.ts +93 -32
- package/agent/apps/desktop/src/app/right-sidebar/terminal/use-terminal-session.ts +381 -119
- package/agent/apps/desktop/src/app/routes.ts +9 -0
- package/agent/apps/desktop/src/app/session/hooks/use-cwd-actions.ts +17 -7
- package/agent/apps/desktop/src/app/session/hooks/use-message-stream.ts +365 -47
- package/agent/apps/desktop/src/app/session/hooks/use-model-controls.test.tsx +198 -0
- package/agent/apps/desktop/src/app/session/hooks/use-model-controls.ts +70 -34
- package/agent/apps/desktop/src/app/session/hooks/use-prompt-actions.test.tsx +1061 -0
- package/agent/apps/desktop/src/app/session/hooks/use-prompt-actions.ts +1143 -165
- package/agent/apps/desktop/src/app/session/hooks/use-route-resume.test.tsx +341 -2
- package/agent/apps/desktop/src/app/session/hooks/use-route-resume.ts +176 -5
- package/agent/apps/desktop/src/app/session/hooks/use-session-actions.test.tsx +259 -0
- package/agent/apps/desktop/src/app/session/hooks/use-session-actions.ts +452 -149
- package/agent/apps/desktop/src/app/session/hooks/use-session-state-cache.test.tsx +327 -0
- package/agent/apps/desktop/src/app/session/hooks/use-session-state-cache.ts +133 -4
- package/agent/apps/desktop/src/app/session-picker-overlay.tsx +32 -0
- package/agent/apps/desktop/src/app/session-switcher.tsx +107 -0
- package/agent/apps/desktop/src/app/settings/about-settings.tsx +45 -36
- package/agent/apps/desktop/src/app/settings/appearance-settings.tsx +243 -162
- package/agent/apps/desktop/src/app/settings/config-settings.tsx +86 -66
- package/agent/apps/desktop/src/app/settings/constants.ts +459 -122
- package/agent/apps/desktop/src/app/settings/credential-key-ui.tsx +373 -0
- package/agent/apps/desktop/src/app/settings/env-credentials.tsx +198 -0
- package/agent/apps/desktop/src/app/settings/env-var-actions-menu.tsx +136 -0
- package/agent/apps/desktop/src/app/settings/field-copy.ts +56 -0
- package/agent/apps/desktop/src/app/settings/gateway-settings.tsx +385 -72
- package/agent/apps/desktop/src/app/settings/helpers.test.ts +156 -1
- package/agent/apps/desktop/src/app/settings/helpers.ts +30 -2
- package/agent/apps/desktop/src/app/settings/index.tsx +118 -84
- package/agent/apps/desktop/src/app/settings/keys-settings.tsx +62 -419
- package/agent/apps/desktop/src/app/settings/mcp-settings.tsx +65 -60
- package/agent/apps/desktop/src/app/settings/model-settings.test.tsx +129 -5
- package/agent/apps/desktop/src/app/settings/model-settings.tsx +370 -65
- package/agent/apps/desktop/src/app/settings/notifications-settings.tsx +150 -0
- package/agent/apps/desktop/src/app/settings/primitives.tsx +5 -11
- package/agent/apps/desktop/src/app/settings/provider-config-panel.test.tsx +142 -0
- package/agent/apps/desktop/src/app/settings/provider-config-panel.tsx +182 -0
- package/agent/apps/desktop/src/app/settings/providers-settings.test.tsx +171 -0
- package/agent/apps/desktop/src/app/settings/providers-settings.tsx +471 -0
- package/agent/apps/desktop/src/app/settings/sessions-settings.tsx +183 -71
- package/agent/apps/desktop/src/app/settings/toolset-config-panel.test.tsx +135 -1
- package/agent/apps/desktop/src/app/settings/toolset-config-panel.tsx +180 -57
- package/agent/apps/desktop/src/app/settings/types.ts +9 -6
- package/agent/apps/desktop/src/app/settings/uninstall-section.tsx +185 -0
- package/agent/apps/desktop/src/app/settings/use-deep-link-highlight.ts +60 -0
- package/agent/apps/desktop/src/app/shell/app-shell.tsx +59 -13
- package/agent/apps/desktop/src/app/shell/gateway-menu-panel.tsx +37 -32
- package/agent/apps/desktop/src/app/shell/hooks/use-overlay-routing.ts +6 -3
- package/agent/apps/desktop/src/app/shell/hooks/use-statusbar-items.tsx +212 -53
- package/agent/apps/desktop/src/app/shell/keybind-panel.tsx +215 -0
- package/agent/apps/desktop/src/app/shell/model-edit-submenu.test.tsx +84 -0
- package/agent/apps/desktop/src/app/shell/model-edit-submenu.tsx +244 -0
- package/agent/apps/desktop/src/app/shell/model-menu-panel.tsx +392 -0
- package/agent/apps/desktop/src/app/shell/statusbar-controls.tsx +23 -33
- package/agent/apps/desktop/src/app/shell/titlebar-controls.tsx +79 -95
- package/agent/apps/desktop/src/app/shell/titlebar.ts +8 -2
- package/agent/apps/desktop/src/app/skills/index.test.tsx +11 -0
- package/agent/apps/desktop/src/app/skills/index.tsx +79 -64
- package/agent/apps/desktop/src/app/types.ts +85 -0
- package/agent/apps/desktop/src/app/updates-overlay.tsx +110 -105
- package/agent/apps/desktop/src/components/assistant-ui/ansi-text.tsx +34 -0
- package/agent/apps/desktop/src/components/assistant-ui/block-direction.test.tsx +129 -0
- package/agent/apps/desktop/src/components/assistant-ui/clarify-tool.tsx +102 -81
- package/agent/apps/desktop/src/components/assistant-ui/directive-text.tsx +92 -15
- package/agent/apps/desktop/src/components/assistant-ui/markdown-text.test.ts +38 -0
- package/agent/apps/desktop/src/components/assistant-ui/markdown-text.tsx +304 -45
- package/agent/apps/desktop/src/components/assistant-ui/message-render-boundary.test.tsx +80 -0
- package/agent/apps/desktop/src/components/assistant-ui/message-render-boundary.tsx +48 -0
- package/agent/apps/desktop/src/components/assistant-ui/streaming.test.tsx +142 -90
- package/agent/apps/desktop/src/components/assistant-ui/thread-list.tsx +337 -0
- package/agent/apps/desktop/src/components/assistant-ui/thread.tsx +667 -190
- package/agent/apps/desktop/src/components/assistant-ui/tool-approval-group.test.tsx +299 -0
- package/agent/apps/desktop/src/components/assistant-ui/tool-approval.test.tsx +133 -0
- package/agent/apps/desktop/src/components/assistant-ui/tool-approval.tsx +239 -0
- package/agent/apps/desktop/src/components/assistant-ui/tool-fallback-model.test.ts +31 -0
- package/agent/apps/desktop/src/components/assistant-ui/tool-fallback-model.ts +152 -134
- package/agent/apps/desktop/src/components/assistant-ui/tool-fallback.tsx +142 -150
- package/agent/apps/desktop/src/components/assistant-ui/tooltip-icon-button.tsx +14 -12
- package/agent/apps/desktop/src/components/assistant-ui/user-message-edit.test.tsx +141 -0
- package/agent/apps/desktop/src/components/assistant-ui/user-message-text.tsx +152 -0
- package/agent/apps/desktop/src/components/boot-failure-overlay.tsx +150 -33
- package/agent/apps/desktop/src/components/boot-failure-reauth.test.ts +100 -0
- package/agent/apps/desktop/src/components/boot-failure-reauth.ts +81 -0
- package/agent/apps/desktop/src/components/brand-mark.tsx +19 -0
- package/agent/apps/desktop/src/components/chat/code-card.tsx +1 -1
- package/agent/apps/desktop/src/components/chat/composer-dock.ts +31 -0
- package/agent/apps/desktop/src/components/chat/diff-lines.tsx +1 -1
- package/agent/apps/desktop/src/components/chat/disclosure-row.tsx +13 -3
- package/agent/apps/desktop/src/components/chat/expandable-block.tsx +52 -0
- package/agent/apps/desktop/src/components/chat/generated-image-result.tsx +174 -0
- package/agent/apps/desktop/src/components/chat/image-generation-placeholder.tsx +70 -37
- package/agent/apps/desktop/src/components/chat/intro.tsx +8 -7
- package/agent/apps/desktop/src/components/chat/preview-attachment.tsx +4 -2
- package/agent/apps/desktop/src/components/chat/shiki-highlighter.test.ts +37 -0
- package/agent/apps/desktop/src/components/chat/shiki-highlighter.tsx +96 -22
- package/agent/apps/desktop/src/components/chat/status-row.tsx +70 -0
- package/agent/apps/desktop/src/components/chat/status-section.tsx +42 -0
- package/agent/apps/desktop/src/components/chat/terminal-output.tsx +54 -0
- package/agent/apps/desktop/src/components/chat/zoomable-image.tsx +70 -109
- package/agent/apps/desktop/src/components/desktop-install-overlay.tsx +154 -84
- package/agent/apps/desktop/src/components/desktop-onboarding-overlay.test.tsx +38 -8
- package/agent/apps/desktop/src/components/desktop-onboarding-overlay.tsx +789 -233
- package/agent/apps/desktop/src/components/error-boundary.tsx +77 -0
- package/agent/apps/desktop/src/components/gateway-connecting-overlay.test.tsx +144 -0
- package/agent/apps/desktop/src/components/gateway-connecting-overlay.tsx +7 -1
- package/agent/apps/desktop/src/components/haptics-provider.tsx +24 -0
- package/agent/apps/desktop/src/components/language-switcher.test.tsx +53 -0
- package/agent/apps/desktop/src/components/language-switcher.tsx +175 -0
- package/agent/apps/desktop/src/components/model-picker.tsx +42 -40
- package/agent/apps/desktop/src/components/model-visibility-dialog.tsx +166 -0
- package/agent/apps/desktop/src/components/notifications.tsx +48 -27
- package/agent/apps/desktop/src/components/pane-shell/index.ts +1 -1
- package/agent/apps/desktop/src/components/pane-shell/pane-shell.tsx +146 -9
- package/agent/apps/desktop/src/components/prompt-overlays.tsx +234 -0
- package/agent/apps/desktop/src/components/session-picker.tsx +108 -0
- package/agent/apps/desktop/src/components/ui/action-status.tsx +25 -0
- package/agent/apps/desktop/src/components/ui/badge.tsx +35 -0
- package/agent/apps/desktop/src/components/ui/button.tsx +37 -13
- package/agent/apps/desktop/src/components/ui/confirm-dialog.tsx +109 -0
- package/agent/apps/desktop/src/components/ui/control.ts +25 -0
- package/agent/apps/desktop/src/components/ui/copy-button.test.tsx +36 -0
- package/agent/apps/desktop/src/components/ui/copy-button.tsx +38 -27
- package/agent/apps/desktop/src/components/ui/dialog.tsx +39 -11
- package/agent/apps/desktop/src/components/ui/dropdown-menu.tsx +98 -24
- package/agent/apps/desktop/src/components/ui/error-state.tsx +50 -0
- package/agent/apps/desktop/src/components/ui/fade-text.tsx +9 -2
- package/agent/apps/desktop/src/components/ui/{braille-spinner.tsx → glyph-spinner.tsx} +15 -13
- package/agent/apps/desktop/src/components/ui/input.tsx +5 -2
- package/agent/apps/desktop/src/components/ui/kbd.tsx +83 -12
- package/agent/apps/desktop/src/components/ui/log-view.tsx +19 -0
- package/agent/apps/desktop/src/components/ui/pagination.tsx +12 -5
- package/agent/apps/desktop/src/components/ui/popover.tsx +44 -0
- package/agent/apps/desktop/src/components/ui/search-field.tsx +80 -0
- package/agent/apps/desktop/src/components/ui/segmented-control.tsx +51 -0
- package/agent/apps/desktop/src/components/ui/select.tsx +10 -3
- package/agent/apps/desktop/src/components/ui/sheet.tsx +8 -2
- package/agent/apps/desktop/src/components/ui/sidebar.tsx +18 -25
- package/agent/apps/desktop/src/components/ui/switch.tsx +38 -15
- package/agent/apps/desktop/src/components/ui/textarea.tsx +4 -11
- package/agent/apps/desktop/src/components/ui/tool-icon.tsx +65 -0
- package/agent/apps/desktop/src/components/ui/tooltip.tsx +31 -4
- package/agent/apps/desktop/src/fonts/JetBrainsMono-Bold.woff2 +0 -0
- package/agent/apps/desktop/src/fonts/JetBrainsMono-Italic.woff2 +0 -0
- package/agent/apps/desktop/src/fonts/JetBrainsMono-Regular.woff2 +0 -0
- package/agent/apps/desktop/src/global.d.ts +181 -4
- package/agent/apps/desktop/src/hermes.test.ts +60 -0
- package/agent/apps/desktop/src/hermes.ts +190 -13
- package/agent/apps/desktop/src/hooks/use-image-download.ts +85 -0
- package/agent/apps/desktop/src/hooks/use-resize-observer.ts +13 -4
- package/agent/apps/desktop/src/hooks/use-worktree-info.ts +68 -0
- package/agent/apps/desktop/src/i18n/catalog.ts +12 -0
- package/agent/apps/desktop/src/i18n/context.test.tsx +232 -0
- package/agent/apps/desktop/src/i18n/context.tsx +183 -0
- package/agent/apps/desktop/src/i18n/define-locale.ts +41 -0
- package/agent/apps/desktop/src/i18n/en.ts +1921 -0
- package/agent/apps/desktop/src/i18n/index.ts +20 -0
- package/agent/apps/desktop/src/i18n/ja.ts +2053 -0
- package/agent/apps/desktop/src/i18n/languages.test.ts +43 -0
- package/agent/apps/desktop/src/i18n/languages.ts +86 -0
- package/agent/apps/desktop/src/i18n/runtime.test.ts +75 -0
- package/agent/apps/desktop/src/i18n/runtime.ts +53 -0
- package/agent/apps/desktop/src/i18n/types.ts +1559 -0
- package/agent/apps/desktop/src/i18n/zh-hant.ts +1992 -0
- package/agent/apps/desktop/src/i18n/zh.ts +2099 -0
- package/agent/apps/desktop/src/lib/ansi.test.ts +123 -0
- package/agent/apps/desktop/src/lib/ansi.ts +186 -0
- package/agent/apps/desktop/src/lib/chat-messages.test.ts +79 -0
- package/agent/apps/desktop/src/lib/chat-messages.ts +68 -29
- package/agent/apps/desktop/src/lib/chat-runtime.test.ts +65 -1
- package/agent/apps/desktop/src/lib/chat-runtime.ts +39 -3
- package/agent/apps/desktop/src/lib/completion-sound.ts +519 -0
- package/agent/apps/desktop/src/lib/desktop-fs.test.ts +116 -0
- package/agent/apps/desktop/src/lib/desktop-fs.ts +113 -0
- package/agent/apps/desktop/src/lib/desktop-slash-commands.test.ts +89 -6
- package/agent/apps/desktop/src/lib/desktop-slash-commands.ts +270 -131
- package/agent/apps/desktop/src/lib/external-link.test.tsx +27 -0
- package/agent/apps/desktop/src/lib/external-link.tsx +9 -2
- package/agent/apps/desktop/src/lib/gateway-events.test.ts +27 -0
- package/agent/apps/desktop/src/lib/gateway-events.ts +16 -0
- package/agent/apps/desktop/src/lib/gateway-ws-url.test.ts +78 -0
- package/agent/apps/desktop/src/lib/gateway-ws-url.ts +91 -0
- package/agent/apps/desktop/src/lib/generated-images.test.ts +97 -0
- package/agent/apps/desktop/src/lib/generated-images.ts +116 -0
- package/agent/apps/desktop/src/lib/haptics.ts +17 -0
- package/agent/apps/desktop/src/lib/icons.ts +10 -2
- package/agent/apps/desktop/src/lib/keybinds/actions.ts +137 -0
- package/agent/apps/desktop/src/lib/keybinds/combo.test.ts +86 -0
- package/agent/apps/desktop/src/lib/keybinds/combo.ts +195 -0
- package/agent/apps/desktop/src/lib/local-preview.ts +23 -2
- package/agent/apps/desktop/src/lib/markdown-preprocess.ts +20 -7
- package/agent/apps/desktop/src/lib/media.remote.test.ts +90 -0
- package/agent/apps/desktop/src/lib/media.ts +40 -1
- package/agent/apps/desktop/src/lib/model-status-label.test.ts +59 -0
- package/agent/apps/desktop/src/lib/model-status-label.ts +122 -0
- package/agent/apps/desktop/src/lib/mutable-ref.ts +6 -0
- package/agent/apps/desktop/src/lib/profile-color.ts +58 -0
- package/agent/apps/desktop/src/lib/query-client.ts +13 -0
- package/agent/apps/desktop/src/lib/remend-tail.test.ts +105 -0
- package/agent/apps/desktop/src/lib/remend-tail.ts +108 -0
- package/agent/apps/desktop/src/lib/session-export.ts +6 -3
- package/agent/apps/desktop/src/lib/session-ids.test.ts +44 -0
- package/agent/apps/desktop/src/lib/session-ids.ts +26 -0
- package/agent/apps/desktop/src/lib/session-search.test.ts +66 -0
- package/agent/apps/desktop/src/lib/session-search.ts +21 -0
- package/agent/apps/desktop/src/lib/session-source.ts +126 -0
- package/agent/apps/desktop/src/lib/storage.test.ts +25 -0
- package/agent/apps/desktop/src/lib/storage.ts +35 -1
- package/agent/apps/desktop/src/lib/todos.test.ts +46 -1
- package/agent/apps/desktop/src/lib/todos.ts +37 -0
- package/agent/apps/desktop/src/lib/tool-result-summary.ts +5 -1
- package/agent/apps/desktop/src/lib/update-copy.test.ts +38 -0
- package/agent/apps/desktop/src/lib/update-copy.ts +44 -0
- package/agent/apps/desktop/src/lib/use-enter-animation.ts +2 -2
- package/agent/apps/desktop/src/lib/yolo-session.ts +50 -0
- package/agent/apps/desktop/src/main.tsx +19 -19
- package/agent/apps/desktop/src/store/boot.ts +4 -3
- package/agent/apps/desktop/src/store/clarify.test.ts +81 -0
- package/agent/apps/desktop/src/store/clarify.ts +50 -13
- package/agent/apps/desktop/src/store/command-palette.ts +20 -0
- package/agent/apps/desktop/src/store/compaction.test.ts +53 -0
- package/agent/apps/desktop/src/store/compaction.ts +38 -0
- package/agent/apps/desktop/src/store/completion-sound.ts +32 -0
- package/agent/apps/desktop/src/store/composer-input-history.test.ts +147 -0
- package/agent/apps/desktop/src/store/composer-input-history.ts +158 -0
- package/agent/apps/desktop/src/store/composer-queue.test.ts +68 -0
- package/agent/apps/desktop/src/store/composer-queue.ts +76 -0
- package/agent/apps/desktop/src/store/composer-status.test.ts +99 -0
- package/agent/apps/desktop/src/store/composer-status.ts +277 -0
- package/agent/apps/desktop/src/store/composer.test.ts +106 -0
- package/agent/apps/desktop/src/store/composer.ts +116 -0
- package/agent/apps/desktop/src/store/cron.ts +19 -0
- package/agent/apps/desktop/src/store/gateway.ts +280 -6
- package/agent/apps/desktop/src/store/keybinds.ts +143 -0
- package/agent/apps/desktop/src/store/layout.ts +107 -9
- package/agent/apps/desktop/src/store/model-presets.test.ts +51 -0
- package/agent/apps/desktop/src/store/model-presets.ts +86 -0
- package/agent/apps/desktop/src/store/model-visibility.test.ts +99 -0
- package/agent/apps/desktop/src/store/model-visibility.ts +161 -0
- package/agent/apps/desktop/src/store/native-notifications.test.ts +192 -0
- package/agent/apps/desktop/src/store/native-notifications.ts +203 -0
- package/agent/apps/desktop/src/store/notifications.ts +10 -7
- package/agent/apps/desktop/src/store/onboarding.test.ts +271 -1
- package/agent/apps/desktop/src/store/onboarding.ts +268 -38
- package/agent/apps/desktop/src/store/preview.ts +10 -1
- package/agent/apps/desktop/src/store/profile.test.ts +89 -0
- package/agent/apps/desktop/src/store/profile.ts +395 -0
- package/agent/apps/desktop/src/store/prompts.test.ts +127 -0
- package/agent/apps/desktop/src/store/prompts.ts +117 -0
- package/agent/apps/desktop/src/store/session-switcher.test.ts +115 -0
- package/agent/apps/desktop/src/store/session-switcher.ts +128 -0
- package/agent/apps/desktop/src/store/session-sync.ts +25 -0
- package/agent/apps/desktop/src/store/session.test.ts +268 -2
- package/agent/apps/desktop/src/store/session.ts +392 -18
- package/agent/apps/desktop/src/store/subagents.ts +3 -0
- package/agent/apps/desktop/src/store/system-actions.ts +48 -0
- package/agent/apps/desktop/src/store/thread-scroll.ts +58 -5
- package/agent/apps/desktop/src/store/todos.test.ts +47 -0
- package/agent/apps/desktop/src/store/todos.ts +64 -0
- package/agent/apps/desktop/src/store/tool-dismiss.ts +45 -0
- package/agent/apps/desktop/src/store/translucency.ts +38 -0
- package/agent/apps/desktop/src/store/updates.test.ts +187 -2
- package/agent/apps/desktop/src/store/updates.ts +268 -18
- package/agent/apps/desktop/src/store/windows.test.ts +143 -0
- package/agent/apps/desktop/src/store/windows.ts +115 -0
- package/agent/apps/desktop/src/styles.css +510 -119
- package/agent/apps/desktop/src/themes/color.ts +142 -0
- package/agent/apps/desktop/src/themes/context.tsx +128 -75
- package/agent/apps/desktop/src/themes/install.test.ts +119 -0
- package/agent/apps/desktop/src/themes/install.ts +95 -0
- package/agent/apps/desktop/src/themes/presets.test.ts +33 -0
- package/agent/apps/desktop/src/themes/presets.ts +13 -4
- package/agent/apps/desktop/src/themes/profile-theme.test.ts +41 -0
- package/agent/apps/desktop/src/themes/types.ts +35 -0
- package/agent/apps/desktop/src/themes/user-themes.test.ts +63 -0
- package/agent/apps/desktop/src/themes/user-themes.ts +122 -0
- package/agent/apps/desktop/src/themes/vscode.test.ts +171 -0
- package/agent/apps/desktop/src/themes/vscode.ts +343 -0
- package/agent/apps/desktop/src/types/hermes.ts +138 -1
- package/agent/apps/desktop/tsconfig.json +2 -2
- package/agent/apps/desktop/vite.config.ts +18 -0
- package/agent/apps/shared/package.json +1 -1
- package/agent/apps/shared/src/json-rpc-gateway.ts +63 -2
- package/agent/apps/shared/tsconfig.json +2 -2
- package/agent/cli-config.yaml.example +78 -1
- package/agent/cli.py +2177 -3162
- package/agent/cron/blueprint_catalog.py +713 -0
- package/agent/cron/jobs.py +226 -110
- package/agent/cron/scheduler.py +468 -193
- package/agent/cron/scheduler_provider.py +177 -0
- package/agent/cron/scripts/__init__.py +1 -0
- package/agent/cron/scripts/classify_items.py +226 -0
- package/agent/cron/suggestion_catalog.py +154 -0
- package/agent/cron/suggestions.py +257 -0
- package/agent/docs/chronos-managed-cron-contract.md +196 -0
- package/agent/docs/design/profile-builder.md +146 -0
- package/agent/docs/middleware/README.md +260 -0
- package/agent/docs/observability/README.md +316 -0
- package/agent/docs/plans/2026-06-09-003-fix-telegram-stream-overflow-continuations-plan.md +240 -0
- package/agent/docs/rca-ssl-cacert-post-git-pull.md +54 -0
- package/agent/docs/relay-connector-contract.md +285 -0
- package/agent/gateway/authz_mixin.py +536 -0
- package/agent/gateway/channel_directory.py +65 -3
- package/agent/gateway/config.py +222 -12
- package/agent/gateway/display_config.py +10 -0
- package/agent/gateway/hooks.py +17 -0
- package/agent/gateway/kanban_watchers.py +1146 -0
- package/agent/gateway/message_timestamps.py +166 -0
- package/agent/gateway/platforms/ADDING_A_PLATFORM.md +29 -0
- package/agent/gateway/platforms/api_server.py +216 -38
- package/agent/gateway/platforms/base.py +210 -58
- package/agent/gateway/platforms/email.py +122 -12
- package/agent/gateway/platforms/feishu.py +80 -11
- package/agent/gateway/platforms/feishu_meeting_invite.py +212 -0
- package/agent/gateway/platforms/matrix.py +1498 -297
- package/agent/gateway/platforms/qqbot/adapter.py +6 -0
- package/agent/gateway/platforms/signal.py +8 -0
- package/agent/gateway/platforms/slack.py +308 -12
- package/agent/gateway/platforms/telegram.py +831 -24
- package/agent/gateway/platforms/webhook.py +109 -21
- package/agent/gateway/platforms/weixin.py +113 -2
- package/agent/gateway/platforms/whatsapp.py +94 -288
- package/agent/gateway/platforms/whatsapp_cloud.py +1956 -0
- package/agent/gateway/platforms/whatsapp_common.py +367 -0
- package/agent/gateway/platforms/yuanbao.py +608 -191
- package/agent/gateway/platforms/yuanbao_proto.py +232 -23
- package/agent/gateway/relay/__init__.py +375 -0
- package/agent/gateway/relay/adapter.py +222 -0
- package/agent/gateway/relay/auth.py +168 -0
- package/agent/gateway/relay/descriptor.py +118 -0
- package/agent/gateway/relay/transport.py +101 -0
- package/agent/gateway/relay/ws_transport.py +327 -0
- package/agent/gateway/response_filters.py +53 -0
- package/agent/gateway/rich_sent_store.py +80 -0
- package/agent/gateway/run.py +2940 -5001
- package/agent/gateway/session.py +109 -8
- package/agent/gateway/session_context.py +22 -4
- package/agent/gateway/slash_commands.py +3854 -0
- package/agent/gateway/status.py +141 -21
- package/agent/gateway/stream_consumer.py +288 -31
- package/agent/hermes-already-has-routines.md +1 -1
- package/agent/hermes_cli/__init__.py +62 -17
- package/agent/hermes_cli/_parser.py +30 -0
- package/agent/hermes_cli/_subprocess_compat.py +61 -0
- package/agent/hermes_cli/active_sessions.py +320 -0
- package/agent/hermes_cli/auth.py +707 -59
- package/agent/hermes_cli/auth_commands.py +39 -22
- package/agent/hermes_cli/backup.py +109 -7
- package/agent/hermes_cli/banner.py +88 -0
- package/agent/hermes_cli/blueprint_cmd.py +318 -0
- package/agent/hermes_cli/cli_agent_setup_mixin.py +684 -0
- package/agent/hermes_cli/cli_commands_mixin.py +2293 -0
- package/agent/hermes_cli/commands.py +215 -91
- package/agent/hermes_cli/config.py +967 -130
- package/agent/hermes_cli/container_boot.py +76 -11
- package/agent/hermes_cli/cron.py +5 -11
- package/agent/hermes_cli/curator.py +21 -0
- package/agent/hermes_cli/dashboard_auth/__init__.py +2 -0
- package/agent/hermes_cli/dashboard_auth/base.py +62 -0
- package/agent/hermes_cli/dashboard_auth/cookies.py +32 -19
- package/agent/hermes_cli/dashboard_auth/login_page.py +156 -6
- package/agent/hermes_cli/dashboard_auth/middleware.py +28 -4
- package/agent/hermes_cli/dashboard_auth/prefix.py +46 -2
- package/agent/hermes_cli/dashboard_auth/public_paths.py +6 -0
- package/agent/hermes_cli/dashboard_auth/routes.py +158 -2
- package/agent/hermes_cli/dashboard_auth/ws_tickets.py +85 -11
- package/agent/hermes_cli/dashboard_register.py +427 -0
- package/agent/hermes_cli/debug.py +155 -50
- package/agent/hermes_cli/doctor.py +255 -14
- package/agent/hermes_cli/dump.py +60 -6
- package/agent/hermes_cli/env_loader.py +33 -0
- package/agent/hermes_cli/gateway.py +755 -103
- package/agent/hermes_cli/gateway_enroll.py +250 -0
- package/agent/hermes_cli/gateway_windows.py +254 -11
- package/agent/hermes_cli/gui_uninstall.py +285 -0
- package/agent/hermes_cli/inventory.py +105 -4
- package/agent/hermes_cli/kanban.py +58 -71
- package/agent/hermes_cli/kanban_db.py +391 -14
- package/agent/hermes_cli/kanban_decompose.py +2 -2
- package/agent/hermes_cli/kanban_specify.py +3 -1
- package/agent/hermes_cli/logs.py +2 -0
- package/agent/hermes_cli/main.py +2889 -5287
- package/agent/hermes_cli/managed_scope.py +214 -0
- package/agent/hermes_cli/managed_uv.py +254 -0
- package/agent/hermes_cli/mcp_catalog.py +6 -3
- package/agent/hermes_cli/mcp_config.py +145 -21
- package/agent/hermes_cli/mcp_security.py +96 -0
- package/agent/hermes_cli/mcp_startup.py +32 -3
- package/agent/hermes_cli/memory_providers.py +149 -0
- package/agent/hermes_cli/memory_setup.py +97 -42
- package/agent/hermes_cli/middleware.py +313 -0
- package/agent/hermes_cli/model_catalog.py +31 -0
- package/agent/hermes_cli/model_cost_guard.py +134 -0
- package/agent/hermes_cli/model_normalize.py +2 -1
- package/agent/hermes_cli/model_setup_flows.py +2759 -0
- package/agent/hermes_cli/model_switch.py +242 -27
- package/agent/hermes_cli/models.py +284 -44
- package/agent/hermes_cli/nous_account.py +33 -6
- package/agent/hermes_cli/nous_billing.py +406 -0
- package/agent/hermes_cli/nous_subscription.py +202 -5
- package/agent/hermes_cli/platforms.py +1 -0
- package/agent/hermes_cli/plugins.py +218 -18
- package/agent/hermes_cli/plugins_cmd.py +249 -105
- package/agent/hermes_cli/portal_cli.py +56 -16
- package/agent/hermes_cli/profile_distribution.py +6 -1
- package/agent/hermes_cli/profiles.py +283 -32
- package/agent/hermes_cli/provider_catalog.py +170 -0
- package/agent/hermes_cli/providers.py +4 -1
- package/agent/hermes_cli/pty_bridge.py +53 -4
- package/agent/hermes_cli/runtime_provider.py +216 -34
- package/agent/hermes_cli/secret_prompt.py +4 -4
- package/agent/hermes_cli/secrets_cli.py +24 -0
- package/agent/hermes_cli/send_cmd.py +28 -2
- package/agent/hermes_cli/service_manager.py +166 -19
- package/agent/hermes_cli/session_listing.py +97 -0
- package/agent/hermes_cli/setup.py +158 -94
- package/agent/hermes_cli/setup_whatsapp_cloud.py +541 -0
- package/agent/hermes_cli/skills_config.py +8 -2
- package/agent/hermes_cli/skills_hub.py +149 -7
- package/agent/hermes_cli/status.py +2 -2
- package/agent/hermes_cli/subcommands/__init__.py +18 -0
- package/agent/hermes_cli/subcommands/_shared.py +29 -0
- package/agent/hermes_cli/subcommands/acp.py +52 -0
- package/agent/hermes_cli/subcommands/auth.py +109 -0
- package/agent/hermes_cli/subcommands/backup.py +38 -0
- package/agent/hermes_cli/subcommands/claw.py +92 -0
- package/agent/hermes_cli/subcommands/config.py +49 -0
- package/agent/hermes_cli/subcommands/cron.py +163 -0
- package/agent/hermes_cli/subcommands/dashboard.py +143 -0
- package/agent/hermes_cli/subcommands/debug.py +77 -0
- package/agent/hermes_cli/subcommands/doctor.py +35 -0
- package/agent/hermes_cli/subcommands/dump.py +28 -0
- package/agent/hermes_cli/subcommands/gateway.py +332 -0
- package/agent/hermes_cli/subcommands/gui.py +63 -0
- package/agent/hermes_cli/subcommands/hooks.py +77 -0
- package/agent/hermes_cli/subcommands/import_cmd.py +31 -0
- package/agent/hermes_cli/subcommands/insights.py +25 -0
- package/agent/hermes_cli/subcommands/login.py +78 -0
- package/agent/hermes_cli/subcommands/logout.py +28 -0
- package/agent/hermes_cli/subcommands/logs.py +78 -0
- package/agent/hermes_cli/subcommands/mcp.py +108 -0
- package/agent/hermes_cli/subcommands/memory.py +53 -0
- package/agent/hermes_cli/subcommands/model.py +72 -0
- package/agent/hermes_cli/subcommands/pairing.py +36 -0
- package/agent/hermes_cli/subcommands/plugins.py +94 -0
- package/agent/hermes_cli/subcommands/postinstall.py +23 -0
- package/agent/hermes_cli/subcommands/profile.py +203 -0
- package/agent/hermes_cli/subcommands/prompt_size.py +36 -0
- package/agent/hermes_cli/subcommands/security.py +62 -0
- package/agent/hermes_cli/subcommands/setup.py +58 -0
- package/agent/hermes_cli/subcommands/skills.py +298 -0
- package/agent/hermes_cli/subcommands/slack.py +60 -0
- package/agent/hermes_cli/subcommands/status.py +28 -0
- package/agent/hermes_cli/subcommands/tools.py +95 -0
- package/agent/hermes_cli/subcommands/uninstall.py +41 -0
- package/agent/hermes_cli/subcommands/update.py +70 -0
- package/agent/hermes_cli/subcommands/version.py +18 -0
- package/agent/hermes_cli/subcommands/webhook.py +76 -0
- package/agent/hermes_cli/subcommands/whatsapp.py +22 -0
- package/agent/hermes_cli/suggestions_cmd.py +153 -0
- package/agent/hermes_cli/telegram_managed_bot.py +358 -0
- package/agent/hermes_cli/tips.py +3 -4
- package/agent/hermes_cli/tools_config.py +155 -28
- package/agent/hermes_cli/uninstall.py +231 -35
- package/agent/hermes_cli/web_server.py +6188 -975
- package/agent/hermes_cli/win_pty_bridge.py +179 -0
- package/agent/hermes_cli/write_approval_commands.py +209 -0
- package/agent/hermes_constants.py +164 -33
- package/agent/hermes_logging.py +74 -2
- package/agent/hermes_state.py +919 -106
- package/agent/hermes_time.py +20 -0
- package/agent/locales/af.yaml +23 -0
- package/agent/locales/de.yaml +23 -0
- package/agent/locales/en.yaml +20 -0
- package/agent/locales/es.yaml +23 -0
- package/agent/locales/fr.yaml +23 -0
- package/agent/locales/ga.yaml +23 -0
- package/agent/locales/hu.yaml +23 -0
- package/agent/locales/it.yaml +23 -0
- package/agent/locales/ja.yaml +23 -0
- package/agent/locales/ko.yaml +23 -0
- package/agent/locales/pt.yaml +23 -0
- package/agent/locales/ru.yaml +23 -0
- package/agent/locales/tr.yaml +23 -0
- package/agent/locales/uk.yaml +23 -0
- package/agent/locales/zh-hant.yaml +23 -0
- package/agent/locales/zh.yaml +23 -0
- package/agent/model_tools.py +204 -40
- package/agent/optional-mcps/clawpump/manifest.yaml +4 -2
- package/agent/optional-mcps/clawpump-stdio/manifest.yaml +2 -0
- package/agent/optional-mcps/unreal-engine/manifest.yaml +54 -0
- package/agent/optional-skills/blockchain/hyperliquid/SKILL.md +2 -2
- package/agent/optional-skills/blockchain/hyperliquid/scripts/hyperliquid_client.py +1 -1
- package/agent/optional-skills/creative/kanban-video-orchestrator/SKILL.md +1 -1
- package/agent/optional-skills/creative/kanban-video-orchestrator/assets/setup.sh.tmpl +4 -3
- package/agent/optional-skills/creative/kanban-video-orchestrator/references/kanban-setup.md +6 -4
- package/agent/optional-skills/creative/kanban-video-orchestrator/references/tool-matrix.md +2 -2
- package/agent/{skills/software-development → optional-skills/devops}/hermes-s6-container-supervision/SKILL.md +2 -0
- package/agent/optional-skills/devops/watchers/SKILL.md +1 -1
- package/agent/optional-skills/devops/watchers/scripts/watch_github.py +2 -1
- package/agent/optional-skills/payments/mpp-agent/SKILL.md +124 -0
- package/agent/optional-skills/payments/stripe-link-cli/SKILL.md +184 -0
- package/agent/optional-skills/payments/stripe-projects/SKILL.md +120 -0
- package/agent/optional-skills/productivity/canvas/SKILL.md +1 -1
- package/agent/optional-skills/productivity/canvas/scripts/canvas_api.py +4 -1
- package/agent/optional-skills/productivity/shop/SKILL.md +224 -0
- package/agent/optional-skills/productivity/shop/references/catalog-mcp.md +236 -0
- package/agent/optional-skills/productivity/shop/references/direct-api.md +278 -0
- package/agent/optional-skills/productivity/shop/references/legal.md +3 -0
- package/agent/optional-skills/productivity/shop/references/safety.md +36 -0
- package/agent/optional-skills/productivity/shopify/SKILL.md +1 -1
- package/agent/optional-skills/productivity/siyuan/SKILL.md +1 -1
- package/agent/optional-skills/productivity/telephony/SKILL.md +4 -4
- package/agent/optional-skills/productivity/telephony/scripts/telephony.py +15 -15
- package/agent/optional-skills/security/1password/SKILL.md +1 -1
- package/agent/{skills/red-teaming → optional-skills/security}/godmode/SKILL.md +3 -4
- package/agent/{skills/red-teaming → optional-skills/security}/godmode/scripts/auto_jailbreak.py +3 -1
- package/agent/optional-skills/software-development/rest-graphql-debug/SKILL.md +1 -1
- package/agent/{skills → optional-skills}/software-development/subagent-driven-development/SKILL.md +5 -5
- package/agent/package-lock.json +4082 -7907
- package/agent/package.json +18 -3
- package/agent/plugins/browser/firecrawl/provider.py +4 -1
- package/agent/plugins/cron/__init__.py +344 -0
- package/agent/plugins/cron/chronos/__init__.py +241 -0
- package/agent/plugins/cron/chronos/_nas_client.py +123 -0
- package/agent/plugins/cron/chronos/plugin.yaml +9 -0
- package/agent/plugins/cron/chronos/verify.py +103 -0
- package/agent/plugins/dashboard_auth/basic/__init__.py +491 -0
- package/agent/plugins/dashboard_auth/basic/plugin.yaml +7 -0
- package/agent/plugins/dashboard_auth/nous/__init__.py +12 -14
- package/agent/plugins/dashboard_auth/self_hosted/__init__.py +736 -0
- package/agent/plugins/dashboard_auth/self_hosted/plugin.yaml +8 -0
- package/agent/plugins/disk-cleanup/disk_cleanup.py +100 -20
- package/agent/plugins/google_meet/audio_bridge.py +4 -0
- package/agent/plugins/google_meet/meet_bot.py +7 -1
- package/agent/plugins/hermes-achievements/dashboard/dist/index.js +9 -15
- package/agent/plugins/image_gen/fal/__init__.py +35 -6
- package/agent/plugins/image_gen/krea/__init__.py +56 -13
- package/agent/plugins/image_gen/openai/__init__.py +122 -24
- package/agent/plugins/image_gen/openai-codex/__init__.py +28 -2
- package/agent/plugins/image_gen/xai/__init__.py +92 -12
- package/agent/plugins/kanban/dashboard/dist/index.js +63 -48
- package/agent/plugins/kanban/dashboard/plugin_api.py +39 -35
- package/agent/plugins/memory/__init__.py +48 -5
- package/agent/plugins/memory/byterover/__init__.py +1 -0
- package/agent/plugins/memory/hindsight/README.md +1 -1
- package/agent/plugins/memory/hindsight/__init__.py +138 -24
- package/agent/plugins/memory/hindsight/plugin.yaml +1 -1
- package/agent/plugins/memory/honcho/README.md +13 -10
- package/agent/plugins/memory/honcho/cli.py +247 -122
- package/agent/plugins/memory/honcho/client.py +112 -102
- package/agent/plugins/memory/openviking/README.md +12 -1
- package/agent/plugins/memory/openviking/__init__.py +2281 -107
- package/agent/plugins/memory/openviking/plugin.yaml +1 -2
- package/agent/plugins/memory/supermemory/README.md +22 -10
- package/agent/plugins/memory/supermemory/__init__.py +142 -37
- package/agent/plugins/memory/supermemory/plugin.yaml +1 -1
- package/agent/plugins/model-providers/anthropic/__init__.py +1 -0
- package/agent/plugins/model-providers/bedrock/__init__.py +1 -0
- package/agent/plugins/model-providers/copilot-acp/__init__.py +1 -0
- package/agent/plugins/model-providers/custom/__init__.py +8 -2
- package/agent/plugins/model-providers/kimi-coding/__init__.py +16 -7
- package/agent/plugins/model-providers/minimax/__init__.py +60 -8
- package/agent/plugins/model-providers/opencode-zen/__init__.py +12 -3
- package/agent/plugins/model-providers/openrouter/__init__.py +75 -4
- package/agent/plugins/model-providers/xiaomi/__init__.py +2 -0
- package/agent/plugins/model-providers/zai/__init__.py +1 -0
- package/agent/plugins/observability/langfuse/__init__.py +147 -14
- package/agent/plugins/observability/nemo_relay/README.md +559 -0
- package/agent/plugins/observability/nemo_relay/__init__.py +962 -0
- package/agent/plugins/observability/nemo_relay/plugin.yaml +20 -0
- package/agent/plugins/platforms/discord/adapter.py +932 -61
- package/agent/plugins/platforms/discord/voice_mixer.py +379 -0
- package/agent/plugins/platforms/google_chat/adapter.py +9 -3
- package/agent/plugins/platforms/google_chat/oauth.py +1 -1
- package/agent/plugins/platforms/homeassistant/__init__.py +3 -0
- package/agent/{gateway/platforms/homeassistant.py → plugins/platforms/homeassistant/adapter.py} +128 -0
- package/agent/plugins/platforms/homeassistant/plugin.yaml +22 -0
- package/agent/plugins/platforms/irc/adapter.py +4 -1
- package/agent/plugins/platforms/line/adapter.py +16 -1
- package/agent/plugins/platforms/mattermost/adapter.py +100 -24
- package/agent/plugins/platforms/photon/README.md +179 -0
- package/agent/plugins/platforms/photon/__init__.py +4 -0
- package/agent/plugins/platforms/photon/adapter.py +1586 -0
- package/agent/plugins/platforms/photon/auth.py +1046 -0
- package/agent/plugins/platforms/photon/cli.py +439 -0
- package/agent/plugins/platforms/photon/plugin.yaml +88 -0
- package/agent/plugins/platforms/photon/sidecar/README.md +52 -0
- package/agent/plugins/platforms/photon/sidecar/index.mjs +720 -0
- package/agent/plugins/platforms/photon/sidecar/package-lock.json +1730 -0
- package/agent/plugins/platforms/photon/sidecar/package.json +25 -0
- package/agent/plugins/platforms/photon/sidecar/patch-spectrum-mixed-attachments.mjs +155 -0
- package/agent/plugins/platforms/raft/__init__.py +3 -0
- package/agent/plugins/platforms/raft/adapter.py +774 -0
- package/agent/plugins/platforms/raft/plugin.yaml +19 -0
- package/agent/plugins/platforms/simplex/adapter.py +777 -220
- package/agent/plugins/platforms/simplex/plugin.yaml +21 -2
- package/agent/plugins/platforms/teams/adapter.py +175 -5
- package/agent/plugins/plugin_utils.py +135 -0
- package/agent/plugins/video_gen/fal/__init__.py +10 -3
- package/agent/plugins/web/searxng/provider.py +15 -2
- package/agent/plugins/web/xai/provider.py +2 -2
- package/agent/providers/base.py +22 -3
- package/agent/pyproject.toml +115 -21
- package/agent/run_agent.py +733 -39
- package/agent/scripts/build_skills_index.py +51 -19
- package/agent/scripts/check_subprocess_stdin.py +177 -0
- package/agent/scripts/contributor_audit.py +2 -0
- package/agent/scripts/docker_config_migrate.py +67 -0
- package/agent/scripts/install.cmd +3 -3
- package/agent/scripts/install.ps1 +580 -154
- package/agent/scripts/install.sh +402 -185
- package/agent/scripts/lib/node-bootstrap.sh +39 -4
- package/agent/scripts/release.py +183 -0
- package/agent/scripts/run_tests.sh +1 -0
- package/agent/scripts/run_tests_parallel.py +18 -23
- package/agent/scripts/whatsapp-bridge/bridge.js +25 -4
- package/agent/setup.py +59 -0
- package/agent/skills/autonomous-ai-agents/codex/SKILL.md +19 -0
- package/agent/skills/autonomous-ai-agents/hermes-agent/SKILL.md +10 -3
- package/agent/skills/{mcp/native-mcp/SKILL.md → autonomous-ai-agents/hermes-agent/references/native-mcp.md} +0 -13
- package/agent/skills/{devops/webhook-subscriptions/SKILL.md → autonomous-ai-agents/hermes-agent/references/webhooks.md} +1 -11
- package/agent/skills/clawpump/SKILL.md +3 -1
- package/agent/skills/devops/kanban-orchestrator/SKILL.md +1 -0
- package/agent/skills/devops/kanban-worker/SKILL.md +1 -0
- package/agent/skills/github/github-auth/SKILL.md +2 -2
- package/agent/skills/github/github-auth/scripts/gh-env.sh +2 -2
- package/agent/skills/github/github-code-review/SKILL.md +2 -2
- package/agent/skills/github/github-issues/SKILL.md +2 -2
- package/agent/skills/github/github-pr-workflow/SKILL.md +2 -2
- package/agent/skills/github/github-repo-management/SKILL.md +2 -2
- package/agent/skills/media/gif-search/SKILL.md +1 -1
- package/agent/skills/media/youtube-content/SKILL.md +10 -7
- package/agent/skills/media/youtube-content/scripts/fetch_transcript.py +3 -3
- package/agent/skills/note-taking/obsidian/SKILL.md +1 -1
- package/agent/skills/productivity/airtable/SKILL.md +2 -2
- package/agent/skills/productivity/google-workspace/scripts/setup.py +33 -7
- package/agent/skills/productivity/notion/SKILL.md +2 -2
- package/agent/skills/productivity/teams-meeting-pipeline/SKILL.md +1 -1
- package/agent/skills/research/llm-wiki/SKILL.md +1 -1
- package/agent/skills/social-media/xurl/SKILL.md +9 -0
- package/agent/skills/software-development/hermes-agent-skill-authoring/SKILL.md +1 -1
- package/agent/skills/software-development/plan/SKILL.md +285 -5
- package/agent/skills/software-development/requesting-code-review/SKILL.md +2 -2
- package/agent/skills/software-development/simplify-code/SKILL.md +212 -0
- package/agent/skills/software-development/spike/SKILL.md +2 -2
- package/agent/skills/software-development/systematic-debugging/SKILL.md +1 -1
- package/agent/skills/software-development/test-driven-development/SKILL.md +1 -1
- package/agent/tools/approval.py +302 -4
- package/agent/tools/async_delegation.py +386 -0
- package/agent/tools/blueprints.py +325 -0
- package/agent/tools/browser_cdp_tool.py +3 -3
- package/agent/tools/browser_tool.py +34 -6
- package/agent/tools/checkpoint_manager.py +31 -1
- package/agent/tools/clarify_tool.py +55 -5
- package/agent/tools/code_execution_tool.py +31 -14
- package/agent/tools/computer_use/cua_backend.py +81 -3
- package/agent/tools/computer_use/tool.py +79 -5
- package/agent/tools/computer_use/vision_routing.py +55 -3
- package/agent/tools/credential_files.py +31 -12
- package/agent/tools/cronjob_tools.py +30 -20
- package/agent/tools/delegate_tool.py +356 -31
- package/agent/tools/env_probe.py +1 -0
- package/agent/tools/environments/docker.py +163 -8
- package/agent/tools/environments/file_sync.py +2 -1
- package/agent/tools/environments/local.py +74 -23
- package/agent/tools/environments/singularity.py +4 -1
- package/agent/tools/environments/ssh.py +78 -11
- package/agent/tools/file_operations.py +277 -41
- package/agent/tools/file_tools.py +166 -28
- package/agent/tools/image_generation_tool.py +515 -29
- package/agent/tools/kanban_tools.py +99 -0
- package/agent/tools/lazy_deps.py +33 -2
- package/agent/tools/mcp_oauth.py +5 -5
- package/agent/tools/mcp_oauth_manager.py +7 -5
- package/agent/tools/mcp_tool.py +840 -33
- package/agent/tools/memory_tool.py +335 -38
- package/agent/tools/osv_check.py +15 -1
- package/agent/tools/process_registry.py +155 -11
- package/agent/tools/read_extract.py +248 -0
- package/agent/tools/read_terminal_tool.py +93 -0
- package/agent/tools/schema_sanitizer.py +38 -0
- package/agent/tools/send_message_tool.py +163 -49
- package/agent/tools/session_search_tool.py +189 -7
- package/agent/tools/skill_manager_tool.py +202 -3
- package/agent/tools/skill_usage.py +52 -4
- package/agent/tools/skills_hub.py +184 -44
- package/agent/tools/skills_sync.py +232 -5
- package/agent/tools/skills_tool.py +125 -11
- package/agent/tools/terminal_tool.py +148 -26
- package/agent/tools/tirith_security.py +2 -0
- package/agent/tools/todo_tool.py +32 -1
- package/agent/tools/transcription_tools.py +13 -5
- package/agent/tools/tts_tool.py +332 -38
- package/agent/tools/url_safety.py +52 -1
- package/agent/tools/vision_tools.py +124 -39
- package/agent/tools/voice_mode.py +4 -3
- package/agent/tools/web_tools.py +45 -15
- package/agent/tools/write_approval.py +493 -0
- package/agent/toolsets.py +34 -10
- package/agent/trajectory_compressor.py +81 -10
- package/agent/tui_gateway/entry.py +43 -6
- package/agent/tui_gateway/server.py +3335 -330
- package/agent/tui_gateway/slash_worker.py +61 -0
- package/agent/tui_gateway/ws.py +67 -9
- package/agent/ui-tui/eslint.config.mjs +0 -4
- package/agent/ui-tui/package.json +6 -6
- package/agent/ui-tui/packages/hermes-ink/package.json +1 -1
- package/agent/ui-tui/packages/hermes-ink/src/ink/app-mouse.test.ts +34 -1
- package/agent/ui-tui/packages/hermes-ink/src/ink/app-rawmode-mouse.test.ts +91 -0
- package/agent/ui-tui/packages/hermes-ink/src/ink/components/App.tsx +35 -2
- package/agent/ui-tui/packages/hermes-ink/src/ink/events/input-event.ts +4 -11
- package/agent/ui-tui/packages/hermes-ink/src/ink/parse-keypress.test.ts +23 -57
- package/agent/ui-tui/packages/hermes-ink/src/ink/parse-keypress.ts +11 -135
- package/agent/ui-tui/packages/hermes-ink/src/ink/termio/tokenize.test.ts +185 -0
- package/agent/ui-tui/packages/hermes-ink/src/ink/termio/tokenize.ts +37 -3
- package/agent/ui-tui/packages/hermes-ink/src/utils/execFileNoThrow.ts +5 -5
- package/agent/ui-tui/src/__tests__/appChromeStatusRule.test.tsx +217 -0
- package/agent/ui-tui/src/__tests__/appChromeStatusRuleDevCredits.test.tsx +73 -0
- package/agent/ui-tui/src/__tests__/approvalAction.test.ts +11 -0
- package/agent/ui-tui/src/__tests__/billingCommand.test.ts +301 -0
- package/agent/ui-tui/src/__tests__/blockLayout.test.ts +122 -0
- package/agent/ui-tui/src/__tests__/brandingMcpCount.test.ts +111 -0
- package/agent/ui-tui/src/__tests__/completionApply.test.ts +51 -0
- package/agent/ui-tui/src/__tests__/createGatewayEventHandler.test.ts +487 -2
- package/agent/ui-tui/src/__tests__/createSlashHandler.test.ts +54 -0
- package/agent/ui-tui/src/__tests__/creditsCommand.test.ts +144 -0
- package/agent/ui-tui/src/__tests__/gatewayClient.test.ts +120 -99
- package/agent/ui-tui/src/__tests__/gracefulExit.test.ts +11 -0
- package/agent/ui-tui/src/__tests__/memoryMonitor.test.ts +102 -0
- package/agent/ui-tui/src/__tests__/paths.test.ts +41 -1
- package/agent/ui-tui/src/__tests__/terminalModes.test.ts +22 -0
- package/agent/ui-tui/src/__tests__/text.test.ts +23 -0
- package/agent/ui-tui/src/__tests__/textInputFastEcho.test.ts +37 -0
- package/agent/ui-tui/src/__tests__/turnControllerNotice.test.ts +43 -0
- package/agent/ui-tui/src/__tests__/useInputHandlers.test.ts +38 -1
- package/agent/ui-tui/src/__tests__/virtualHeights.test.ts +8 -0
- package/agent/ui-tui/src/app/createGatewayEventHandler.ts +102 -7
- package/agent/ui-tui/src/app/interfaces.ts +64 -1
- package/agent/ui-tui/src/app/overlayStore.ts +18 -2
- package/agent/ui-tui/src/app/slash/commands/billing.ts +332 -0
- package/agent/ui-tui/src/app/slash/commands/core.ts +31 -2
- package/agent/ui-tui/src/app/slash/commands/credits.ts +57 -0
- package/agent/ui-tui/src/app/slash/commands/ops.ts +28 -0
- package/agent/ui-tui/src/app/slash/commands/session.ts +32 -4
- package/agent/ui-tui/src/app/slash/registry.ts +4 -0
- package/agent/ui-tui/src/app/turnController.ts +145 -2
- package/agent/ui-tui/src/app/uiStore.ts +2 -0
- package/agent/ui-tui/src/app/useInputHandlers.ts +42 -4
- package/agent/ui-tui/src/app/useMainApp.ts +54 -8
- package/agent/ui-tui/src/app/useSessionLifecycle.ts +40 -31
- package/agent/ui-tui/src/app/useSubmission.ts +23 -31
- package/agent/ui-tui/src/components/appChrome.tsx +112 -5
- package/agent/ui-tui/src/components/appLayout.tsx +9 -0
- package/agent/ui-tui/src/components/appOverlays.tsx +25 -1
- package/agent/ui-tui/src/components/billingOverlay.tsx +684 -0
- package/agent/ui-tui/src/components/branding.tsx +15 -3
- package/agent/ui-tui/src/components/messageLine.tsx +25 -3
- package/agent/ui-tui/src/components/pluginsHub.tsx +238 -0
- package/agent/ui-tui/src/components/prompts.tsx +31 -17
- package/agent/ui-tui/src/components/streamingAssistant.tsx +63 -55
- package/agent/ui-tui/src/components/textInput.tsx +16 -0
- package/agent/ui-tui/src/config/env.ts +12 -0
- package/agent/ui-tui/src/config/limits.ts +13 -0
- package/agent/ui-tui/src/domain/blockLayout.ts +146 -0
- package/agent/ui-tui/src/domain/paths.ts +24 -0
- package/agent/ui-tui/src/domain/slash.ts +40 -0
- package/agent/ui-tui/src/entry.tsx +35 -4
- package/agent/ui-tui/src/gatewayClient.ts +22 -10
- package/agent/ui-tui/src/gatewayTypes.ts +130 -1
- package/agent/ui-tui/src/lib/gracefulExit.ts +24 -4
- package/agent/ui-tui/src/lib/memory.test.ts +162 -0
- package/agent/ui-tui/src/lib/memory.ts +60 -1
- package/agent/ui-tui/src/lib/memoryMonitor.ts +79 -4
- package/agent/ui-tui/src/lib/osc52.ts +1 -1
- package/agent/ui-tui/src/lib/text.test.ts +32 -1
- package/agent/ui-tui/src/lib/text.ts +29 -2
- package/agent/ui-tui/src/lib/virtualHeights.ts +13 -0
- package/agent/ui-tui/src/types.ts +5 -0
- package/agent/ui-tui/tsconfig.build.json +0 -1
- package/agent/ui-tui/tsconfig.json +2 -1
- package/agent/utils.py +66 -2
- package/agent/uv.lock +300 -684
- package/agent/web/index.html +2 -2
- package/agent/web/package.json +11 -6
- package/agent/web/public/claw-bg.webp +0 -0
- package/agent/web/public/claw-logo.webp +0 -0
- package/agent/web/src/App.tsx +138 -48
- package/agent/web/src/components/AutomationBlueprints.tsx +225 -0
- package/agent/web/src/components/Backdrop.tsx +15 -0
- package/agent/web/src/components/ChatSessionList.tsx +260 -0
- package/agent/web/src/components/ChatSidebar.tsx +262 -78
- package/agent/web/src/components/ConfirmDialog.tsx +122 -0
- package/agent/web/src/components/ModelPickerDialog.tsx +111 -16
- package/agent/web/src/components/ModelReloadConfirm.tsx +40 -0
- package/agent/web/src/components/ProfileScopeBanner.tsx +30 -0
- package/agent/web/src/components/ProfileSwitcher.tsx +67 -0
- package/agent/web/src/components/ReasoningPicker.tsx +167 -0
- package/agent/web/src/components/SkillEditorDialog.tsx +215 -0
- package/agent/web/src/components/ThemeSwitcher.tsx +119 -4
- package/agent/web/src/components/ToolsetConfigDrawer.tsx +457 -0
- package/agent/web/src/contexts/PageHeaderProvider.tsx +7 -4
- package/agent/web/src/contexts/ProfileProvider.tsx +137 -0
- package/agent/web/src/contexts/SystemActions.tsx +6 -8
- package/agent/web/src/contexts/profile-context.ts +19 -0
- package/agent/web/src/contexts/useProfileScope.ts +6 -0
- package/agent/web/src/i18n/af.ts +5 -4
- package/agent/web/src/i18n/de.ts +5 -4
- package/agent/web/src/i18n/en.ts +58 -4
- package/agent/web/src/i18n/es.ts +5 -3
- package/agent/web/src/i18n/fr.ts +5 -3
- package/agent/web/src/i18n/ga.ts +5 -4
- package/agent/web/src/i18n/hu.ts +5 -4
- package/agent/web/src/i18n/it.ts +5 -4
- package/agent/web/src/i18n/ja.ts +5 -4
- package/agent/web/src/i18n/ko.ts +5 -4
- package/agent/web/src/i18n/pt.ts +5 -3
- package/agent/web/src/i18n/ru.ts +5 -4
- package/agent/web/src/i18n/tr.ts +5 -4
- package/agent/web/src/i18n/types.ts +59 -1
- package/agent/web/src/i18n/uk.ts +5 -3
- package/agent/web/src/i18n/zh-hant.ts +5 -4
- package/agent/web/src/i18n/zh.ts +5 -4
- package/agent/web/src/index.css +2 -2
- package/agent/web/src/lib/api.ts +819 -52
- package/agent/web/src/lib/dashboard-flags.ts +16 -7
- package/agent/web/src/lib/reasoning-effort.test.ts +48 -0
- package/agent/web/src/lib/reasoning-effort.ts +36 -0
- package/agent/web/src/lib/session-refresh.test.ts +21 -0
- package/agent/web/src/lib/session-refresh.ts +26 -0
- package/agent/web/src/pages/ChannelsPage.tsx +529 -68
- package/agent/web/src/pages/ChatPage.tsx +249 -56
- package/agent/web/src/pages/ConfigPage.tsx +11 -1
- package/agent/web/src/pages/CronPage.tsx +219 -31
- package/agent/web/src/pages/EnvPage.tsx +25 -6
- package/agent/web/src/pages/FilesPage.tsx +525 -0
- package/agent/web/src/pages/McpPage.tsx +80 -3
- package/agent/web/src/pages/ModelsPage.tsx +97 -12
- package/agent/web/src/pages/PluginsPage.tsx +1 -1
- package/agent/web/src/pages/ProfileBuilderPage.tsx +611 -0
- package/agent/web/src/pages/ProfilesPage.tsx +1038 -172
- package/agent/web/src/pages/SessionsPage.tsx +144 -13
- package/agent/web/src/pages/SkillsPage.tsx +851 -70
- package/agent/web/src/pages/SystemPage.tsx +340 -4
- package/agent/web/src/pages/WalletPage.tsx +401 -0
- package/agent/web/src/pages/WebhooksPage.tsx +145 -15
- package/agent/web/src/pages/X402Page.tsx +207 -0
- package/agent/web/src/plugins/registry.ts +28 -11
- package/agent/web/src/plugins/sdk.d.ts +160 -0
- package/agent/web/src/themes/context.tsx +112 -5
- package/agent/web/src/themes/fonts.ts +167 -0
- package/agent/web/src/themes/index.ts +7 -0
- package/agent/web/tsconfig.app.json +0 -1
- package/agent/web/vite.config.ts +1 -8
- package/agent/web/vitest.config.ts +16 -0
- package/package.json +1 -1
- package/agent/apps/desktop/package-lock.json +0 -18363
- package/agent/apps/desktop/src/app/chat/composer/skin-slash-popover.tsx +0 -56
- package/agent/apps/desktop/src/components/assistant-ui/thread-virtualizer.tsx +0 -382
- package/agent/apps/desktop/src/components/assistant-ui/todo-tool.tsx +0 -109
- package/agent/apps/desktop/src/components/chat/generated-image-context.tsx +0 -19
- package/agent/optional-skills/productivity/shop-app/SKILL.md +0 -340
- package/agent/skills/autonomous-ai-agents/kanban-codex-lane/SKILL.md +0 -277
- package/agent/skills/autonomous-ai-agents/kanban-codex-lane/templates/pmb-codex-lane-prompt.md +0 -57
- package/agent/skills/diagramming/DESCRIPTION.md +0 -3
- package/agent/skills/domain/DESCRIPTION.md +0 -24
- package/agent/skills/gifs/DESCRIPTION.md +0 -3
- package/agent/skills/inference-sh/DESCRIPTION.md +0 -19
- package/agent/skills/mcp/DESCRIPTION.md +0 -3
- package/agent/skills/media/spotify/SKILL.md +0 -135
- package/agent/skills/mlops/training/DESCRIPTION.md +0 -3
- package/agent/skills/mlops/vector-databases/DESCRIPTION.md +0 -3
- package/agent/skills/productivity/linear/SKILL.md +0 -380
- package/agent/skills/productivity/linear/scripts/linear_api.py +0 -445
- package/agent/skills/software-development/debugging-hermes-tui-commands/SKILL.md +0 -152
- package/agent/skills/software-development/writing-plans/SKILL.md +0 -297
- package/agent/ui-tui/package-lock.json +0 -7449
- package/agent/ui-tui/packages/hermes-ink/package-lock.json +0 -1289
- package/agent/web/package-lock.json +0 -8887
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/PORT_NOTES.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/SKILL.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/prompts/system.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/palettes/macaron.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/palettes/mono-ink.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/palettes/neon.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/palettes/warm.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/prompt-construction.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/style-presets.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/blueprint.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/chalkboard.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/editorial.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/elegant.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/fantasy-animation.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/flat-doodle.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/flat.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/ink-notes.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/intuition-machine.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/minimal.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/nature.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/notion.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/pixel-art.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/playful.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/retro.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/scientific.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/screen-print.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/sketch-notes.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/sketch.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/vector-illustration.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/vintage.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/warm.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles/watercolor.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/styles.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/usage.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-article-illustrator/references/workflow.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/PORT_NOTES.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/SKILL.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/analysis-framework.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/chalk.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/ink-brush.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/ligne-claire.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/manga.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/minimalist.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/art-styles/realistic.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/auto-selection.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/base-prompt.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/character-template.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/cinematic.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/dense.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/four-panel.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/mixed.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/splash.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/standard.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/layouts/webtoon.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/ohmsha-guide.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/partial-workflows.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/concept-story.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/four-panel.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/ohmsha.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/shoujo.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/presets/wuxia.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/storyboard-template.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/action.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/dramatic.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/energetic.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/neutral.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/romantic.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/vintage.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/tones/warm.md +0 -0
- /package/agent/{skills → optional-skills}/creative/baoyu-comic/references/workflow.md +0 -0
- /package/agent/{skills → optional-skills}/creative/creative-ideation/SKILL.md +0 -0
- /package/agent/{skills → optional-skills}/creative/creative-ideation/references/full-prompt-library.md +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/ATTRIBUTION.md +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/SKILL.md +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/references/palettes.md +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/scripts/__init__.py +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/scripts/palettes.py +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/scripts/pixel_art.py +0 -0
- /package/agent/{skills → optional-skills}/creative/pixel-art/scripts/pixel_art_video.py +0 -0
- /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/SKILL.md +0 -0
- /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/references/analysis-modules.md +0 -0
- /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/references/methods-guide.md +0 -0
- /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/templates/abliteration-config.yaml +0 -0
- /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/templates/analysis-study.yaml +0 -0
- /package/agent/{skills/mlops/inference → optional-skills/mlops}/obliteratus/templates/batch-abliteration.yaml +0 -0
- /package/agent/{skills → optional-skills}/mlops/research/DESCRIPTION.md +0 -0
- /package/agent/{skills → optional-skills}/mlops/research/dspy/SKILL.md +0 -0
- /package/agent/{skills → optional-skills}/mlops/research/dspy/references/examples.md +0 -0
- /package/agent/{skills → optional-skills}/mlops/research/dspy/references/modules.md +0 -0
- /package/agent/{skills → optional-skills}/mlops/research/dspy/references/optimizers.md +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/references/jailbreak-templates.md +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/references/refusal-detection.md +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/scripts/godmode_race.py +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/scripts/load_godmode.py +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/scripts/parseltongue.py +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/templates/prefill-subtle.json +0 -0
- /package/agent/{skills/red-teaming → optional-skills/security}/godmode/templates/prefill.json +0 -0
- /package/agent/{skills → optional-skills}/software-development/subagent-driven-development/references/context-budget-discipline.md +0 -0
- /package/agent/{skills → optional-skills}/software-development/subagent-driven-development/references/gates-taxonomy.md +0 -0
|
@@ -9,6 +9,7 @@ from __future__ import annotations
|
|
|
9
9
|
|
|
10
10
|
import json
|
|
11
11
|
import os
|
|
12
|
+
import urllib.parse
|
|
12
13
|
import urllib.request
|
|
13
14
|
import urllib.error
|
|
14
15
|
import time
|
|
@@ -52,12 +53,15 @@ OPENROUTER_MODELS: list[tuple[str, str]] = [
|
|
|
52
53
|
("deepseek/deepseek-v4-flash", ""),
|
|
53
54
|
# Qwen
|
|
54
55
|
("qwen/qwen3.7-max", ""),
|
|
56
|
+
("qwen/qwen3.7-plus", ""),
|
|
55
57
|
("qwen/qwen3.6-35b-a3b", ""),
|
|
56
58
|
# MoonshotAI
|
|
57
59
|
("moonshotai/kimi-k2.6", "recommended"),
|
|
60
|
+
("moonshotai/kimi-k2.7-code", ""),
|
|
58
61
|
# MiniMax
|
|
59
62
|
("minimax/minimax-m3", ""),
|
|
60
63
|
# Z-AI
|
|
64
|
+
("z-ai/glm-5.2", ""),
|
|
61
65
|
("z-ai/glm-5.1", ""),
|
|
62
66
|
# Xiaomi
|
|
63
67
|
("xiaomi/mimo-v2.5-pro", ""),
|
|
@@ -72,8 +76,10 @@ OPENROUTER_MODELS: list[tuple[str, str]] = [
|
|
|
72
76
|
# Free tier
|
|
73
77
|
("openrouter/elephant-alpha", "free"),
|
|
74
78
|
("openrouter/owl-alpha", "free"),
|
|
79
|
+
("poolside/laguna-m.1:free", "free"),
|
|
75
80
|
("tencent/hy3-preview:free", "free"),
|
|
76
81
|
("nvidia/nemotron-3-super-120b-a12b:free", "free"),
|
|
82
|
+
("nvidia/nemotron-3-ultra-550b-a55b:free", "free"),
|
|
77
83
|
("inclusionai/ring-2.6-1t:free", "free"),
|
|
78
84
|
]
|
|
79
85
|
|
|
@@ -104,14 +110,20 @@ def _codex_curated_models() -> list[str]:
|
|
|
104
110
|
# (grok-4, grok-4-0709, grok-4-fast{,-reasoning,-non-reasoning},
|
|
105
111
|
# grok-4-1-fast{,-reasoning,-non-reasoning}, grok-code-fast-1 → grok-4.3).
|
|
106
112
|
_XAI_STATIC_FALLBACK: list[str] = [
|
|
113
|
+
"grok-build-0.1",
|
|
107
114
|
"grok-4.3",
|
|
108
115
|
"grok-4.20-0309-reasoning",
|
|
109
116
|
"grok-4.20-0309-non-reasoning",
|
|
110
117
|
"grok-4.20-multi-agent-0309",
|
|
111
118
|
]
|
|
112
119
|
|
|
120
|
+
# Callable via xAI OAuth but omitted from models.dev and /v1/models listings.
|
|
121
|
+
_XAI_CURATED_EXTRAS: list[str] = [
|
|
122
|
+
"grok-composer-2.5-fast",
|
|
123
|
+
]
|
|
124
|
+
|
|
113
125
|
|
|
114
|
-
_XAI_TOP_MODEL = "grok-
|
|
126
|
+
_XAI_TOP_MODEL = "grok-build-0.1"
|
|
115
127
|
|
|
116
128
|
|
|
117
129
|
def _xai_promote_top(ids: list[str]) -> list[str]:
|
|
@@ -121,6 +133,18 @@ def _xai_promote_top(ids: list[str]) -> list[str]:
|
|
|
121
133
|
return ids
|
|
122
134
|
|
|
123
135
|
|
|
136
|
+
def _xai_merge_curated_extras(ids: list[str]) -> list[str]:
|
|
137
|
+
"""Append Hermes-curated xAI models that are missing from models.dev."""
|
|
138
|
+
out = list(ids)
|
|
139
|
+
for extra in _XAI_CURATED_EXTRAS:
|
|
140
|
+
if extra in out:
|
|
141
|
+
continue
|
|
142
|
+
# Keep the headline model pinned; slot extras immediately after it.
|
|
143
|
+
insert_at = 1 if out and out[0] == _XAI_TOP_MODEL else len(out)
|
|
144
|
+
out.insert(insert_at, extra)
|
|
145
|
+
return out
|
|
146
|
+
|
|
147
|
+
|
|
124
148
|
def _xai_curated_models() -> list[str]:
|
|
125
149
|
"""Derive the xAI-direct curated list from models.dev disk cache.
|
|
126
150
|
|
|
@@ -140,12 +164,12 @@ def _xai_curated_models() -> list[str]:
|
|
|
140
164
|
if isinstance(models, dict) and models:
|
|
141
165
|
ids = [mid for mid in models.keys() if isinstance(mid, str)]
|
|
142
166
|
if ids:
|
|
143
|
-
return _xai_promote_top(sorted(ids))
|
|
167
|
+
return _xai_merge_curated_extras(_xai_promote_top(sorted(ids)))
|
|
144
168
|
except Exception:
|
|
145
169
|
# Any failure (missing file, malformed JSON, import error)
|
|
146
170
|
# falls through to the static list.
|
|
147
171
|
pass
|
|
148
|
-
return list(_XAI_STATIC_FALLBACK)
|
|
172
|
+
return _xai_merge_curated_extras(list(_XAI_STATIC_FALLBACK))
|
|
149
173
|
|
|
150
174
|
|
|
151
175
|
_PROVIDER_MODELS: dict[str, list[str]] = {
|
|
@@ -169,12 +193,15 @@ _PROVIDER_MODELS: dict[str, list[str]] = {
|
|
|
169
193
|
"deepseek/deepseek-v4-flash",
|
|
170
194
|
# Qwen
|
|
171
195
|
"qwen/qwen3.7-max",
|
|
196
|
+
"qwen/qwen3.7-plus",
|
|
172
197
|
"qwen/qwen3.6-35b-a3b",
|
|
173
198
|
# MoonshotAI
|
|
174
199
|
"moonshotai/kimi-k2.6",
|
|
200
|
+
"moonshotai/kimi-k2.7-code",
|
|
175
201
|
# MiniMax
|
|
176
202
|
"minimax/minimax-m3",
|
|
177
203
|
# Z-AI
|
|
204
|
+
"z-ai/glm-5.2",
|
|
178
205
|
"z-ai/glm-5.1",
|
|
179
206
|
# Xiaomi
|
|
180
207
|
"xiaomi/mimo-v2.5-pro",
|
|
@@ -241,9 +268,16 @@ _PROVIDER_MODELS: dict[str, list[str]] = {
|
|
|
241
268
|
"google-gemini-cli": [
|
|
242
269
|
"gemini-3.1-pro-preview",
|
|
243
270
|
"gemini-3-pro-preview",
|
|
271
|
+
# Code Assist serves two flash slugs with different access gates
|
|
272
|
+
# (gemini-cli models.ts): gemini-3-flash-preview is the preview flash
|
|
273
|
+
# that subscription/free-tier OAuth users actually reach, while
|
|
274
|
+
# gemini-3.5-flash is GA-channel-gated. Offer both so non-GA users
|
|
275
|
+
# aren't stuck with a slug cloudcode-pa 404s for them.
|
|
276
|
+
"gemini-3-flash-preview",
|
|
244
277
|
"gemini-3.5-flash",
|
|
245
278
|
],
|
|
246
279
|
"zai": [
|
|
280
|
+
"glm-5.2",
|
|
247
281
|
"glm-5.1",
|
|
248
282
|
"glm-5",
|
|
249
283
|
"glm-5v-turbo",
|
|
@@ -268,6 +302,7 @@ _PROVIDER_MODELS: dict[str, list[str]] = {
|
|
|
268
302
|
"openai/gpt-oss-120b",
|
|
269
303
|
],
|
|
270
304
|
"kimi-coding": [
|
|
305
|
+
"kimi-k2.7-code",
|
|
271
306
|
"kimi-k2.6",
|
|
272
307
|
"kimi-k2.5",
|
|
273
308
|
"kimi-for-coding",
|
|
@@ -314,6 +349,7 @@ _PROVIDER_MODELS: dict[str, list[str]] = {
|
|
|
314
349
|
"MiniMax-M2",
|
|
315
350
|
],
|
|
316
351
|
"anthropic": [
|
|
352
|
+
"claude-fable-5",
|
|
317
353
|
"claude-opus-4-8",
|
|
318
354
|
"claude-opus-4-7",
|
|
319
355
|
"claude-opus-4-6",
|
|
@@ -582,7 +618,8 @@ def union_with_portal_free_recommendations(
|
|
|
582
618
|
pair where:
|
|
583
619
|
|
|
584
620
|
* Portal free recommendations missing from ``curated_ids`` are
|
|
585
|
-
appended
|
|
621
|
+
appended after the curated list (so the in-repo curated models
|
|
622
|
+
show first and Portal-only picks follow).
|
|
586
623
|
* ``pricing`` gets a synthetic ``{"prompt": "0", "completion": "0"}``
|
|
587
624
|
entry for any free recommendation missing from the live pricing
|
|
588
625
|
map, so :func:`partition_nous_models_by_tier` keeps it.
|
|
@@ -617,11 +654,11 @@ def union_with_portal_free_recommendations(
|
|
|
617
654
|
|
|
618
655
|
augmented_ids = list(curated_ids)
|
|
619
656
|
seen = set(augmented_ids)
|
|
620
|
-
#
|
|
621
|
-
#
|
|
657
|
+
# Append Portal free recommendations that aren't already curated, so the
|
|
658
|
+
# in-repo curated ("HA") models show first and Portal-only picks follow.
|
|
622
659
|
new_ones = [mid for mid in portal_free_ids if mid not in seen]
|
|
623
660
|
if new_ones:
|
|
624
|
-
augmented_ids =
|
|
661
|
+
augmented_ids = augmented_ids + new_ones
|
|
625
662
|
|
|
626
663
|
return (augmented_ids, augmented_pricing)
|
|
627
664
|
|
|
@@ -647,7 +684,8 @@ def union_with_portal_paid_recommendations(
|
|
|
647
684
|
``(model_ids, pricing)`` pair where:
|
|
648
685
|
|
|
649
686
|
* Portal paid recommendations missing from ``curated_ids`` are
|
|
650
|
-
appended
|
|
687
|
+
appended after the curated list (so the in-repo curated models
|
|
688
|
+
show first and Portal-only picks follow).
|
|
651
689
|
* ``pricing`` is left untouched — we deliberately do NOT synthesize
|
|
652
690
|
pricing entries for paid models. Live pricing is fetched separately
|
|
653
691
|
via :func:`get_pricing_for_provider`; if the live endpoint hasn't
|
|
@@ -682,11 +720,11 @@ def union_with_portal_paid_recommendations(
|
|
|
682
720
|
|
|
683
721
|
augmented_ids = list(curated_ids)
|
|
684
722
|
seen = set(augmented_ids)
|
|
685
|
-
#
|
|
686
|
-
#
|
|
723
|
+
# Append Portal paid recommendations that aren't already curated, so the
|
|
724
|
+
# in-repo curated ("HA") models show first and Portal-only picks follow.
|
|
687
725
|
new_ones = [mid for mid in portal_paid_ids if mid not in seen]
|
|
688
726
|
if new_ones:
|
|
689
|
-
augmented_ids =
|
|
727
|
+
augmented_ids = augmented_ids + new_ones
|
|
690
728
|
|
|
691
729
|
return (augmented_ids, dict(pricing))
|
|
692
730
|
|
|
@@ -754,6 +792,64 @@ _NOUS_RECOMMENDED_CACHE_TTL: int = 600 # seconds (10 minutes)
|
|
|
754
792
|
_nous_recommended_cache: dict[str, tuple[dict[str, Any], float]] = {}
|
|
755
793
|
|
|
756
794
|
|
|
795
|
+
def _nous_recommended_disk_path() -> "Path":
|
|
796
|
+
"""Disk path for the persisted recommended-models cache."""
|
|
797
|
+
from hermes_constants import get_hermes_home
|
|
798
|
+
return get_hermes_home() / "cache" / "nous_recommended_cache.json"
|
|
799
|
+
|
|
800
|
+
|
|
801
|
+
def _read_nous_recommended_disk(base: str) -> dict[str, Any] | None:
|
|
802
|
+
"""Return the last-known-good payload for ``base`` from disk, or None.
|
|
803
|
+
|
|
804
|
+
The disk file is a JSON object keyed by portal base URL so staging and
|
|
805
|
+
prod don't collide:
|
|
806
|
+
``{"<base>": {"data": {...}, "ts": <epoch_seconds>}}``.
|
|
807
|
+
"""
|
|
808
|
+
try:
|
|
809
|
+
with open(_nous_recommended_disk_path(), encoding="utf-8") as fh:
|
|
810
|
+
blob = json.load(fh)
|
|
811
|
+
except (OSError, json.JSONDecodeError):
|
|
812
|
+
return None
|
|
813
|
+
if not isinstance(blob, dict):
|
|
814
|
+
return None
|
|
815
|
+
entry = blob.get(base)
|
|
816
|
+
if not isinstance(entry, dict):
|
|
817
|
+
return None
|
|
818
|
+
data = entry.get("data")
|
|
819
|
+
return data if isinstance(data, dict) and data else None
|
|
820
|
+
|
|
821
|
+
|
|
822
|
+
def _write_nous_recommended_disk(base: str, data: dict[str, Any]) -> None:
|
|
823
|
+
"""Persist ``data`` as the last-known-good payload for ``base``.
|
|
824
|
+
|
|
825
|
+
Merges into any existing per-base map, then writes atomically. Failures
|
|
826
|
+
are non-fatal (logged at debug) — the in-process cache still works.
|
|
827
|
+
"""
|
|
828
|
+
if not data:
|
|
829
|
+
return
|
|
830
|
+
path = _nous_recommended_disk_path()
|
|
831
|
+
try:
|
|
832
|
+
try:
|
|
833
|
+
with open(path, encoding="utf-8") as fh:
|
|
834
|
+
blob = json.load(fh)
|
|
835
|
+
if not isinstance(blob, dict):
|
|
836
|
+
blob = {}
|
|
837
|
+
except (OSError, json.JSONDecodeError):
|
|
838
|
+
blob = {}
|
|
839
|
+
blob[base] = {"data": data, "ts": time.time()}
|
|
840
|
+
path.parent.mkdir(parents=True, exist_ok=True)
|
|
841
|
+
tmp = path.with_suffix(path.suffix + ".tmp")
|
|
842
|
+
with open(tmp, "w", encoding="utf-8") as fh:
|
|
843
|
+
json.dump(blob, fh, indent=2)
|
|
844
|
+
fh.write("\n")
|
|
845
|
+
os.replace(tmp, path)
|
|
846
|
+
except OSError as exc:
|
|
847
|
+
import logging
|
|
848
|
+
logging.getLogger(__name__).debug(
|
|
849
|
+
"nous recommended-models disk cache write failed: %s", exc
|
|
850
|
+
)
|
|
851
|
+
|
|
852
|
+
|
|
757
853
|
def fetch_nous_recommended_models(
|
|
758
854
|
portal_base_url: str = "",
|
|
759
855
|
timeout: float = 5.0,
|
|
@@ -764,12 +860,19 @@ def fetch_nous_recommended_models(
|
|
|
764
860
|
|
|
765
861
|
Hits ``<portal>/api/nous/recommended-models``. The endpoint is public —
|
|
766
862
|
no auth is required. Results are cached per portal URL for
|
|
767
|
-
``_NOUS_RECOMMENDED_CACHE_TTL`` seconds; pass
|
|
768
|
-
bypass the cache.
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
(
|
|
772
|
-
|
|
863
|
+
``_NOUS_RECOMMENDED_CACHE_TTL`` seconds in process; pass
|
|
864
|
+
``force_refresh=True`` to bypass the in-process cache.
|
|
865
|
+
|
|
866
|
+
A successful live fetch is also persisted to a per-base disk cache
|
|
867
|
+
(``$HERMES_HOME/cache/nous_recommended_cache.json``) as last-known-good.
|
|
868
|
+
When the live fetch fails (network, parse, non-2xx) and the in-process
|
|
869
|
+
cache is empty, the disk copy is returned instead of ``{}`` — so a
|
|
870
|
+
transient Portal hiccup no longer silently drops the free/paid model
|
|
871
|
+
recommendations from the picker. Self-heals on the next successful fetch.
|
|
872
|
+
|
|
873
|
+
Returns the parsed JSON dict, or ``{}`` only when neither the network nor
|
|
874
|
+
any cache layer can supply data. Callers must treat missing/null fields
|
|
875
|
+
as "no recommendation" and fall back to their own default.
|
|
773
876
|
"""
|
|
774
877
|
base = (portal_base_url or "https://portal.nousresearch.com").rstrip("/")
|
|
775
878
|
now = time.monotonic()
|
|
@@ -792,6 +895,19 @@ def fetch_nous_recommended_models(
|
|
|
792
895
|
except Exception:
|
|
793
896
|
data = {}
|
|
794
897
|
|
|
898
|
+
if data:
|
|
899
|
+
# Live fetch succeeded — refresh both cache layers.
|
|
900
|
+
_nous_recommended_cache[base] = (data, now)
|
|
901
|
+
_write_nous_recommended_disk(base, data)
|
|
902
|
+
return data
|
|
903
|
+
|
|
904
|
+
# Live fetch failed. Fall back to the last-known-good disk copy so a
|
|
905
|
+
# transient Portal hiccup doesn't drop the recommendations entirely.
|
|
906
|
+
disk = _read_nous_recommended_disk(base)
|
|
907
|
+
if disk:
|
|
908
|
+
_nous_recommended_cache[base] = (disk, now)
|
|
909
|
+
return disk
|
|
910
|
+
|
|
795
911
|
_nous_recommended_cache[base] = (data, now)
|
|
796
912
|
return data
|
|
797
913
|
|
|
@@ -1140,17 +1256,46 @@ _PROVIDER_ALIASES = {
|
|
|
1140
1256
|
}
|
|
1141
1257
|
|
|
1142
1258
|
|
|
1143
|
-
|
|
1144
|
-
|
|
1259
|
+
# Cost-safe overrides for the *silent* auto-default
|
|
1260
|
+
# (``get_default_model_for_provider``). Most providers' curated lists lead with a
|
|
1261
|
+
# sensible default, but Nous Portal is a per-token *metered aggregator* whose
|
|
1262
|
+
# list is ordered best-/most-capable-first — entry [0] is the priciest flagship
|
|
1263
|
+
# (``anthropic/claude-opus-4.8``, $5/$25 per Mtok). Using that as the
|
|
1264
|
+
# non-interactive fallback when a profile sets ``provider: nous`` with no model
|
|
1265
|
+
# silently bills the most expensive model for traffic the user never opted into
|
|
1266
|
+
# (a missing default escalated to Opus and billed 863 requests before the user
|
|
1267
|
+
# noticed). Pin the silent default to a low-cost curated model instead so a
|
|
1268
|
+
# missing model can never escalate to the flagship.
|
|
1269
|
+
#
|
|
1270
|
+
# This is deliberately a fixed, side-effect-free default for the hot resolution
|
|
1271
|
+
# path. The *interactive* default (GUI onboarding / ``hermes model``) uses the
|
|
1272
|
+
# richer free/paid-tier-aware resolver — see ``get_recommended_default_model``
|
|
1273
|
+
# in hermes_cli/web_server.py and ``partition_nous_models_by_tier`` — which can
|
|
1274
|
+
# hit the Portal; this fallback must stay cheap and network-free.
|
|
1275
|
+
_PROVIDER_SILENT_DEFAULT_OVERRIDES: dict[str, str] = {
|
|
1276
|
+
"nous": "deepseek/deepseek-v4-flash",
|
|
1277
|
+
}
|
|
1145
1278
|
|
|
1146
|
-
Uses the first entry in _PROVIDER_MODELS as the default. This is the
|
|
1147
|
-
model a user would be offered first in the ``hermes model`` picker.
|
|
1148
1279
|
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1280
|
+
def get_default_model_for_provider(provider: str) -> str:
|
|
1281
|
+
"""Return a cost-safe default model for a provider, or "" if unknown.
|
|
1282
|
+
|
|
1283
|
+
Used as a NON-INTERACTIVE fallback when a provider is configured but no
|
|
1284
|
+
model was ever selected (e.g. ``hermes auth add openai-codex`` without
|
|
1285
|
+
``hermes model``, or a profile that sets ``provider`` with no ``model``).
|
|
1286
|
+
|
|
1287
|
+
For most providers this is the first entry in ``_PROVIDER_MODELS`` — the
|
|
1288
|
+
same model the ``hermes model`` picker offers first. For metered aggregators
|
|
1289
|
+
whose curated list is ordered most-capable-first, that entry is also the
|
|
1290
|
+
most EXPENSIVE one, so silently defaulting to it is a billing footgun. Such
|
|
1291
|
+
providers carry an explicit low-cost override in
|
|
1292
|
+
``_PROVIDER_SILENT_DEFAULT_OVERRIDES``; a missing model must never
|
|
1293
|
+
auto-escalate to the flagship.
|
|
1152
1294
|
"""
|
|
1153
1295
|
models = _PROVIDER_MODELS.get(provider, [])
|
|
1296
|
+
override = _PROVIDER_SILENT_DEFAULT_OVERRIDES.get(provider)
|
|
1297
|
+
if override and override in models:
|
|
1298
|
+
return override
|
|
1154
1299
|
return models[0] if models else ""
|
|
1155
1300
|
|
|
1156
1301
|
|
|
@@ -1568,15 +1713,36 @@ def parse_model_input(raw: str, current_provider: str) -> tuple[str, str]:
|
|
|
1568
1713
|
|
|
1569
1714
|
def _get_custom_base_url() -> str:
|
|
1570
1715
|
"""Get the custom endpoint base_url from config.yaml."""
|
|
1716
|
+
model_cfg = _get_model_config_dict()
|
|
1717
|
+
return str(model_cfg.get("base_url", "")).strip()
|
|
1718
|
+
|
|
1719
|
+
|
|
1720
|
+
def _get_model_config_dict() -> dict[str, Any]:
|
|
1721
|
+
"""Return the main model config mapping, or an empty dict."""
|
|
1571
1722
|
try:
|
|
1572
1723
|
from hermes_cli.config import load_config
|
|
1573
1724
|
config = load_config()
|
|
1574
1725
|
model_cfg = config.get("model", {})
|
|
1575
1726
|
if isinstance(model_cfg, dict):
|
|
1576
|
-
return
|
|
1727
|
+
return model_cfg
|
|
1577
1728
|
except Exception:
|
|
1578
1729
|
pass
|
|
1579
|
-
return
|
|
1730
|
+
return {}
|
|
1731
|
+
|
|
1732
|
+
|
|
1733
|
+
def _base_url_looks_like_anthropic_messages(base_url: str) -> bool:
|
|
1734
|
+
normalized = str(base_url or "").strip().lower().rstrip("/")
|
|
1735
|
+
if not normalized:
|
|
1736
|
+
return False
|
|
1737
|
+
path = urllib.parse.urlparse(normalized).path.rstrip("/")
|
|
1738
|
+
return path.endswith("/anthropic") or path.endswith("/anthropic/v1")
|
|
1739
|
+
|
|
1740
|
+
|
|
1741
|
+
def _anthropic_models_url(base_url: Optional[str] = None) -> str:
|
|
1742
|
+
endpoint = str(base_url or "https://api.anthropic.com").strip().rstrip("/")
|
|
1743
|
+
if endpoint.endswith("/v1"):
|
|
1744
|
+
return endpoint + "/models"
|
|
1745
|
+
return endpoint + "/v1/models"
|
|
1580
1746
|
|
|
1581
1747
|
|
|
1582
1748
|
def curated_models_for_provider(
|
|
@@ -1862,19 +2028,21 @@ def model_supports_fast_mode(model_id: Optional[str]) -> bool:
|
|
|
1862
2028
|
|
|
1863
2029
|
|
|
1864
2030
|
def _is_anthropic_fast_model(model_id: Optional[str]) -> bool:
|
|
1865
|
-
"""Return True if the model
|
|
1866
|
-
|
|
1867
|
-
|
|
1868
|
-
|
|
1869
|
-
"
|
|
1870
|
-
|
|
1871
|
-
|
|
2031
|
+
"""Return True if the model accepts the Anthropic Fast Mode ``speed`` param.
|
|
2032
|
+
|
|
2033
|
+
This gates the *speed=fast request parameter*, which Anthropic supports on
|
|
2034
|
+
Opus 4.6 only (Opus 4.7 explicitly 400s). It is deliberately NOT a general
|
|
2035
|
+
"is this a fast model" check: for Opus 4.8 the fast offering is a SEPARATE
|
|
2036
|
+
model id (``…-opus-4.8-fast``) selected via the model field, not the speed
|
|
2037
|
+
parameter — see ``agent.anthropic_adapter._supports_fast_mode`` and its
|
|
2038
|
+
test. Keep this in lock-step with that adapter gate so the UI never shows a
|
|
2039
|
+
Fast toggle that the runtime would silently drop.
|
|
1872
2040
|
"""
|
|
1873
2041
|
raw = _strip_vendor_prefix(str(model_id or ""))
|
|
1874
2042
|
base = raw.split(":")[0]
|
|
1875
2043
|
if not base.startswith("claude-"):
|
|
1876
2044
|
return False
|
|
1877
|
-
# Only Opus 4.6 supports fast
|
|
2045
|
+
# Only Opus 4.6 supports the speed=fast parameter at present.
|
|
1878
2046
|
return "opus-4-6" in base or "opus-4.6" in base
|
|
1879
2047
|
|
|
1880
2048
|
|
|
@@ -2094,9 +2262,35 @@ def provider_model_ids(provider: Optional[str], *, force_refresh: bool = False)
|
|
|
2094
2262
|
except Exception:
|
|
2095
2263
|
pass
|
|
2096
2264
|
if normalized == "anthropic":
|
|
2097
|
-
|
|
2265
|
+
model_cfg = _get_model_config_dict()
|
|
2266
|
+
cfg_provider = normalize_provider(str(model_cfg.get("provider", "") or ""))
|
|
2267
|
+
if cfg_provider == "anthropic":
|
|
2268
|
+
cfg_base_url = str(model_cfg.get("base_url", "") or "").strip()
|
|
2269
|
+
cfg_api_key = str(model_cfg.get("api_key", "") or "").strip()
|
|
2270
|
+
else:
|
|
2271
|
+
cfg_base_url = ""
|
|
2272
|
+
cfg_api_key = ""
|
|
2273
|
+
live = _fetch_anthropic_models(
|
|
2274
|
+
base_url=cfg_base_url or None,
|
|
2275
|
+
api_key=cfg_api_key or None,
|
|
2276
|
+
)
|
|
2098
2277
|
if live:
|
|
2099
|
-
|
|
2278
|
+
if cfg_base_url:
|
|
2279
|
+
return live
|
|
2280
|
+
# The live /v1/models dump lags newly-routed curated aliases
|
|
2281
|
+
# (e.g. claude-fable-5, which is reachable on Anthropic before it
|
|
2282
|
+
# is enumerated by the models endpoint). Surface curated entries
|
|
2283
|
+
# first, then append any live-only models, so a fresh curated
|
|
2284
|
+
# model never disappears just because the API hasn't listed it yet.
|
|
2285
|
+
curated = list(_PROVIDER_MODELS.get("anthropic", []))
|
|
2286
|
+
merged = list(curated)
|
|
2287
|
+
merged_lower = {m.lower() for m in curated}
|
|
2288
|
+
for m in live:
|
|
2289
|
+
if m.lower() not in merged_lower:
|
|
2290
|
+
merged.append(m)
|
|
2291
|
+
merged_lower.add(m.lower())
|
|
2292
|
+
return merged
|
|
2293
|
+
return list(_PROVIDER_MODELS.get("anthropic", []))
|
|
2100
2294
|
if normalized == "ollama-cloud":
|
|
2101
2295
|
live = fetch_ollama_cloud_models(force_refresh=force_refresh)
|
|
2102
2296
|
if live:
|
|
@@ -2151,13 +2345,16 @@ def provider_model_ids(provider: Optional[str], *, force_refresh: bool = False)
|
|
|
2151
2345
|
if normalized == "custom":
|
|
2152
2346
|
base_url = _get_custom_base_url()
|
|
2153
2347
|
if base_url:
|
|
2348
|
+
model_cfg = _get_model_config_dict()
|
|
2154
2349
|
# Try common API key env vars for custom endpoints
|
|
2155
2350
|
api_key = (
|
|
2156
|
-
|
|
2351
|
+
str(model_cfg.get("api_key", "") or "").strip()
|
|
2352
|
+
or os.getenv("CUSTOM_API_KEY", "")
|
|
2157
2353
|
or os.getenv("OPENAI_API_KEY", "")
|
|
2158
2354
|
or os.getenv("OPENROUTER_API_KEY", "")
|
|
2159
2355
|
)
|
|
2160
|
-
|
|
2356
|
+
api_mode = "anthropic_messages" if _base_url_looks_like_anthropic_messages(base_url) else None
|
|
2357
|
+
live = fetch_api_models(api_key, base_url, api_mode=api_mode)
|
|
2161
2358
|
if live:
|
|
2162
2359
|
return live
|
|
2163
2360
|
# Bedrock uses live discovery keyed by the resolved AWS region so that
|
|
@@ -2191,8 +2388,24 @@ def provider_model_ids(provider: Optional[str], *, force_refresh: bool = False)
|
|
|
2191
2388
|
if not base_url:
|
|
2192
2389
|
base_url = _p.base_url
|
|
2193
2390
|
if api_key:
|
|
2194
|
-
live = _p.fetch_models(api_key=api_key)
|
|
2391
|
+
live = _p.fetch_models(api_key=api_key, base_url=base_url or None)
|
|
2195
2392
|
if live:
|
|
2393
|
+
# Merge static curated list with live API results so
|
|
2394
|
+
# models that the live endpoint omits (stale cache,
|
|
2395
|
+
# partial rollout) still appear in the picker.
|
|
2396
|
+
# Curated entries come first so deliberately-surfaced
|
|
2397
|
+
# newest models (e.g. kimi-k2.7-code, #46309) stay at
|
|
2398
|
+
# the top of the picker; live-only entries are appended
|
|
2399
|
+
# afterwards for discovery. (#46850)
|
|
2400
|
+
curated = list(_PROVIDER_MODELS.get(normalized, []))
|
|
2401
|
+
if curated:
|
|
2402
|
+
merged = list(curated)
|
|
2403
|
+
merged_lower = {m.lower() for m in curated}
|
|
2404
|
+
for m in live:
|
|
2405
|
+
if m.lower() not in merged_lower:
|
|
2406
|
+
merged.append(m)
|
|
2407
|
+
merged_lower.add(m.lower())
|
|
2408
|
+
return merged
|
|
2196
2409
|
return live
|
|
2197
2410
|
# Use profile's fallback_models if defined
|
|
2198
2411
|
if _p.fallback_models:
|
|
@@ -2406,18 +2619,24 @@ def clear_provider_models_cache(provider: Optional[str] = None) -> None:
|
|
|
2406
2619
|
pass
|
|
2407
2620
|
|
|
2408
2621
|
|
|
2409
|
-
def _fetch_anthropic_models(
|
|
2622
|
+
def _fetch_anthropic_models(
|
|
2623
|
+
timeout: float = 5.0,
|
|
2624
|
+
*,
|
|
2625
|
+
base_url: Optional[str] = None,
|
|
2626
|
+
api_key: Optional[str] = None,
|
|
2627
|
+
) -> Optional[list[str]]:
|
|
2410
2628
|
"""Fetch available models from the Anthropic /v1/models endpoint.
|
|
2411
2629
|
|
|
2412
2630
|
Uses resolve_anthropic_token() to find credentials (env vars or
|
|
2413
|
-
Claude Code auto-discovery)
|
|
2631
|
+
Claude Code auto-discovery) unless api_key is provided explicitly.
|
|
2632
|
+
Returns sorted model IDs or None.
|
|
2414
2633
|
"""
|
|
2415
2634
|
try:
|
|
2416
2635
|
from agent.anthropic_adapter import resolve_anthropic_token, _is_oauth_token
|
|
2417
2636
|
except ImportError:
|
|
2418
2637
|
return None
|
|
2419
2638
|
|
|
2420
|
-
token = resolve_anthropic_token()
|
|
2639
|
+
token = (api_key or "").strip() or resolve_anthropic_token()
|
|
2421
2640
|
if not token:
|
|
2422
2641
|
return None
|
|
2423
2642
|
|
|
@@ -2432,7 +2651,7 @@ def _fetch_anthropic_models(timeout: float = 5.0) -> Optional[list[str]]:
|
|
|
2432
2651
|
|
|
2433
2652
|
def _do_request(h: dict[str, str]):
|
|
2434
2653
|
req = urllib.request.Request(
|
|
2435
|
-
|
|
2654
|
+
_anthropic_models_url(base_url),
|
|
2436
2655
|
headers=h,
|
|
2437
2656
|
)
|
|
2438
2657
|
with urllib.request.urlopen(req, timeout=timeout) as resp:
|
|
@@ -3622,7 +3841,10 @@ def validate_requested_model(
|
|
|
3622
3841
|
# tokens. (The api_mode=="anthropic_messages" branch below handles the
|
|
3623
3842
|
# Messages-API transport case separately.)
|
|
3624
3843
|
if normalized == "anthropic":
|
|
3625
|
-
anthropic_models = _fetch_anthropic_models(
|
|
3844
|
+
anthropic_models = _fetch_anthropic_models(
|
|
3845
|
+
base_url=base_url or None,
|
|
3846
|
+
api_key=api_key or None,
|
|
3847
|
+
)
|
|
3626
3848
|
if anthropic_models is not None:
|
|
3627
3849
|
if requested_for_lookup in set(anthropic_models):
|
|
3628
3850
|
return {
|
|
@@ -3739,6 +3961,24 @@ def validate_requested_model(
|
|
|
3739
3961
|
if suggestions:
|
|
3740
3962
|
suggestion_text = "\n Similar models: " + ", ".join(f"`{s}`" for s in suggestions)
|
|
3741
3963
|
|
|
3964
|
+
# Model not in live /v1/models — check the curated catalog
|
|
3965
|
+
# before rejecting. Providers may omit models from their live
|
|
3966
|
+
# listing that are still valid (stale cache, partial rollout,
|
|
3967
|
+
# gated previews). Use the pure-catalog helper (no extra live
|
|
3968
|
+
# fetch) so we only accept models Hermes actually ships. (#46850)
|
|
3969
|
+
if _model_in_provider_catalog(
|
|
3970
|
+
requested_for_lookup.lower(), _provider_keys(normalized)
|
|
3971
|
+
):
|
|
3972
|
+
return {
|
|
3973
|
+
"accepted": True,
|
|
3974
|
+
"persist": True,
|
|
3975
|
+
"recognized": True,
|
|
3976
|
+
"message": (
|
|
3977
|
+
f"Note: `{requested}` was not found in the live /v1/models listing "
|
|
3978
|
+
f"but exists in the curated catalog — accepted."
|
|
3979
|
+
),
|
|
3980
|
+
}
|
|
3981
|
+
|
|
3742
3982
|
return {
|
|
3743
3983
|
"accepted": False,
|
|
3744
3984
|
"persist": False,
|
|
@@ -38,6 +38,7 @@ class NousPortalSubscriptionInfo:
|
|
|
38
38
|
plan: Optional[str] = None
|
|
39
39
|
tier: Optional[int] = None
|
|
40
40
|
monthly_charge: Optional[float] = None
|
|
41
|
+
monthly_credits: Optional[float] = None
|
|
41
42
|
current_period_end: Optional[str] = None
|
|
42
43
|
credits_remaining: Optional[float] = None
|
|
43
44
|
rollover_credits: Optional[float] = None
|
|
@@ -79,6 +80,8 @@ class NousPortalAccountInfo:
|
|
|
79
80
|
fresh: bool
|
|
80
81
|
user_id: Optional[str] = None
|
|
81
82
|
org_id: Optional[str] = None
|
|
83
|
+
org_slug: Optional[str] = None
|
|
84
|
+
org_name: Optional[str] = None
|
|
82
85
|
client_id: Optional[str] = None
|
|
83
86
|
product_id: Optional[str] = None
|
|
84
87
|
nous_client: Optional[str] = None
|
|
@@ -139,6 +142,29 @@ def nous_portal_billing_url(account_info: Optional[NousPortalAccountInfo] = None
|
|
|
139
142
|
return f"{base.rstrip('/')}/billing"
|
|
140
143
|
|
|
141
144
|
|
|
145
|
+
def nous_portal_topup_url(account_info: Optional[NousPortalAccountInfo] = None) -> str:
|
|
146
|
+
"""Return the portal top-up URL that auto-opens the top-up modal.
|
|
147
|
+
|
|
148
|
+
Prefers the org-pinned page ``{base}/orgs/{slug}/billing?topup=open`` (skips
|
|
149
|
+
the legacy shim's re-resolution + multi-org disambiguation). Falls back to the
|
|
150
|
+
legacy ``{base}/billing?topup=open`` when the account has no ``org_slug`` (the
|
|
151
|
+
portal's ``slug`` is nullable; the legacy page forwards the param through to
|
|
152
|
+
the org-pinned page). Never builds ``/orgs/None/billing``.
|
|
153
|
+
|
|
154
|
+
The ``?topup=open`` query is the NAS enabler that lands the user in the
|
|
155
|
+
top-up flow rather than just on the billing page.
|
|
156
|
+
"""
|
|
157
|
+
base_billing = nous_portal_billing_url(account_info) # {base}/billing
|
|
158
|
+
base = base_billing[: -len("/billing")] # strip the trailing /billing
|
|
159
|
+
|
|
160
|
+
slug = getattr(account_info, "org_slug", None) if account_info is not None else None
|
|
161
|
+
if isinstance(slug, str) and slug.strip():
|
|
162
|
+
from urllib.parse import quote
|
|
163
|
+
|
|
164
|
+
return f"{base}/orgs/{quote(slug.strip(), safe='')}/billing?topup=open"
|
|
165
|
+
return f"{base}/billing?topup=open"
|
|
166
|
+
|
|
167
|
+
|
|
142
168
|
def format_nous_portal_entitlement_message(
|
|
143
169
|
account_info: Optional[NousPortalAccountInfo],
|
|
144
170
|
*,
|
|
@@ -606,12 +632,10 @@ def _info_from_account_payload(
|
|
|
606
632
|
state: dict[str, Any],
|
|
607
633
|
portal_base_url: Optional[str],
|
|
608
634
|
) -> NousPortalAccountInfo:
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
else {}
|
|
614
|
-
)
|
|
635
|
+
raw_user = payload.get("user")
|
|
636
|
+
user: dict[str, Any] = raw_user if isinstance(raw_user, dict) else {}
|
|
637
|
+
raw_org = payload.get("organisation")
|
|
638
|
+
organisation: dict[str, Any] = raw_org if isinstance(raw_org, dict) else {}
|
|
615
639
|
subscription = _subscription_from_payload(payload.get("subscription"))
|
|
616
640
|
access = _paid_service_access_from_payload(payload.get("paid_service_access"))
|
|
617
641
|
paid_access = access.allowed if access else None
|
|
@@ -623,6 +647,8 @@ def _info_from_account_payload(
|
|
|
623
647
|
source="account_api",
|
|
624
648
|
fresh=True,
|
|
625
649
|
org_id=_coerce_str(organisation.get("id")) or (access.organisation_id if access else None),
|
|
650
|
+
org_slug=_coerce_str(organisation.get("slug")),
|
|
651
|
+
org_name=_coerce_str(organisation.get("name")),
|
|
626
652
|
client_id=_coerce_str(state.get("client_id")),
|
|
627
653
|
portal_base_url=portal_base_url,
|
|
628
654
|
inference_base_url=_coerce_str(state.get("inference_base_url")),
|
|
@@ -662,6 +688,7 @@ def _subscription_from_payload(value: Any) -> Optional[NousPortalSubscriptionInf
|
|
|
662
688
|
plan=_coerce_str(value.get("plan")),
|
|
663
689
|
tier=_coerce_int(value.get("tier")),
|
|
664
690
|
monthly_charge=_coerce_float(value.get("monthly_charge")),
|
|
691
|
+
monthly_credits=_coerce_float(value.get("monthly_credits")),
|
|
665
692
|
current_period_end=_coerce_str(value.get("current_period_end")),
|
|
666
693
|
credits_remaining=_coerce_float(value.get("credits_remaining")),
|
|
667
694
|
rollover_credits=_coerce_float(value.get("rollover_credits")),
|