agent-orcha 0.0.5 → 0.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +250 -1275
- package/dist/lib/agents/agent-executor.d.ts +4 -2
- package/dist/lib/agents/agent-executor.d.ts.map +1 -1
- package/dist/lib/agents/agent-executor.js +85 -53
- package/dist/lib/agents/agent-executor.js.map +1 -1
- package/dist/lib/agents/agent-loader.d.ts +3 -0
- package/dist/lib/agents/agent-loader.d.ts.map +1 -1
- package/dist/lib/agents/agent-loader.js +10 -1
- package/dist/lib/agents/agent-loader.js.map +1 -1
- package/dist/lib/agents/react-loop.d.ts.map +1 -1
- package/dist/lib/agents/react-loop.js +207 -142
- package/dist/lib/agents/react-loop.js.map +1 -1
- package/dist/lib/agents/types.d.ts +181 -18
- package/dist/lib/agents/types.d.ts.map +1 -1
- package/dist/lib/agents/types.js +18 -2
- package/dist/lib/agents/types.js.map +1 -1
- package/dist/lib/functions/function-loader.d.ts +2 -0
- package/dist/lib/functions/function-loader.d.ts.map +1 -1
- package/dist/lib/functions/function-loader.js +10 -0
- package/dist/lib/functions/function-loader.js.map +1 -1
- package/dist/lib/functions/simple-function-wrapper.js +3 -3
- package/dist/lib/functions/simple-function-wrapper.js.map +1 -1
- package/dist/lib/integrations/email.d.ts +38 -0
- package/dist/lib/integrations/email.d.ts.map +1 -0
- package/dist/lib/integrations/email.js +249 -0
- package/dist/lib/integrations/email.js.map +1 -0
- package/dist/lib/integrations/integration-manager.d.ts +5 -0
- package/dist/lib/integrations/integration-manager.d.ts.map +1 -1
- package/dist/lib/integrations/integration-manager.js +53 -3
- package/dist/lib/integrations/integration-manager.js.map +1 -1
- package/dist/lib/integrations/types.d.ts +187 -4
- package/dist/lib/integrations/types.d.ts.map +1 -1
- package/dist/lib/integrations/types.js +24 -1
- package/dist/lib/integrations/types.js.map +1 -1
- package/dist/lib/knowledge/knowledge-store.d.ts +7 -1
- package/dist/lib/knowledge/knowledge-store.d.ts.map +1 -1
- package/dist/lib/knowledge/knowledge-store.js +96 -8
- package/dist/lib/knowledge/knowledge-store.js.map +1 -1
- package/dist/lib/knowledge/loaders/file-loaders.d.ts +8 -3
- package/dist/lib/knowledge/loaders/file-loaders.d.ts.map +1 -1
- package/dist/lib/knowledge/loaders/file-loaders.js +96 -75
- package/dist/lib/knowledge/loaders/file-loaders.js.map +1 -1
- package/dist/lib/knowledge/loaders/web-loader.d.ts +12 -3
- package/dist/lib/knowledge/loaders/web-loader.d.ts.map +1 -1
- package/dist/lib/knowledge/loaders/web-loader.js +56 -22
- package/dist/lib/knowledge/loaders/web-loader.js.map +1 -1
- package/dist/lib/knowledge/sqlite-store.d.ts.map +1 -1
- package/dist/lib/knowledge/sqlite-store.js +19 -10
- package/dist/lib/knowledge/sqlite-store.js.map +1 -1
- package/dist/lib/knowledge/types.d.ts +69 -33
- package/dist/lib/knowledge/types.d.ts.map +1 -1
- package/dist/lib/knowledge/types.js +18 -3
- package/dist/lib/knowledge/types.js.map +1 -1
- package/dist/lib/llm/index.d.ts +1 -1
- package/dist/lib/llm/index.d.ts.map +1 -1
- package/dist/lib/llm/index.js +1 -1
- package/dist/lib/llm/index.js.map +1 -1
- package/dist/lib/llm/llm-call-logger.d.ts +3 -1
- package/dist/lib/llm/llm-call-logger.d.ts.map +1 -1
- package/dist/lib/llm/llm-call-logger.js +31 -26
- package/dist/lib/llm/llm-call-logger.js.map +1 -1
- package/dist/lib/llm/llm-config.d.ts +59 -8
- package/dist/lib/llm/llm-config.d.ts.map +1 -1
- package/dist/lib/llm/llm-config.js +163 -17
- package/dist/lib/llm/llm-config.js.map +1 -1
- package/dist/lib/llm/llm-factory.d.ts +1 -2
- package/dist/lib/llm/llm-factory.d.ts.map +1 -1
- package/dist/lib/llm/llm-factory.js +44 -8
- package/dist/lib/llm/llm-factory.js.map +1 -1
- package/dist/lib/llm/providers/anthropic-chat-model.d.ts +5 -1
- package/dist/lib/llm/providers/anthropic-chat-model.d.ts.map +1 -1
- package/dist/lib/llm/providers/anthropic-chat-model.js +118 -42
- package/dist/lib/llm/providers/anthropic-chat-model.js.map +1 -1
- package/dist/lib/llm/providers/gemini-chat-model.d.ts +3 -2
- package/dist/lib/llm/providers/gemini-chat-model.d.ts.map +1 -1
- package/dist/lib/llm/providers/gemini-chat-model.js +83 -24
- package/dist/lib/llm/providers/gemini-chat-model.js.map +1 -1
- package/dist/lib/llm/providers/openai-chat-model.d.ts +20 -1
- package/dist/lib/llm/providers/openai-chat-model.d.ts.map +1 -1
- package/dist/lib/llm/providers/openai-chat-model.js +265 -32
- package/dist/lib/llm/providers/openai-chat-model.js.map +1 -1
- package/dist/lib/llm/providers/openai-embeddings.d.ts.map +1 -1
- package/dist/lib/llm/providers/openai-embeddings.js +41 -10
- package/dist/lib/llm/providers/openai-embeddings.js.map +1 -1
- package/dist/lib/local-llm/binary-manager.d.ts +66 -0
- package/dist/lib/local-llm/binary-manager.d.ts.map +1 -0
- package/dist/lib/local-llm/binary-manager.js +441 -0
- package/dist/lib/local-llm/binary-manager.js.map +1 -0
- package/dist/lib/local-llm/engine-interface.d.ts +47 -0
- package/dist/lib/local-llm/engine-interface.d.ts.map +1 -0
- package/dist/lib/local-llm/engine-interface.js +2 -0
- package/dist/lib/local-llm/engine-interface.js.map +1 -0
- package/dist/lib/local-llm/engine-registry.d.ts +20 -0
- package/dist/lib/local-llm/engine-registry.d.ts.map +1 -0
- package/dist/lib/local-llm/engine-registry.js +56 -0
- package/dist/lib/local-llm/engine-registry.js.map +1 -0
- package/dist/lib/local-llm/engines/llama-cpp-engine.d.ts +31 -0
- package/dist/lib/local-llm/engines/llama-cpp-engine.d.ts.map +1 -0
- package/dist/lib/local-llm/engines/llama-cpp-engine.js +164 -0
- package/dist/lib/local-llm/engines/llama-cpp-engine.js.map +1 -0
- package/dist/lib/local-llm/engines/mlx-serve-engine.d.ts +31 -0
- package/dist/lib/local-llm/engines/mlx-serve-engine.d.ts.map +1 -0
- package/dist/lib/local-llm/engines/mlx-serve-engine.js +161 -0
- package/dist/lib/local-llm/engines/mlx-serve-engine.js.map +1 -0
- package/dist/lib/local-llm/gguf-reader.d.ts +20 -0
- package/dist/lib/local-llm/gguf-reader.d.ts.map +1 -0
- package/dist/lib/local-llm/gguf-reader.js +190 -0
- package/dist/lib/local-llm/gguf-reader.js.map +1 -0
- package/dist/lib/local-llm/index.d.ts +9 -0
- package/dist/lib/local-llm/index.d.ts.map +1 -0
- package/dist/lib/local-llm/index.js +6 -0
- package/dist/lib/local-llm/index.js.map +1 -0
- package/dist/lib/local-llm/llama-server-process.d.ts +42 -0
- package/dist/lib/local-llm/llama-server-process.d.ts.map +1 -0
- package/dist/lib/local-llm/llama-server-process.js +237 -0
- package/dist/lib/local-llm/llama-server-process.js.map +1 -0
- package/dist/lib/local-llm/mlx-binary-manager.d.ts +33 -0
- package/dist/lib/local-llm/mlx-binary-manager.d.ts.map +1 -0
- package/dist/lib/local-llm/mlx-binary-manager.js +211 -0
- package/dist/lib/local-llm/mlx-binary-manager.js.map +1 -0
- package/dist/lib/local-llm/mlx-server-process.d.ts +26 -0
- package/dist/lib/local-llm/mlx-server-process.d.ts.map +1 -0
- package/dist/lib/local-llm/mlx-server-process.js +210 -0
- package/dist/lib/local-llm/mlx-server-process.js.map +1 -0
- package/dist/lib/local-llm/model-manager.d.ts +33 -0
- package/dist/lib/local-llm/model-manager.d.ts.map +1 -0
- package/dist/lib/local-llm/model-manager.js +591 -0
- package/dist/lib/local-llm/model-manager.js.map +1 -0
- package/dist/lib/local-llm/types.d.ts +51 -0
- package/dist/lib/local-llm/types.d.ts.map +1 -0
- package/dist/lib/local-llm/types.js +2 -0
- package/dist/lib/local-llm/types.js.map +1 -0
- package/dist/lib/logger.d.ts +2 -0
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +68 -6
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/mcp/mcp-client.d.ts.map +1 -1
- package/dist/lib/mcp/mcp-client.js +5 -3
- package/dist/lib/mcp/mcp-client.js.map +1 -1
- package/dist/lib/mcp/types.d.ts +0 -9
- package/dist/lib/mcp/types.d.ts.map +1 -1
- package/dist/lib/mcp/types.js +1 -2
- package/dist/lib/mcp/types.js.map +1 -1
- package/dist/lib/memory/memory-manager.d.ts +1 -0
- package/dist/lib/memory/memory-manager.d.ts.map +1 -1
- package/dist/lib/memory/memory-manager.js +9 -0
- package/dist/lib/memory/memory-manager.js.map +1 -1
- package/dist/lib/orchestrator.d.ts +11 -8
- package/dist/lib/orchestrator.d.ts.map +1 -1
- package/dist/lib/orchestrator.js +246 -5
- package/dist/lib/orchestrator.js.map +1 -1
- package/dist/lib/sandbox/cdp-client.d.ts +15 -0
- package/dist/lib/sandbox/cdp-client.d.ts.map +1 -0
- package/dist/lib/sandbox/cdp-client.js +139 -0
- package/dist/lib/sandbox/cdp-client.js.map +1 -0
- package/dist/lib/sandbox/html-to-markdown.d.ts +9 -1
- package/dist/lib/sandbox/html-to-markdown.d.ts.map +1 -1
- package/dist/lib/sandbox/html-to-markdown.js +67 -10
- package/dist/lib/sandbox/html-to-markdown.js.map +1 -1
- package/dist/lib/sandbox/index.d.ts +6 -0
- package/dist/lib/sandbox/index.d.ts.map +1 -1
- package/dist/lib/sandbox/index.js +5 -0
- package/dist/lib/sandbox/index.js.map +1 -1
- package/dist/lib/sandbox/page-readiness.d.ts +37 -0
- package/dist/lib/sandbox/page-readiness.d.ts.map +1 -0
- package/dist/lib/sandbox/page-readiness.js +268 -0
- package/dist/lib/sandbox/page-readiness.js.map +1 -0
- package/dist/lib/sandbox/sandbox-browser.d.ts +4 -0
- package/dist/lib/sandbox/sandbox-browser.d.ts.map +1 -0
- package/dist/lib/sandbox/sandbox-browser.js +316 -0
- package/dist/lib/sandbox/sandbox-browser.js.map +1 -0
- package/dist/lib/sandbox/sandbox-container.d.ts +39 -0
- package/dist/lib/sandbox/sandbox-container.d.ts.map +1 -0
- package/dist/lib/sandbox/sandbox-container.js +176 -0
- package/dist/lib/sandbox/sandbox-container.js.map +1 -0
- package/dist/lib/sandbox/sandbox-file.d.ts +4 -0
- package/dist/lib/sandbox/sandbox-file.d.ts.map +1 -0
- package/dist/lib/sandbox/sandbox-file.js +169 -0
- package/dist/lib/sandbox/sandbox-file.js.map +1 -0
- package/dist/lib/sandbox/sandbox-shell.d.ts +5 -0
- package/dist/lib/sandbox/sandbox-shell.d.ts.map +1 -0
- package/dist/lib/sandbox/sandbox-shell.js +111 -0
- package/dist/lib/sandbox/sandbox-shell.js.map +1 -0
- package/dist/lib/sandbox/sandbox-web.d.ts.map +1 -1
- package/dist/lib/sandbox/sandbox-web.js +64 -24
- package/dist/lib/sandbox/sandbox-web.js.map +1 -1
- package/dist/lib/sandbox/types.d.ts +9 -0
- package/dist/lib/sandbox/types.d.ts.map +1 -1
- package/dist/lib/sandbox/types.js +1 -0
- package/dist/lib/sandbox/types.js.map +1 -1
- package/dist/lib/sandbox/vision-browser.d.ts +4 -0
- package/dist/lib/sandbox/vision-browser.d.ts.map +1 -0
- package/dist/lib/sandbox/vision-browser.js +298 -0
- package/dist/lib/sandbox/vision-browser.js.map +1 -0
- package/dist/lib/sea/app-window.d.ts +7 -0
- package/dist/lib/sea/app-window.d.ts.map +1 -0
- package/dist/lib/sea/app-window.js +95 -0
- package/dist/lib/sea/app-window.js.map +1 -0
- package/dist/lib/sea/bootstrap.d.ts +18 -0
- package/dist/lib/sea/bootstrap.d.ts.map +1 -0
- package/dist/lib/sea/bootstrap.js +103 -0
- package/dist/lib/sea/bootstrap.js.map +1 -0
- package/dist/lib/sea/sqlite-vec-shim.d.ts +3 -0
- package/dist/lib/sea/sqlite-vec-shim.d.ts.map +1 -0
- package/dist/lib/sea/sqlite-vec-shim.js +10 -0
- package/dist/lib/sea/sqlite-vec-shim.js.map +1 -0
- package/dist/lib/skills/skill-loader.d.ts +2 -0
- package/dist/lib/skills/skill-loader.d.ts.map +1 -1
- package/dist/lib/skills/skill-loader.js +12 -1
- package/dist/lib/skills/skill-loader.js.map +1 -1
- package/dist/lib/tasks/task-manager.d.ts +3 -1
- package/dist/lib/tasks/task-manager.d.ts.map +1 -1
- package/dist/lib/tasks/task-manager.js +11 -0
- package/dist/lib/tasks/task-manager.js.map +1 -1
- package/dist/lib/tasks/task-store.d.ts +1 -1
- package/dist/lib/tasks/task-store.d.ts.map +1 -1
- package/dist/lib/tasks/task-store.js.map +1 -1
- package/dist/lib/tasks/types.d.ts +18 -0
- package/dist/lib/tasks/types.d.ts.map +1 -1
- package/dist/lib/tools/built-in/integration-tools.d.ts +4 -0
- package/dist/lib/tools/built-in/integration-tools.d.ts.map +1 -0
- package/dist/lib/tools/built-in/integration-tools.js +47 -0
- package/dist/lib/tools/built-in/integration-tools.js.map +1 -0
- package/dist/lib/tools/built-in/knowledge-entity-lookup.tool.d.ts +1 -2
- package/dist/lib/tools/built-in/knowledge-entity-lookup.tool.d.ts.map +1 -1
- package/dist/lib/tools/built-in/knowledge-entity-lookup.tool.js +17 -17
- package/dist/lib/tools/built-in/knowledge-entity-lookup.tool.js.map +1 -1
- package/dist/lib/tools/built-in/knowledge-graph-schema.tool.d.ts.map +1 -1
- package/dist/lib/tools/built-in/knowledge-graph-schema.tool.js +2 -4
- package/dist/lib/tools/built-in/knowledge-graph-schema.tool.js.map +1 -1
- package/dist/lib/tools/built-in/knowledge-search.tool.js +4 -4
- package/dist/lib/tools/built-in/knowledge-search.tool.js.map +1 -1
- package/dist/lib/tools/built-in/knowledge-sql.tool.d.ts.map +1 -1
- package/dist/lib/tools/built-in/knowledge-sql.tool.js +74 -40
- package/dist/lib/tools/built-in/knowledge-sql.tool.js.map +1 -1
- package/dist/lib/tools/built-in/knowledge-tools-factory.js +2 -2
- package/dist/lib/tools/built-in/knowledge-tools-factory.js.map +1 -1
- package/dist/lib/tools/built-in/knowledge-traverse.tool.d.ts +1 -2
- package/dist/lib/tools/built-in/knowledge-traverse.tool.d.ts.map +1 -1
- package/dist/lib/tools/built-in/knowledge-traverse.tool.js +5 -11
- package/dist/lib/tools/built-in/knowledge-traverse.tool.js.map +1 -1
- package/dist/lib/tools/built-in/query-validators.d.ts.map +1 -1
- package/dist/lib/tools/built-in/query-validators.js +4 -0
- package/dist/lib/tools/built-in/query-validators.js.map +1 -1
- package/dist/lib/tools/workspace/workspace-tools.d.ts +1 -0
- package/dist/lib/tools/workspace/workspace-tools.d.ts.map +1 -1
- package/dist/lib/tools/workspace/workspace-tools.js +44 -4
- package/dist/lib/tools/workspace/workspace-tools.js.map +1 -1
- package/dist/lib/triggers/cron-trigger.d.ts +1 -1
- package/dist/lib/triggers/cron-trigger.d.ts.map +1 -1
- package/dist/lib/triggers/cron-trigger.js.map +1 -1
- package/dist/lib/triggers/trigger-manager.d.ts +1 -0
- package/dist/lib/triggers/trigger-manager.d.ts.map +1 -1
- package/dist/lib/triggers/trigger-manager.js +26 -0
- package/dist/lib/triggers/trigger-manager.js.map +1 -1
- package/dist/lib/triggers/webhook-trigger.d.ts +1 -1
- package/dist/lib/triggers/webhook-trigger.d.ts.map +1 -1
- package/dist/lib/triggers/webhook-trigger.js.map +1 -1
- package/dist/lib/types/llm-types.d.ts +22 -4
- package/dist/lib/types/llm-types.d.ts.map +1 -1
- package/dist/lib/types/llm-types.js +50 -0
- package/dist/lib/types/llm-types.js.map +1 -1
- package/dist/lib/types/tool-factory.d.ts +2 -2
- package/dist/lib/types/tool-factory.d.ts.map +1 -1
- package/dist/lib/types/tool-factory.js +9 -2
- package/dist/lib/types/tool-factory.js.map +1 -1
- package/dist/lib/utils/document-extract.d.ts +10 -0
- package/dist/lib/utils/document-extract.d.ts.map +1 -0
- package/dist/lib/utils/document-extract.js +149 -0
- package/dist/lib/utils/document-extract.js.map +1 -0
- package/dist/lib/utils/env-substitution.d.ts +6 -0
- package/dist/lib/utils/env-substitution.d.ts.map +1 -0
- package/dist/lib/utils/env-substitution.js +15 -0
- package/dist/lib/utils/env-substitution.js.map +1 -0
- package/dist/lib/workflows/react-workflow-executor.d.ts.map +1 -1
- package/dist/lib/workflows/react-workflow-executor.js +23 -17
- package/dist/lib/workflows/react-workflow-executor.js.map +1 -1
- package/dist/lib/workflows/types.d.ts +81 -55
- package/dist/lib/workflows/types.d.ts.map +1 -1
- package/dist/lib/workflows/types.js +10 -0
- package/dist/lib/workflows/types.js.map +1 -1
- package/dist/lib/workflows/workflow-loader.d.ts +3 -0
- package/dist/lib/workflows/workflow-loader.d.ts.map +1 -1
- package/dist/lib/workflows/workflow-loader.js +10 -1
- package/dist/lib/workflows/workflow-loader.js.map +1 -1
- package/dist/public/assets/logo.png +0 -0
- package/dist/public/chat.html +39 -0
- package/dist/public/index.html +6 -176
- package/dist/public/src/components/AgentComposer.js +807 -0
- package/dist/public/src/components/AgentsView.js +1812 -508
- package/dist/public/src/components/AppRoot.js +125 -38
- package/dist/public/src/components/GraphView.js +382 -300
- package/dist/public/src/components/IdeView.js +277 -86
- package/dist/public/src/components/KnowledgeView.js +94 -130
- package/dist/public/src/components/LlmView.js +15 -19
- package/dist/public/src/components/LocalLlmView.js +2440 -0
- package/dist/public/src/components/LogViewer.js +155 -0
- package/dist/public/src/components/McpView.js +41 -49
- package/dist/public/src/components/MonitorView.js +174 -83
- package/dist/public/src/components/NavBar.js +16 -26
- package/dist/public/src/components/StandaloneChat.js +875 -0
- package/dist/public/src/services/ApiService.js +203 -4
- package/dist/public/src/services/SessionStore.js +86 -0
- package/dist/public/src/services/StreamManager.js +183 -0
- package/dist/public/src/store.js +1 -3
- package/dist/public/src/utils/card.js +21 -0
- package/dist/public/src/utils/markdown.js +7 -0
- package/dist/public/styles.css +2777 -0
- package/dist/src/cli/commands/init.d.ts.map +1 -1
- package/dist/src/cli/commands/init.js +7 -1
- package/dist/src/cli/commands/init.js.map +1 -1
- package/dist/src/cli/commands/start.d.ts.map +1 -1
- package/dist/src/cli/commands/start.js +28 -5
- package/dist/src/cli/commands/start.js.map +1 -1
- package/dist/src/cli/index.js +19 -5
- package/dist/src/cli/index.js.map +1 -1
- package/dist/src/index.js +7 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/middleware/auth.d.ts.map +1 -1
- package/dist/src/middleware/auth.js +28 -6
- package/dist/src/middleware/auth.js.map +1 -1
- package/dist/src/middleware/rate-limit.d.ts +8 -0
- package/dist/src/middleware/rate-limit.d.ts.map +1 -0
- package/dist/src/middleware/rate-limit.js +21 -0
- package/dist/src/middleware/rate-limit.js.map +1 -0
- package/dist/src/routes/agents.route.d.ts.map +1 -1
- package/dist/src/routes/agents.route.js +138 -10
- package/dist/src/routes/agents.route.js.map +1 -1
- package/dist/src/routes/chat.route.d.ts +3 -0
- package/dist/src/routes/chat.route.d.ts.map +1 -0
- package/dist/src/routes/chat.route.js +156 -0
- package/dist/src/routes/chat.route.js.map +1 -0
- package/dist/src/routes/files.route.d.ts.map +1 -1
- package/dist/src/routes/files.route.js +37 -2
- package/dist/src/routes/files.route.js.map +1 -1
- package/dist/src/routes/llm.route.d.ts.map +1 -1
- package/dist/src/routes/llm.route.js +263 -8
- package/dist/src/routes/llm.route.js.map +1 -1
- package/dist/src/routes/local-llm.route.d.ts +3 -0
- package/dist/src/routes/local-llm.route.d.ts.map +1 -0
- package/dist/src/routes/local-llm.route.js +688 -0
- package/dist/src/routes/local-llm.route.js.map +1 -0
- package/dist/src/routes/logs.route.d.ts +3 -0
- package/dist/src/routes/logs.route.d.ts.map +1 -0
- package/dist/src/routes/logs.route.js +24 -0
- package/dist/src/routes/logs.route.js.map +1 -0
- package/dist/src/routes/tasks.route.d.ts.map +1 -1
- package/dist/src/routes/tasks.route.js +15 -1
- package/dist/src/routes/tasks.route.js.map +1 -1
- package/dist/src/routes/vnc.route.d.ts +12 -0
- package/dist/src/routes/vnc.route.d.ts.map +1 -0
- package/dist/src/routes/vnc.route.js +74 -0
- package/dist/src/routes/vnc.route.js.map +1 -0
- package/dist/src/routes/workflows.route.d.ts.map +1 -1
- package/dist/src/routes/workflows.route.js +24 -0
- package/dist/src/routes/workflows.route.js.map +1 -1
- package/dist/src/server.d.ts.map +1 -1
- package/dist/src/server.js +29 -3
- package/dist/src/server.js.map +1 -1
- package/dist/templates/Demo.md +152 -0
- package/dist/templates/README.md +12 -3
- package/dist/templates/agents/actor.agent.yaml +34 -0
- package/dist/templates/agents/architect.agent.yaml +20 -13
- package/dist/templates/agents/chatbot.agent.yaml +23 -27
- package/dist/templates/agents/corporate.agent.yaml +64 -0
- package/dist/templates/agents/functions.agent.yaml +29 -0
- package/dist/templates/agents/investment-analyst.agent.yaml +79 -0
- package/dist/templates/agents/music-librarian.agent.yaml +46 -0
- package/dist/templates/agents/network-security.agent.yaml +81 -0
- package/dist/templates/agents/transport-security.agent.yaml +69 -0
- package/dist/templates/agents/web-engineer.agent.yaml +98 -0
- package/dist/templates/agents/web-pilot.agent.yaml +57 -0
- package/dist/templates/knowledge/music-store/LICENSE.md +11 -0
- package/dist/templates/knowledge/music-store/musicstore.sqlite +0 -0
- package/dist/templates/knowledge/music-store/tables.png +0 -0
- package/dist/templates/knowledge/music-store.knowledge.yaml +138 -0
- package/dist/templates/knowledge/org-chart/personnel.csv +21 -21
- package/dist/templates/knowledge/org-chart.knowledge.yaml +4 -0
- package/dist/templates/knowledge/patient-records.knowledge.yaml +20 -0
- package/dist/templates/knowledge/pdf-patients/PDF_Deid_Deidentification_0.pdf +0 -0
- package/dist/templates/knowledge/pdf-patients/PDF_Deid_Deidentification_1.pdf +0 -0
- package/dist/templates/knowledge/pdf-patients/PDF_Deid_Deidentification_10.pdf +0 -0
- package/dist/templates/knowledge/pdf-patients/PDF_Deid_Deidentification_11.pdf +0 -0
- package/dist/templates/knowledge/pet-store.knowledge.yaml +3 -0
- package/dist/templates/knowledge/security-incidents/incidents.json +55935 -0
- package/dist/templates/knowledge/security-incidents.knowledge.yaml +46 -0
- package/dist/templates/knowledge/{example.knowledge.yaml → transcripts.knowledge.yaml} +9 -5
- package/dist/templates/knowledge/transport-ot/systems.csv +117 -0
- package/dist/templates/knowledge/transport-ot.knowledge.yaml +55 -0
- package/dist/templates/knowledge/web-docs.knowledge.yaml +1 -1
- package/dist/templates/llm.json +62 -22
- package/dist/templates/mcp.json +7 -4
- package/dist/templates/skills/orcha-builder/SKILL.md +148 -215
- package/dist/templates/skills/pii-guard/SKILL.md +22 -0
- package/dist/templates/skills/sandbox/SKILL.md +25 -48
- package/dist/templates/skills/web-pilot/SKILL.md +51 -0
- package/dist/templates/workflows/example.workflow.yaml +27 -35
- package/dist/templates/workflows/react-example.workflow.yaml +14 -19
- package/dist/templates/workflows/team-chat.workflow.yaml +47 -0
- package/package.json +17 -4
- package/dist/public/src/components/SkillsView.js +0 -137
- package/dist/public/src/components/WorkflowsView.js +0 -416
- package/dist/templates/agents/knowledge-broker.agent.yaml +0 -39
- package/dist/templates/agents/sandbox.agent.yaml +0 -56
|
@@ -0,0 +1,688 @@
|
|
|
1
|
+
import * as os from 'os';
|
|
2
|
+
import { ModelManager } from "../../lib/local-llm/index.js";
|
|
3
|
+
import { engineRegistry } from "../../lib/local-llm/engine-registry.js";
|
|
4
|
+
import { getLLMConfig, saveLLMConfig, LLMFactory, resolveDefaultName, } from "../../lib/llm/index.js";
|
|
5
|
+
import { detectProvider } from "../../lib/llm/provider-detector.js";
|
|
6
|
+
import { detectGpu, queryNvidiaVram } from "../../lib/local-llm/binary-manager.js";
|
|
7
|
+
import { logger } from "../../lib/logger.js";
|
|
8
|
+
const DEFAULT_ENGINE_URLS = {
|
|
9
|
+
ollama: 'http://localhost:11434',
|
|
10
|
+
lmstudio: 'http://localhost:1234',
|
|
11
|
+
};
|
|
12
|
+
function getEngineUrl(engine) {
|
|
13
|
+
const config = getLLMConfig();
|
|
14
|
+
return config?.engineUrls?.[engine] || DEFAULT_ENGINE_URLS[engine] || '';
|
|
15
|
+
}
|
|
16
|
+
async function fetchOllamaCapabilities(baseUrl, modelName) {
|
|
17
|
+
try {
|
|
18
|
+
const controller = new AbortController();
|
|
19
|
+
const timer = setTimeout(() => controller.abort(), 2000);
|
|
20
|
+
const res = await fetch(`${baseUrl}/api/show`, {
|
|
21
|
+
method: 'POST',
|
|
22
|
+
headers: { 'Content-Type': 'application/json' },
|
|
23
|
+
body: JSON.stringify({ model: modelName }),
|
|
24
|
+
signal: controller.signal,
|
|
25
|
+
});
|
|
26
|
+
clearTimeout(timer);
|
|
27
|
+
if (!res.ok)
|
|
28
|
+
return [];
|
|
29
|
+
const data = await res.json();
|
|
30
|
+
return Array.isArray(data.capabilities) ? data.capabilities : [];
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
return [];
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
async function fetchOllamaRunning(baseUrl) {
|
|
37
|
+
try {
|
|
38
|
+
const controller = new AbortController();
|
|
39
|
+
const timer = setTimeout(() => controller.abort(), 2000);
|
|
40
|
+
const res = await fetch(`${baseUrl}/api/ps`, { signal: controller.signal });
|
|
41
|
+
clearTimeout(timer);
|
|
42
|
+
if (!res.ok)
|
|
43
|
+
return [];
|
|
44
|
+
const data = await res.json();
|
|
45
|
+
return data.models || [];
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
return [];
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async function unloadOllamaModel(baseUrl, model) {
|
|
52
|
+
try {
|
|
53
|
+
const controller = new AbortController();
|
|
54
|
+
const timer = setTimeout(() => controller.abort(), 5000);
|
|
55
|
+
const res = await fetch(`${baseUrl}/api/generate`, {
|
|
56
|
+
method: 'POST',
|
|
57
|
+
headers: { 'Content-Type': 'application/json' },
|
|
58
|
+
body: JSON.stringify({ model, keep_alive: 0 }),
|
|
59
|
+
signal: controller.signal,
|
|
60
|
+
});
|
|
61
|
+
clearTimeout(timer);
|
|
62
|
+
return res.ok;
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return false;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function unloadLmStudioModel(baseUrl, instanceId) {
|
|
69
|
+
try {
|
|
70
|
+
const controller = new AbortController();
|
|
71
|
+
const timer = setTimeout(() => controller.abort(), 5000);
|
|
72
|
+
const res = await fetch(`${baseUrl}/api/v1/models/unload`, {
|
|
73
|
+
method: 'POST',
|
|
74
|
+
headers: { 'Content-Type': 'application/json' },
|
|
75
|
+
body: JSON.stringify({ instance_id: instanceId }),
|
|
76
|
+
signal: controller.signal,
|
|
77
|
+
});
|
|
78
|
+
clearTimeout(timer);
|
|
79
|
+
return res.ok;
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
async function probeExternalEngine(engine) {
|
|
86
|
+
const baseUrl = getEngineUrl(engine);
|
|
87
|
+
const timeout = 2000;
|
|
88
|
+
try {
|
|
89
|
+
const controller = new AbortController();
|
|
90
|
+
const timer = setTimeout(() => controller.abort(), timeout);
|
|
91
|
+
let models = [];
|
|
92
|
+
let running = [];
|
|
93
|
+
if (engine === 'ollama') {
|
|
94
|
+
const res = await fetch(`${baseUrl}/api/tags`, { signal: controller.signal });
|
|
95
|
+
clearTimeout(timer);
|
|
96
|
+
if (!res.ok)
|
|
97
|
+
return { available: false, models: [], running: [] };
|
|
98
|
+
const data = await res.json();
|
|
99
|
+
const rawModels = data.models || [];
|
|
100
|
+
// Fetch capabilities + running models in parallel
|
|
101
|
+
const [capsResults, runningModels] = await Promise.all([
|
|
102
|
+
Promise.all(rawModels.map((m) => fetchOllamaCapabilities(baseUrl, m.name))),
|
|
103
|
+
fetchOllamaRunning(baseUrl),
|
|
104
|
+
]);
|
|
105
|
+
// Build running model map: name -> { sizeVram, contextLength }
|
|
106
|
+
const runMap = new Map();
|
|
107
|
+
for (const r of runningModels) {
|
|
108
|
+
runMap.set(r.name, r);
|
|
109
|
+
}
|
|
110
|
+
models = rawModels.map((m, i) => {
|
|
111
|
+
const rm = runMap.get(m.name);
|
|
112
|
+
return {
|
|
113
|
+
name: m.name,
|
|
114
|
+
size: m.size,
|
|
115
|
+
parameterSize: m.details?.parameter_size || null,
|
|
116
|
+
family: m.details?.family || null,
|
|
117
|
+
quantization: m.details?.quantization_level || null,
|
|
118
|
+
capabilities: capsResults[i],
|
|
119
|
+
loaded: !!rm,
|
|
120
|
+
sizeVram: rm?.size_vram || null,
|
|
121
|
+
contextLength: rm?.context_length || null,
|
|
122
|
+
};
|
|
123
|
+
});
|
|
124
|
+
running = runningModels.map((r) => ({
|
|
125
|
+
name: r.name,
|
|
126
|
+
size: r.size,
|
|
127
|
+
sizeVram: r.size_vram,
|
|
128
|
+
contextLength: r.context_length,
|
|
129
|
+
expiresAt: r.expires_at,
|
|
130
|
+
}));
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
// Use LM Studio's rich API for capabilities, loaded state, and instance IDs
|
|
134
|
+
const res = await fetch(`${baseUrl}/api/v1/models`, { signal: controller.signal });
|
|
135
|
+
clearTimeout(timer);
|
|
136
|
+
if (!res.ok)
|
|
137
|
+
return { available: false, models: [], running: [] };
|
|
138
|
+
const data = await res.json();
|
|
139
|
+
const rawModels = data.models || [];
|
|
140
|
+
models = rawModels.map((m) => {
|
|
141
|
+
const caps = [];
|
|
142
|
+
if (m.capabilities?.vision)
|
|
143
|
+
caps.push('vision');
|
|
144
|
+
if (m.capabilities?.trained_for_tool_use)
|
|
145
|
+
caps.push('tools');
|
|
146
|
+
const instances = m.loaded_instances || [];
|
|
147
|
+
return {
|
|
148
|
+
name: m.key,
|
|
149
|
+
type: m.type || null,
|
|
150
|
+
arch: m.architecture || null,
|
|
151
|
+
quantization: m.quantization?.name || null,
|
|
152
|
+
size: m.size_bytes || null,
|
|
153
|
+
parameterSize: m.params_string || null,
|
|
154
|
+
maxContextLength: m.max_context_length || null,
|
|
155
|
+
format: m.format || null,
|
|
156
|
+
capabilities: caps,
|
|
157
|
+
loaded: instances.length > 0,
|
|
158
|
+
instanceId: instances[0]?.id || null,
|
|
159
|
+
contextLength: instances[0]?.config?.context_length || null,
|
|
160
|
+
};
|
|
161
|
+
});
|
|
162
|
+
running = models
|
|
163
|
+
.filter((m) => m.loaded)
|
|
164
|
+
.map((m) => ({
|
|
165
|
+
name: m.name,
|
|
166
|
+
size: m.size,
|
|
167
|
+
instanceId: m.instanceId,
|
|
168
|
+
contextLength: m.contextLength,
|
|
169
|
+
}));
|
|
170
|
+
}
|
|
171
|
+
return { available: true, models, running };
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
return { available: false, models: [], running: [] };
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
export const localLlmRoutes = async (fastify) => {
|
|
178
|
+
const workspaceRoot = fastify.orchestrator.workspaceRoot;
|
|
179
|
+
const manager = new ModelManager(workspaceRoot);
|
|
180
|
+
const llmJsonPath = fastify.orchestrator.llmConfigPath;
|
|
181
|
+
// GET /engines — probe availability of all local engines
|
|
182
|
+
fastify.get('/engines', async () => {
|
|
183
|
+
const llamaEngine = engineRegistry.getEngine('llama-cpp');
|
|
184
|
+
const mlxEngine = engineRegistry.getEngine('mlx-serve');
|
|
185
|
+
const [ollama, lmstudio] = await Promise.all([
|
|
186
|
+
probeExternalEngine('ollama'),
|
|
187
|
+
probeExternalEngine('lmstudio'),
|
|
188
|
+
]);
|
|
189
|
+
return {
|
|
190
|
+
'llama-cpp': { available: llamaEngine.isAvailable() },
|
|
191
|
+
'mlx-serve': { available: mlxEngine.isAvailable() },
|
|
192
|
+
ollama: { available: ollama.available, models: ollama.models, running: ollama.running },
|
|
193
|
+
lmstudio: { available: lmstudio.available, models: lmstudio.models, running: lmstudio.running },
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
// GET /engines/urls — return custom engine base URLs
|
|
197
|
+
fastify.get('/engines/urls', async () => {
|
|
198
|
+
const config = getLLMConfig();
|
|
199
|
+
return {
|
|
200
|
+
ollama: config?.engineUrls?.ollama || DEFAULT_ENGINE_URLS.ollama,
|
|
201
|
+
lmstudio: config?.engineUrls?.lmstudio || DEFAULT_ENGINE_URLS.lmstudio,
|
|
202
|
+
};
|
|
203
|
+
});
|
|
204
|
+
// POST /engines/urls — set a custom base URL for an external engine
|
|
205
|
+
fastify.post('/engines/urls', async (request, reply) => {
|
|
206
|
+
const { engine, url } = request.body;
|
|
207
|
+
if (!engine || !url) {
|
|
208
|
+
return reply.status(400).send({ error: 'engine and url are required' });
|
|
209
|
+
}
|
|
210
|
+
if (engine !== 'ollama' && engine !== 'lmstudio') {
|
|
211
|
+
return reply.status(400).send({ error: 'engine must be ollama or lmstudio' });
|
|
212
|
+
}
|
|
213
|
+
// Strip trailing slash
|
|
214
|
+
const cleanUrl = url.replace(/\/+$/, '');
|
|
215
|
+
const config = getLLMConfig();
|
|
216
|
+
if (!config) {
|
|
217
|
+
return reply.status(500).send({ error: 'LLM config not loaded' });
|
|
218
|
+
}
|
|
219
|
+
if (!config.engineUrls)
|
|
220
|
+
config.engineUrls = {};
|
|
221
|
+
// If it matches the default, remove the override
|
|
222
|
+
if (cleanUrl === DEFAULT_ENGINE_URLS[engine]) {
|
|
223
|
+
delete config.engineUrls[engine];
|
|
224
|
+
if (Object.keys(config.engineUrls).length === 0)
|
|
225
|
+
delete config.engineUrls;
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
config.engineUrls[engine] = cleanUrl;
|
|
229
|
+
}
|
|
230
|
+
await saveLLMConfig(llmJsonPath, config);
|
|
231
|
+
return { ok: true };
|
|
232
|
+
});
|
|
233
|
+
// POST /engines/activate — activate an external engine model (ollama/lmstudio)
|
|
234
|
+
fastify.post('/engines/activate', async (request, reply) => {
|
|
235
|
+
const { engine, model, role = 'chat' } = request.body;
|
|
236
|
+
if (!engine || !model) {
|
|
237
|
+
return reply.status(400).send({ error: 'engine and model are required' });
|
|
238
|
+
}
|
|
239
|
+
if (engine !== 'ollama' && engine !== 'lmstudio') {
|
|
240
|
+
return reply.status(400).send({ error: 'engine must be ollama or lmstudio' });
|
|
241
|
+
}
|
|
242
|
+
const baseUrl = `${getEngineUrl(engine)}/v1`;
|
|
243
|
+
const config = getLLMConfig();
|
|
244
|
+
if (!config) {
|
|
245
|
+
return reply.status(500).send({ error: 'LLM config not loaded' });
|
|
246
|
+
}
|
|
247
|
+
if (role === 'embedding') {
|
|
248
|
+
// Stop any managed embedding engines
|
|
249
|
+
for (const e of engineRegistry.getAllEngines()) {
|
|
250
|
+
if (e.getEmbeddingStatus().running)
|
|
251
|
+
await e.unloadEmbedding();
|
|
252
|
+
}
|
|
253
|
+
config.embeddings[engine] = {
|
|
254
|
+
provider: 'local',
|
|
255
|
+
engine: engine,
|
|
256
|
+
baseUrl,
|
|
257
|
+
model,
|
|
258
|
+
};
|
|
259
|
+
config.embeddings['default'] = engine;
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
// Stop any managed chat engines
|
|
263
|
+
for (const e of engineRegistry.getAllEngines()) {
|
|
264
|
+
if (e.getChatStatus().running)
|
|
265
|
+
await e.unloadChat();
|
|
266
|
+
}
|
|
267
|
+
// Preserve reasoningBudget from the current default entry
|
|
268
|
+
const resolvedKey = resolveDefaultName('models');
|
|
269
|
+
const currentDefault = typeof config.models[resolvedKey] === 'object' ? config.models[resolvedKey] : null;
|
|
270
|
+
config.models[engine] = {
|
|
271
|
+
provider: 'local',
|
|
272
|
+
engine: engine,
|
|
273
|
+
baseUrl,
|
|
274
|
+
model,
|
|
275
|
+
...(currentDefault?.reasoningBudget != null ? { reasoningBudget: currentDefault.reasoningBudget } : {}),
|
|
276
|
+
};
|
|
277
|
+
config.models['default'] = engine;
|
|
278
|
+
}
|
|
279
|
+
await saveLLMConfig(llmJsonPath, config);
|
|
280
|
+
LLMFactory.clearCache();
|
|
281
|
+
// For LM Studio, unload running models first, then load the new one
|
|
282
|
+
if (engine === 'lmstudio') {
|
|
283
|
+
const lmBaseUrl = getEngineUrl('lmstudio');
|
|
284
|
+
// Unload all currently loaded models to free memory
|
|
285
|
+
try {
|
|
286
|
+
const probe = await probeExternalEngine('lmstudio');
|
|
287
|
+
for (const r of probe.running) {
|
|
288
|
+
if (r.instanceId) {
|
|
289
|
+
await unloadLmStudioModel(lmBaseUrl, r.instanceId);
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
catch (err) {
|
|
294
|
+
logger.warn('[LocalLLM] Failed to unload existing LM Studio models:', err);
|
|
295
|
+
}
|
|
296
|
+
// Load the new model
|
|
297
|
+
try {
|
|
298
|
+
const modelConfig = config.models[engine];
|
|
299
|
+
const ctxSize = (modelConfig && typeof modelConfig === 'object') ? modelConfig.contextSize : undefined;
|
|
300
|
+
const loadRes = await fetch(`${lmBaseUrl}/api/v1/models/load`, {
|
|
301
|
+
method: 'POST',
|
|
302
|
+
headers: { 'Content-Type': 'application/json' },
|
|
303
|
+
body: JSON.stringify({
|
|
304
|
+
model,
|
|
305
|
+
...(ctxSize ? { context_length: ctxSize } : {}),
|
|
306
|
+
}),
|
|
307
|
+
});
|
|
308
|
+
if (!loadRes.ok) {
|
|
309
|
+
logger.warn(`[LocalLLM] LM Studio model load returned ${loadRes.status}`);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
catch (err) {
|
|
313
|
+
logger.warn('[LocalLLM] Failed to load model in LM Studio:', err);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return { ok: true };
|
|
317
|
+
});
|
|
318
|
+
// POST /engines/context — update context size for external engines
|
|
319
|
+
fastify.post('/engines/context', async (request, reply) => {
|
|
320
|
+
const { contextSize } = request.body;
|
|
321
|
+
if (!contextSize || typeof contextSize !== 'number') {
|
|
322
|
+
return reply.status(400).send({ error: 'contextSize is required' });
|
|
323
|
+
}
|
|
324
|
+
const config = getLLMConfig();
|
|
325
|
+
if (!config) {
|
|
326
|
+
return reply.status(500).send({ error: 'LLM config not loaded' });
|
|
327
|
+
}
|
|
328
|
+
// Resolve the default pointer to the actual config entry
|
|
329
|
+
const resolvedKey = resolveDefaultName('models');
|
|
330
|
+
const defaultModel = config.models[resolvedKey];
|
|
331
|
+
if (!defaultModel || typeof defaultModel === 'string') {
|
|
332
|
+
return reply.status(400).send({ error: 'No default model configured' });
|
|
333
|
+
}
|
|
334
|
+
// Save to llm.json
|
|
335
|
+
defaultModel.contextSize = contextSize;
|
|
336
|
+
await saveLLMConfig(llmJsonPath, config);
|
|
337
|
+
LLMFactory.clearCache();
|
|
338
|
+
// For LM Studio, reload the model with new context_length
|
|
339
|
+
if (defaultModel.engine === 'lmstudio') {
|
|
340
|
+
try {
|
|
341
|
+
const loadRes = await fetch(`${getEngineUrl('lmstudio')}/api/v1/models/load`, {
|
|
342
|
+
method: 'POST',
|
|
343
|
+
headers: { 'Content-Type': 'application/json' },
|
|
344
|
+
body: JSON.stringify({
|
|
345
|
+
model: defaultModel.model,
|
|
346
|
+
context_length: contextSize,
|
|
347
|
+
}),
|
|
348
|
+
});
|
|
349
|
+
if (!loadRes.ok) {
|
|
350
|
+
logger.warn(`[LocalLLM] LM Studio model reload returned ${loadRes.status}`);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
catch (err) {
|
|
354
|
+
logger.warn('[LocalLLM] Failed to reload LM Studio model with new context:', err);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
return { ok: true };
|
|
358
|
+
});
|
|
359
|
+
// POST /engines/unload — unload a model from Ollama or LM Studio
|
|
360
|
+
fastify.post('/engines/unload', async (request, reply) => {
|
|
361
|
+
const { engine, model, instanceId } = request.body;
|
|
362
|
+
if (!engine || !model) {
|
|
363
|
+
return reply.status(400).send({ error: 'engine and model are required' });
|
|
364
|
+
}
|
|
365
|
+
let ok = false;
|
|
366
|
+
if (engine === 'ollama') {
|
|
367
|
+
ok = await unloadOllamaModel(getEngineUrl('ollama'), model);
|
|
368
|
+
}
|
|
369
|
+
else if (engine === 'lmstudio') {
|
|
370
|
+
// LM Studio needs instance_id; if not provided, probe for it
|
|
371
|
+
let iid = instanceId;
|
|
372
|
+
if (!iid) {
|
|
373
|
+
try {
|
|
374
|
+
const ctrl = new AbortController();
|
|
375
|
+
const t = setTimeout(() => ctrl.abort(), 2000);
|
|
376
|
+
const r = await fetch(`${getEngineUrl('lmstudio')}/api/v1/models`, { signal: ctrl.signal });
|
|
377
|
+
clearTimeout(t);
|
|
378
|
+
if (r.ok) {
|
|
379
|
+
const d = await r.json();
|
|
380
|
+
const found = (d.models || []).find((m) => m.key === model && m.loaded_instances?.length);
|
|
381
|
+
iid = found?.loaded_instances?.[0]?.id;
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
catch { /* ignore */ }
|
|
385
|
+
}
|
|
386
|
+
if (!iid) {
|
|
387
|
+
return reply.status(400).send({ error: `No loaded instance found for ${model}` });
|
|
388
|
+
}
|
|
389
|
+
ok = await unloadLmStudioModel(getEngineUrl('lmstudio'), iid);
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
return reply.status(400).send({ error: 'engine must be ollama or lmstudio' });
|
|
393
|
+
}
|
|
394
|
+
if (!ok) {
|
|
395
|
+
return reply.status(500).send({ error: `Failed to unload ${model} from ${engine}` });
|
|
396
|
+
}
|
|
397
|
+
return { ok: true };
|
|
398
|
+
});
|
|
399
|
+
// GET /status — return per-engine status
|
|
400
|
+
fastify.get('/status', async () => {
|
|
401
|
+
const gpu = detectGpu();
|
|
402
|
+
const state = await manager.getState();
|
|
403
|
+
const config = getLLMConfig();
|
|
404
|
+
const resolvedKey = resolveDefaultName('models');
|
|
405
|
+
const defaultModel = config?.models[resolvedKey];
|
|
406
|
+
const defaultProvider = (defaultModel && typeof defaultModel !== 'string') ? detectProvider(defaultModel) : null;
|
|
407
|
+
const defaultEngine = (defaultModel && typeof defaultModel !== 'string') ? (defaultModel.engine || null) : null;
|
|
408
|
+
const llamaEngine = engineRegistry.getEngine('llama-cpp');
|
|
409
|
+
const mlxEngine = engineRegistry.getEngine('mlx-serve');
|
|
410
|
+
return {
|
|
411
|
+
engines: engineRegistry.getAllStatus(),
|
|
412
|
+
available: true,
|
|
413
|
+
lastActiveModel: state.lastActiveModel,
|
|
414
|
+
systemRamBytes: os.totalmem(),
|
|
415
|
+
freeRamBytes: os.freemem(),
|
|
416
|
+
gpu,
|
|
417
|
+
gpuVram: gpu.accel?.startsWith('cuda') || gpu.accel === 'vulkan' ? queryNvidiaVram() : null,
|
|
418
|
+
defaultProvider,
|
|
419
|
+
defaultEngine,
|
|
420
|
+
platform: process.platform,
|
|
421
|
+
arch: process.arch,
|
|
422
|
+
// Per-engine binary info for frontend compatibility
|
|
423
|
+
llamaVersion: llamaEngine.getBinaryVersion(),
|
|
424
|
+
binarySource: llamaEngine.getBinarySource() ?? 'managed',
|
|
425
|
+
mlxVersion: mlxEngine.getBinaryVersion(),
|
|
426
|
+
mlxBinarySource: mlxEngine.getBinarySource() ?? 'managed',
|
|
427
|
+
};
|
|
428
|
+
});
|
|
429
|
+
// GET /models
|
|
430
|
+
fastify.get('/models', async () => {
|
|
431
|
+
return manager.listModels();
|
|
432
|
+
});
|
|
433
|
+
// GET /models/downloads — active download progress (pollable)
|
|
434
|
+
fastify.get('/models/downloads', async () => {
|
|
435
|
+
return manager.getActiveDownloads();
|
|
436
|
+
});
|
|
437
|
+
// GET /models/interrupted — partial downloads from previous sessions
|
|
438
|
+
fastify.get('/models/interrupted', async () => {
|
|
439
|
+
return manager.getInterruptedDownloads();
|
|
440
|
+
});
|
|
441
|
+
// DELETE /models/interrupted/:fileName — discard a partial download
|
|
442
|
+
fastify.delete('/models/interrupted/:fileName', async (request) => {
|
|
443
|
+
await manager.deleteInterruptedDownload(request.params.fileName);
|
|
444
|
+
return { ok: true };
|
|
445
|
+
});
|
|
446
|
+
// GET /models/download?repo=...&fileName=...&type=gguf|mlx (SSE stream)
|
|
447
|
+
fastify.get('/models/download', async (request, reply) => {
|
|
448
|
+
const { repo, fileName, type } = request.query;
|
|
449
|
+
if (!repo) {
|
|
450
|
+
return reply.status(400).send({ error: 'repo is required' });
|
|
451
|
+
}
|
|
452
|
+
if (type !== 'mlx' && !fileName) {
|
|
453
|
+
return reply.status(400).send({ error: 'fileName is required for GGUF downloads' });
|
|
454
|
+
}
|
|
455
|
+
reply.raw.setHeader('Content-Type', 'text/event-stream');
|
|
456
|
+
reply.raw.setHeader('Cache-Control', 'no-cache');
|
|
457
|
+
reply.raw.setHeader('Connection', 'keep-alive');
|
|
458
|
+
let clientDisconnected = false;
|
|
459
|
+
reply.raw.on('close', () => { clientDisconnected = true; });
|
|
460
|
+
try {
|
|
461
|
+
let model;
|
|
462
|
+
if (type === 'mlx') {
|
|
463
|
+
// MLX: download entire repo
|
|
464
|
+
model = await manager.downloadMlxModel(repo, (progress) => {
|
|
465
|
+
if (!clientDisconnected) {
|
|
466
|
+
reply.raw.write(`data: ${JSON.stringify({ type: 'progress', ...progress })}\n\n`);
|
|
467
|
+
}
|
|
468
|
+
});
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
// GGUF: download single file
|
|
472
|
+
model = await manager.downloadModel(repo, fileName, (progress) => {
|
|
473
|
+
if (!clientDisconnected) {
|
|
474
|
+
reply.raw.write(`data: ${JSON.stringify({ type: 'progress', ...progress })}\n\n`);
|
|
475
|
+
}
|
|
476
|
+
});
|
|
477
|
+
// Auto-download mmproj for vision models (skip if user downloaded an mmproj directly)
|
|
478
|
+
if (!clientDisconnected && !fileName.toLowerCase().includes('mmproj')) {
|
|
479
|
+
const mmproj = await manager.autoDownloadMmproj(repo, (progress) => {
|
|
480
|
+
if (!clientDisconnected) {
|
|
481
|
+
reply.raw.write(`data: ${JSON.stringify({ type: 'progress', ...progress })}\n\n`);
|
|
482
|
+
}
|
|
483
|
+
});
|
|
484
|
+
if (mmproj && !clientDisconnected) {
|
|
485
|
+
reply.raw.write(`data: ${JSON.stringify({ type: 'mmproj', model: mmproj })}\n\n`);
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
}
|
|
489
|
+
if (!clientDisconnected) {
|
|
490
|
+
reply.raw.write(`data: ${JSON.stringify({ type: 'complete', model })}\n\n`);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
catch (err) {
|
|
494
|
+
if (!clientDisconnected) {
|
|
495
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
496
|
+
reply.raw.write(`data: ${JSON.stringify({ type: 'error', error: message })}\n\n`);
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
reply.raw.end();
|
|
500
|
+
});
|
|
501
|
+
// POST /models/:id/activate — route to correct engine, NO cross-engine kill
|
|
502
|
+
fastify.post('/models/:id/activate', async (request, reply) => {
|
|
503
|
+
const model = await manager.getModel(request.params.id);
|
|
504
|
+
if (!model) {
|
|
505
|
+
return reply.status(404).send({ error: 'Model not found' });
|
|
506
|
+
}
|
|
507
|
+
// Read existing config for contextSize and reasoningBudget from the resolved default
|
|
508
|
+
const fullConfig = getLLMConfig();
|
|
509
|
+
const resolvedKey = resolveDefaultName('models');
|
|
510
|
+
const currentDefault = fullConfig?.models[resolvedKey];
|
|
511
|
+
const currentObj = (currentDefault && typeof currentDefault !== 'string') ? currentDefault : null;
|
|
512
|
+
const engineName = model.type === 'mlx' ? 'mlx-serve' : 'llama-cpp';
|
|
513
|
+
const engine = engineRegistry.getEngine(engineName);
|
|
514
|
+
if (!engine) {
|
|
515
|
+
return reply.status(500).send({ error: `Engine ${engineName} not available` });
|
|
516
|
+
}
|
|
517
|
+
try {
|
|
518
|
+
await engine.swapChat(model.filePath, {
|
|
519
|
+
...(currentObj?.contextSize !== undefined ? { contextSize: currentObj.contextSize } : {}),
|
|
520
|
+
...(currentObj?.reasoningBudget !== undefined ? { reasoningBudget: currentObj.reasoningBudget } : {}),
|
|
521
|
+
});
|
|
522
|
+
}
|
|
523
|
+
catch (err) {
|
|
524
|
+
logger.error('[LocalLLM] Failed to load model:', err);
|
|
525
|
+
return reply.status(500).send({ error: `Failed to load: ${err.message}` });
|
|
526
|
+
}
|
|
527
|
+
const chatStatus = engine.getChatStatus();
|
|
528
|
+
const detectedCtx = chatStatus.contextSize;
|
|
529
|
+
const modelName = model.type === 'mlx' ? model.fileName : model.fileName.replace(/\.gguf$/i, '');
|
|
530
|
+
const localEntry = {
|
|
531
|
+
provider: 'local',
|
|
532
|
+
engine: engineName,
|
|
533
|
+
model: modelName,
|
|
534
|
+
...(detectedCtx ? { contextSize: detectedCtx } : {}),
|
|
535
|
+
reasoningBudget: currentObj?.reasoningBudget ?? 0,
|
|
536
|
+
};
|
|
537
|
+
// Update llm.json — write to engine key and set default pointer
|
|
538
|
+
try {
|
|
539
|
+
const config = getLLMConfig();
|
|
540
|
+
if (config) {
|
|
541
|
+
config.models[engineName] = localEntry;
|
|
542
|
+
config.models['default'] = engineName;
|
|
543
|
+
await saveLLMConfig(llmJsonPath, config);
|
|
544
|
+
LLMFactory.clearCache();
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
catch (err) {
|
|
548
|
+
logger.error('[LocalLLM] Failed to update llm.json:', err);
|
|
549
|
+
}
|
|
550
|
+
// Save state
|
|
551
|
+
await manager.saveState({ lastActiveModel: model.id });
|
|
552
|
+
return { ok: true, status: engine.getStatus() };
|
|
553
|
+
});
|
|
554
|
+
// POST /models/:id/activate-embedding
|
|
555
|
+
fastify.post('/models/:id/activate-embedding', async (request, reply) => {
|
|
556
|
+
const model = await manager.getModel(request.params.id);
|
|
557
|
+
if (!model) {
|
|
558
|
+
return reply.status(404).send({ error: 'Model not found' });
|
|
559
|
+
}
|
|
560
|
+
const engineName = model.type === 'mlx' ? 'mlx-serve' : 'llama-cpp';
|
|
561
|
+
const engine = engineRegistry.getEngine(engineName);
|
|
562
|
+
if (!engine) {
|
|
563
|
+
return reply.status(500).send({ error: `Engine ${engineName} not available` });
|
|
564
|
+
}
|
|
565
|
+
try {
|
|
566
|
+
await engine.loadEmbedding(model.filePath);
|
|
567
|
+
}
|
|
568
|
+
catch (err) {
|
|
569
|
+
logger.error('[LocalLLM] Failed to load embedding model:', err);
|
|
570
|
+
return reply.status(500).send({ error: `Failed to load: ${err.message}` });
|
|
571
|
+
}
|
|
572
|
+
// Update llm.json — write to engine key and set default pointer
|
|
573
|
+
try {
|
|
574
|
+
const config = getLLMConfig();
|
|
575
|
+
if (config) {
|
|
576
|
+
const embModelName = model.type === 'mlx' ? model.fileName : model.fileName.replace(/\.gguf$/i, '');
|
|
577
|
+
config.embeddings[engineName] = {
|
|
578
|
+
provider: 'local',
|
|
579
|
+
engine: engineName,
|
|
580
|
+
model: embModelName,
|
|
581
|
+
};
|
|
582
|
+
config.embeddings['default'] = engineName;
|
|
583
|
+
await saveLLMConfig(llmJsonPath, config);
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
catch (err) {
|
|
587
|
+
logger.error('[LocalLLM] Failed to update llm.json:', err);
|
|
588
|
+
}
|
|
589
|
+
return { ok: true, status: engine.getEmbeddingStatus() };
|
|
590
|
+
});
|
|
591
|
+
// DELETE /models/:id
|
|
592
|
+
fastify.delete('/models/:id', async (request, reply) => {
|
|
593
|
+
const model = await manager.getModel(request.params.id);
|
|
594
|
+
if (!model) {
|
|
595
|
+
return reply.status(404).send({ error: 'Model not found' });
|
|
596
|
+
}
|
|
597
|
+
// Don't delete if currently active in any engine (chat or embedding)
|
|
598
|
+
for (const engine of engineRegistry.getAllEngines()) {
|
|
599
|
+
const chatStatus = engine.getChatStatus();
|
|
600
|
+
if (chatStatus.running && chatStatus.activeModel === model.filePath) {
|
|
601
|
+
return reply.status(409).send({ error: 'Cannot delete the currently active model. Stop it first.' });
|
|
602
|
+
}
|
|
603
|
+
const embStatus = engine.getEmbeddingStatus();
|
|
604
|
+
if (embStatus.running && embStatus.activeModel === model.filePath) {
|
|
605
|
+
return reply.status(409).send({ error: 'Cannot delete the active embedding model. Stop it first.' });
|
|
606
|
+
}
|
|
607
|
+
}
|
|
608
|
+
await manager.deleteModel(request.params.id);
|
|
609
|
+
return { ok: true };
|
|
610
|
+
});
|
|
611
|
+
// GET /browse?q=...&limit=10&format=gguf|mlx
|
|
612
|
+
fastify.get('/browse', async (request, reply) => {
|
|
613
|
+
const { q, limit, format } = request.query;
|
|
614
|
+
if (!q) {
|
|
615
|
+
return reply.status(400).send({ error: 'q (query) is required' });
|
|
616
|
+
}
|
|
617
|
+
const fmt = format === 'mlx' ? 'mlx' : 'gguf';
|
|
618
|
+
return manager.browseHuggingFace(q, Number(limit) || 10, fmt);
|
|
619
|
+
});
|
|
620
|
+
// POST /stop — accept optional engine param to stop specific engine
|
|
621
|
+
fastify.post('/stop', async (request) => {
|
|
622
|
+
const engineName = request.body?.engine;
|
|
623
|
+
if (engineName) {
|
|
624
|
+
const engine = engineRegistry.getEngine(engineName);
|
|
625
|
+
if (engine)
|
|
626
|
+
await engine.unloadChat();
|
|
627
|
+
}
|
|
628
|
+
else {
|
|
629
|
+
// Legacy: stop all managed chat engines
|
|
630
|
+
for (const engine of engineRegistry.getAllEngines()) {
|
|
631
|
+
await engine.unloadChat();
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
return { ok: true };
|
|
635
|
+
});
|
|
636
|
+
// POST /stop-embedding — accept optional engine param
|
|
637
|
+
fastify.post('/stop-embedding', async (request) => {
|
|
638
|
+
const engineName = request.body?.engine;
|
|
639
|
+
if (engineName) {
|
|
640
|
+
const engine = engineRegistry.getEngine(engineName);
|
|
641
|
+
if (engine)
|
|
642
|
+
await engine.unloadEmbedding();
|
|
643
|
+
}
|
|
644
|
+
else {
|
|
645
|
+
for (const engine of engineRegistry.getAllEngines()) {
|
|
646
|
+
await engine.unloadEmbedding();
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
return { ok: true };
|
|
650
|
+
});
|
|
651
|
+
// GET /check-update — check for llama-cpp update
|
|
652
|
+
fastify.get('/check-update', async () => {
|
|
653
|
+
const engine = engineRegistry.getEngine('llama-cpp');
|
|
654
|
+
return engine.checkForUpdate();
|
|
655
|
+
});
|
|
656
|
+
// POST /update-binary — pull latest llama-server from GitHub
|
|
657
|
+
fastify.post('/update-binary', async (_request, reply) => {
|
|
658
|
+
const engine = engineRegistry.getEngine('llama-cpp');
|
|
659
|
+
if (engine.getBinarySource() === 'system') {
|
|
660
|
+
return reply.status(400).send({ error: 'llama-server is system-installed. Update it via your package manager.' });
|
|
661
|
+
}
|
|
662
|
+
if (engine.getChatStatus().running)
|
|
663
|
+
await engine.unloadChat();
|
|
664
|
+
if (engine.getEmbeddingStatus().running)
|
|
665
|
+
await engine.unloadEmbedding();
|
|
666
|
+
await engine.updateBinary();
|
|
667
|
+
return { ok: true, version: engine.getBinaryVersion() };
|
|
668
|
+
});
|
|
669
|
+
// GET /check-mlx-update — compare local mlx-serve version with latest GitHub release
|
|
670
|
+
fastify.get('/check-mlx-update', async () => {
|
|
671
|
+
const engine = engineRegistry.getEngine('mlx-serve');
|
|
672
|
+
return engine.checkForUpdate();
|
|
673
|
+
});
|
|
674
|
+
// POST /update-mlx-binary — pull latest mlx-serve from GitHub
|
|
675
|
+
fastify.post('/update-mlx-binary', async (_request, reply) => {
|
|
676
|
+
const engine = engineRegistry.getEngine('mlx-serve');
|
|
677
|
+
if (engine.getBinarySource() === 'system') {
|
|
678
|
+
return reply.status(400).send({ error: 'mlx-serve is system-installed. Update it manually.' });
|
|
679
|
+
}
|
|
680
|
+
if (engine.getChatStatus().running)
|
|
681
|
+
await engine.unloadChat();
|
|
682
|
+
if (engine.getEmbeddingStatus().running)
|
|
683
|
+
await engine.unloadEmbedding();
|
|
684
|
+
await engine.updateBinary();
|
|
685
|
+
return { ok: true, version: engine.getBinaryVersion() };
|
|
686
|
+
});
|
|
687
|
+
};
|
|
688
|
+
//# sourceMappingURL=local-llm.route.js.map
|