@tyvm/knowhow 0.0.32 → 0.0.34
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/autodoc/plugins/downloader/downloader.mdx +2 -2
- package/benchmarks/.dockerignore +7 -0
- package/benchmarks/README.md +166 -0
- package/benchmarks/docker/Dockerfile +68 -0
- package/benchmarks/example-config.yml +27 -0
- package/benchmarks/jest.config.js +13 -0
- package/benchmarks/package-lock.json +4297 -0
- package/benchmarks/package.json +39 -0
- package/benchmarks/results/4542435/2025-08-05/lms/lms-openai-gpt-oss-20b.json +2814 -0
- package/benchmarks/results/4542435/2025-08-05/lms/lms-qwen-qwen3-30b-a3b-2507.json +2014 -0
- package/benchmarks/results/4fb9125/2025-08-07/anthropic/anthropic-claude-sonnet-4-20250514.json +3121 -0
- package/benchmarks/results/5766aee/2025-08-02/lms-qwen/qwen3-coder-30b.json +98 -0
- package/benchmarks/results/6d73808/2025-08-07/openai/openai-gpt-5.json +3256 -0
- package/benchmarks/results/77bf0a6/2025-08-02/lms-qwen/qwen3-30b-a3b-2507.json +4298 -0
- package/benchmarks/results/8c0d445/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +3031 -0
- package/benchmarks/results/8c0d445/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +2990 -0
- package/benchmarks/results/ac6b2ab/2025-08-03/anthropic/anthropic-claude-sonnet-4-20250514.json +3256 -0
- package/benchmarks/results/ac6b2ab/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +3007 -0
- package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-2025-04-14.json +3256 -0
- package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-mini-2025-04-14.json +3036 -0
- package/benchmarks/results/ac6b2ab/2025-08-03/openai/openai-gpt-4.1-nano-2025-04-14.json +3280 -0
- package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-30b-a3b-2507.json +1920 -0
- package/benchmarks/results/adff675/2025-08-04/lms/lms-qwen-qwen3-coder-30b.json +3281 -0
- package/benchmarks/results/b502ed9/2025-08-03/lms-qwen/qwen3-coder-30b.json +2896 -0
- package/benchmarks/results/d1a8129/2025-08-03/lms/lms-qwen-qwen3-coder-30b.json +3011 -0
- package/benchmarks/results/e60471c/2025-08-03/lms/qwen3-30b-a3b-2507.json +3003 -0
- package/benchmarks/scripts/build-and-run.sh +47 -0
- package/benchmarks/scripts/clone-exercism.sh +92 -0
- package/benchmarks/scripts/validate.sh +48 -0
- package/benchmarks/src/__tests__/runner.test.ts +27 -0
- package/benchmarks/src/cli.ts +90 -0
- package/benchmarks/src/evaluators/EvaluatorRegistry.ts +64 -0
- package/benchmarks/src/evaluators/JavaScriptEvaluator.ts +183 -0
- package/benchmarks/src/evaluators/index.ts +3 -0
- package/benchmarks/src/evaluators/types.ts +22 -0
- package/benchmarks/src/index.ts +3 -0
- package/benchmarks/src/providers.ts +13 -0
- package/benchmarks/src/runner.ts +824 -0
- package/benchmarks/src/types.ts +63 -0
- package/benchmarks/tsconfig.json +19 -0
- package/jest.config.js +2 -1
- package/leaderboard/README.md +148 -0
- package/leaderboard/app/api/benchmark-data/route.ts +131 -0
- package/leaderboard/app/api/benchmark-detail/route.ts +172 -0
- package/leaderboard/app/details/[model]/[provider]/[language]/page.tsx +501 -0
- package/leaderboard/app/exercise/[model]/[provider]/[language]/[exercise]/page.tsx +375 -0
- package/leaderboard/app/globals.css +27 -0
- package/leaderboard/app/layout.tsx +21 -0
- package/leaderboard/app/page.tsx +170 -0
- package/leaderboard/components/LeaderboardTable.tsx +168 -0
- package/leaderboard/components/PerformanceChart.tsx +109 -0
- package/leaderboard/next-env.d.ts +5 -0
- package/leaderboard/next.config.js +4 -0
- package/leaderboard/package-lock.json +6363 -0
- package/leaderboard/package.json +28 -0
- package/leaderboard/postcss.config.js +6 -0
- package/leaderboard/tailwind.config.js +17 -0
- package/leaderboard/tsconfig.json +28 -0
- package/leaderboard/types/benchmark.ts +67 -0
- package/leaderboard/utils/dataProcessor.ts +33 -0
- package/package.json +2 -1
- package/src/agents/base/base.ts +147 -21
- package/src/agents/base/prompt.ts +28 -0
- package/src/agents/index.ts +3 -0
- package/src/agents/patcher/patcher.ts +6 -4
- package/src/agents/setup/setup.ts +56 -0
- package/src/agents/tools/agentCall.ts +6 -2
- package/src/agents/tools/aiClient.ts +74 -8
- package/src/agents/tools/execCommand.ts +13 -14
- package/src/agents/tools/executeScript/README.md +16 -0
- package/src/agents/tools/index.ts +2 -0
- package/src/agents/tools/list.ts +73 -16
- package/src/agents/tools/startAgentTask.ts +109 -0
- package/src/agents/tools/textSearch.ts +1 -1
- package/src/agents/tools/visionTool.ts +31 -2
- package/src/agents/tools/ycmd/client.ts +608 -0
- package/src/agents/tools/ycmd/definitions.ts +294 -0
- package/src/agents/tools/ycmd/detection.ts +211 -0
- package/src/agents/tools/ycmd/index.ts +11 -0
- package/src/agents/tools/ycmd/installer.ts +251 -0
- package/src/agents/tools/ycmd/server.ts +535 -0
- package/src/agents/tools/ycmd/serverManager.ts +316 -0
- package/src/agents/tools/ycmd/tools/completion.ts +113 -0
- package/src/agents/tools/ycmd/tools/diagnostics.ts +155 -0
- package/src/agents/tools/ycmd/tools/getLocations.ts +173 -0
- package/src/agents/tools/ycmd/tools/goto.ts +169 -0
- package/src/agents/tools/ycmd/tools/refactor.ts +204 -0
- package/src/agents/tools/ycmd/tools/signature.ts +174 -0
- package/src/agents/tools/ycmd/tools/start.ts +95 -0
- package/src/agents/tools/ycmd/utils/pathUtils.ts +59 -0
- package/src/ai.ts +15 -0
- package/src/chat/CliChatService.ts +277 -0
- package/src/chat/modules/AgentModule.ts +980 -0
- package/src/chat/modules/AskModule.ts +98 -0
- package/src/chat/modules/BaseChatModule.ts +66 -0
- package/src/chat/modules/InternalChatModule.ts +174 -0
- package/src/chat/modules/SearchModule.ts +166 -0
- package/src/chat/modules/SetupModule.ts +185 -0
- package/src/chat/modules/SystemModule.ts +120 -0
- package/src/chat/modules/VoiceModule.ts +70 -0
- package/src/chat/modules/index.js +5 -0
- package/src/chat/types.ts +97 -0
- package/src/chat.ts +9 -1
- package/src/chat2.ts +62 -0
- package/src/cli.ts +264 -35
- package/src/clients/anthropic.ts +14 -7
- package/src/clients/gemini.ts +15 -7
- package/src/clients/http.ts +17 -7
- package/src/clients/index.ts +117 -4
- package/src/clients/knowhow.ts +7 -2
- package/src/clients/knowhowMcp.ts +118 -0
- package/src/clients/openai.ts +32 -8
- package/src/clients/types.ts +1 -0
- package/src/clients/xai.ts +17 -5
- package/src/config.ts +30 -5
- package/src/conversion.ts +4 -1
- package/src/embeddings.ts +79 -23
- package/src/login.ts +26 -9
- package/src/microphone.ts +0 -1
- package/src/plugins/downloader/downloader.ts +72 -24
- package/src/plugins/downloader/plugin.ts +3 -1
- package/src/plugins/plugins.ts +3 -0
- package/src/processors/CustomVariables.ts +425 -0
- package/src/processors/HarmonyToolProcessor.ts +264 -0
- package/src/processors/XmlToolCallProcessor.ts +533 -0
- package/src/processors/index.ts +3 -0
- package/src/prompts/KnowhowConfigExamples.ts +376 -0
- package/src/services/KnowhowClient.ts +49 -3
- package/src/services/Mcp.ts +42 -3
- package/src/services/McpServer.ts +14 -4
- package/src/services/McpWebsocketTransport.ts +21 -7
- package/src/services/MessageProcessor.ts +10 -5
- package/src/services/index.ts +5 -0
- package/src/services/script-execution/ScriptExecutor.ts +34 -1
- package/src/services/types.ts +17 -14
- package/src/types.ts +17 -0
- package/src/utils/index.ts +138 -0
- package/tests/XmlToolCallProcessor.test.ts +468 -0
- package/tests/manual/ycmd/debug_diagnostics_test.ts +127 -0
- package/tests/manual/ycmd/fixtures/debug_diagnostics.ts +26 -0
- package/tests/manual/ycmd/fixtures/file_change_test.ts +17 -0
- package/tests/manual/ycmd/minimal_advanced_test.ts +108 -0
- package/tests/manual/ycmd/simple_diagnostics_test.ts +61 -0
- package/tests/manual/ycmd/simple_test.ts +74 -0
- package/tests/manual/ycmd/test-typescript-sample.ts +34 -0
- package/tests/manual/ycmd/test_advanced_features.ts +407 -0
- package/tests/manual/ycmd/test_advanced_with_tools.ts +320 -0
- package/tests/manual/ycmd/test_comprehensive_typescript.ts +179 -0
- package/tests/manual/ycmd/test_diagnostics_file_changes.ts +249 -0
- package/tests/manual/ycmd/test_diagnostics_fix.ts +99 -0
- package/tests/manual/ycmd/test_diagnostics_simple.ts +100 -0
- package/tests/manual/ycmd/test_diagnostics_timing.ts +120 -0
- package/tests/manual/ycmd/test_discover_commands.ts +310 -0
- package/tests/manual/ycmd/test_endpoints.ts +115 -0
- package/tests/manual/ycmd/test_final_comprehensive.ts +218 -0
- package/tests/manual/ycmd/test_final_validation.ts +150 -0
- package/tests/manual/ycmd/test_implementation.js +42 -0
- package/tests/manual/ycmd/test_individual_ycmd_tool.ts +39 -0
- package/tests/manual/ycmd/test_server_manager.ts +52 -0
- package/tests/manual/ycmd/test_simple_debug.ts +86 -0
- package/tests/manual/ycmd/test_tsserver_workflow.js +83 -0
- package/tests/manual/ycmd/test_tsserver_workflow.ts +122 -0
- package/tests/manual/ycmd/test_typescript_simple.ts +48 -0
- package/tests/manual/ycmd/test_typescript_ycmd.ts +105 -0
- package/tests/manual/ycmd/test_workspace_config.ts +90 -0
- package/tests/manual/ycmd/test_ycmd_auto_start.ts +137 -0
- package/tests/manual/ycmd/test_ycmd_comprehensive.ts +73 -0
- package/tests/manual/ycmd/test_ycmd_connection.py +10 -0
- package/tests/manual/ycmd/test_ycmd_direct.ts +142 -0
- package/tests/manual/ycmd/test_ycmd_experiment.ts +48 -0
- package/tests/manual/ycmd/test_ycmd_final.ts +200 -0
- package/tests/manual/ycmd/test_ycmd_fixed.py +18 -0
- package/tests/manual/ycmd/test_ycmd_integration.ts +112 -0
- package/tests/manual/ycmd/test_ycmd_simple.ts +45 -0
- package/tests/manual/ycmd/test_ycmd_usage.py +27 -0
- package/tests/manual/ycmd/working_simple_test.ts +134 -0
- package/ts_build/src/agents/base/base.d.ts +14 -1
- package/ts_build/src/agents/base/base.js +91 -17
- package/ts_build/src/agents/base/base.js.map +1 -1
- package/ts_build/src/agents/base/prompt.d.ts +1 -1
- package/ts_build/src/agents/base/prompt.js +28 -0
- package/ts_build/src/agents/base/prompt.js.map +1 -1
- package/ts_build/src/agents/index.d.ts +2 -0
- package/ts_build/src/agents/index.js +2 -0
- package/ts_build/src/agents/index.js.map +1 -1
- package/ts_build/src/agents/patcher/patcher.js +6 -3
- package/ts_build/src/agents/patcher/patcher.js.map +1 -1
- package/ts_build/src/agents/setup/setup.d.ts +8 -0
- package/ts_build/src/agents/setup/setup.js +59 -0
- package/ts_build/src/agents/setup/setup.js.map +1 -0
- package/ts_build/src/agents/tools/agentCall.js +5 -2
- package/ts_build/src/agents/tools/agentCall.js.map +1 -1
- package/ts_build/src/agents/tools/aiClient.d.ts +6 -5
- package/ts_build/src/agents/tools/aiClient.js +37 -6
- package/ts_build/src/agents/tools/aiClient.js.map +1 -1
- package/ts_build/src/agents/tools/execCommand.d.ts +2 -2
- package/ts_build/src/agents/tools/execCommand.js +5 -6
- package/ts_build/src/agents/tools/execCommand.js.map +1 -1
- package/ts_build/src/agents/tools/executeScript/index.d.ts +1 -1
- package/ts_build/src/agents/tools/index.d.ts +2 -0
- package/ts_build/src/agents/tools/index.js +2 -0
- package/ts_build/src/agents/tools/index.js.map +1 -1
- package/ts_build/src/agents/tools/list.js +66 -16
- package/ts_build/src/agents/tools/list.js.map +1 -1
- package/ts_build/src/agents/tools/startAgentTask.d.ts +13 -0
- package/ts_build/src/agents/tools/startAgentTask.js +74 -0
- package/ts_build/src/agents/tools/startAgentTask.js.map +1 -0
- package/ts_build/src/agents/tools/startChatTask.d.ts +13 -0
- package/ts_build/src/agents/tools/startChatTask.js +73 -0
- package/ts_build/src/agents/tools/startChatTask.js.map +1 -0
- package/ts_build/src/agents/tools/textSearch.js +1 -1
- package/ts_build/src/agents/tools/textSearch.js.map +1 -1
- package/ts_build/src/agents/tools/visionTool.d.ts +1 -1
- package/ts_build/src/agents/tools/visionTool.js +23 -3
- package/ts_build/src/agents/tools/visionTool.js.map +1 -1
- package/ts_build/src/agents/tools/ycmd/client.d.ts +93 -0
- package/ts_build/src/agents/tools/ycmd/client.js +355 -0
- package/ts_build/src/agents/tools/ycmd/client.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/definitions.d.ts +345 -0
- package/ts_build/src/agents/tools/ycmd/definitions.js +298 -0
- package/ts_build/src/agents/tools/ycmd/definitions.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/detection.d.ts +11 -0
- package/ts_build/src/agents/tools/ycmd/detection.js +175 -0
- package/ts_build/src/agents/tools/ycmd/detection.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/index.d.ts +8 -0
- package/ts_build/src/agents/tools/ycmd/index.js +20 -0
- package/ts_build/src/agents/tools/ycmd/index.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/installer.d.ts +19 -0
- package/ts_build/src/agents/tools/ycmd/installer.js +196 -0
- package/ts_build/src/agents/tools/ycmd/installer.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/server.d.ts +35 -0
- package/ts_build/src/agents/tools/ycmd/server.js +363 -0
- package/ts_build/src/agents/tools/ycmd/server.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/serverManager.d.ts +39 -0
- package/ts_build/src/agents/tools/ycmd/serverManager.js +210 -0
- package/ts_build/src/agents/tools/ycmd/serverManager.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/completion.d.ts +22 -0
- package/ts_build/src/agents/tools/ycmd/tools/completion.js +72 -0
- package/ts_build/src/agents/tools/ycmd/tools/completion.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/diagnostics.d.ts +42 -0
- package/ts_build/src/agents/tools/ycmd/tools/diagnostics.js +88 -0
- package/ts_build/src/agents/tools/ycmd/tools/diagnostics.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/getLocations.d.ts +22 -0
- package/ts_build/src/agents/tools/ycmd/tools/getLocations.js +142 -0
- package/ts_build/src/agents/tools/ycmd/tools/getLocations.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/goto.d.ts +20 -0
- package/ts_build/src/agents/tools/ycmd/tools/goto.js +101 -0
- package/ts_build/src/agents/tools/ycmd/tools/goto.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/refactor.d.ts +32 -0
- package/ts_build/src/agents/tools/ycmd/tools/refactor.js +123 -0
- package/ts_build/src/agents/tools/ycmd/tools/refactor.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/signature.d.ts +25 -0
- package/ts_build/src/agents/tools/ycmd/tools/signature.js +110 -0
- package/ts_build/src/agents/tools/ycmd/tools/signature.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/tools/start.d.ts +17 -0
- package/ts_build/src/agents/tools/ycmd/tools/start.js +65 -0
- package/ts_build/src/agents/tools/ycmd/tools/start.js.map +1 -0
- package/ts_build/src/agents/tools/ycmd/utils/pathUtils.d.ts +4 -0
- package/ts_build/src/agents/tools/ycmd/utils/pathUtils.js +67 -0
- package/ts_build/src/agents/tools/ycmd/utils/pathUtils.js.map +1 -0
- package/ts_build/src/ai.d.ts +1 -0
- package/ts_build/src/ai.js +40 -1
- package/ts_build/src/ai.js.map +1 -1
- package/ts_build/src/chat/ChatCommandHandler.d.ts +36 -0
- package/ts_build/src/chat/ChatCommandHandler.js +268 -0
- package/ts_build/src/chat/ChatCommandHandler.js.map +1 -0
- package/ts_build/src/chat/ChatInputManager.d.ts +22 -0
- package/ts_build/src/chat/ChatInputManager.js +85 -0
- package/ts_build/src/chat/ChatInputManager.js.map +1 -0
- package/ts_build/src/chat/ChatManager.d.ts +49 -0
- package/ts_build/src/chat/ChatManager.js +271 -0
- package/ts_build/src/chat/ChatManager.js.map +1 -0
- package/ts_build/src/chat/ChatSession.d.ts +32 -0
- package/ts_build/src/chat/ChatSession.js +3 -0
- package/ts_build/src/chat/ChatSession.js.map +1 -0
- package/ts_build/src/chat/ChatSessionManager.d.ts +19 -0
- package/ts_build/src/chat/ChatSessionManager.js +188 -0
- package/ts_build/src/chat/ChatSessionManager.js.map +1 -0
- package/ts_build/src/chat/ChatStateManager.d.ts +58 -0
- package/ts_build/src/chat/ChatStateManager.js +156 -0
- package/ts_build/src/chat/ChatStateManager.js.map +1 -0
- package/ts_build/src/chat/CliChatService.d.ts +35 -0
- package/ts_build/src/chat/CliChatService.js +201 -0
- package/ts_build/src/chat/CliChatService.js.map +1 -0
- package/ts_build/src/chat/InterruptibleInput.d.ts +20 -0
- package/ts_build/src/chat/InterruptibleInput.js +109 -0
- package/ts_build/src/chat/InterruptibleInput.js.map +1 -0
- package/ts_build/src/chat/interfaces/ChatModule.d.ts +6 -0
- package/ts_build/src/chat/interfaces/ChatModule.js +3 -0
- package/ts_build/src/chat/interfaces/ChatModule.js.map +1 -0
- package/ts_build/src/chat/modules/AgentModule.d.ts +56 -0
- package/ts_build/src/chat/modules/AgentModule.js +705 -0
- package/ts_build/src/chat/modules/AgentModule.js.map +1 -0
- package/ts_build/src/chat/modules/AskModule.d.ts +10 -0
- package/ts_build/src/chat/modules/AskModule.js +63 -0
- package/ts_build/src/chat/modules/AskModule.js.map +1 -0
- package/ts_build/src/chat/modules/BaseChatModule.d.ts +14 -0
- package/ts_build/src/chat/modules/BaseChatModule.js +32 -0
- package/ts_build/src/chat/modules/BaseChatModule.js.map +1 -0
- package/ts_build/src/chat/modules/InternalChatModule.d.ts +24 -0
- package/ts_build/src/chat/modules/InternalChatModule.js +127 -0
- package/ts_build/src/chat/modules/InternalChatModule.js.map +1 -0
- package/ts_build/src/chat/modules/SearchModule.d.ts +12 -0
- package/ts_build/src/chat/modules/SearchModule.js +119 -0
- package/ts_build/src/chat/modules/SearchModule.js.map +1 -0
- package/ts_build/src/chat/modules/SetupModule.d.ts +15 -0
- package/ts_build/src/chat/modules/SetupModule.js +147 -0
- package/ts_build/src/chat/modules/SetupModule.js.map +1 -0
- package/ts_build/src/chat/modules/SystemModule.d.ts +14 -0
- package/ts_build/src/chat/modules/SystemModule.js +90 -0
- package/ts_build/src/chat/modules/SystemModule.js.map +1 -0
- package/ts_build/src/chat/modules/VoiceModule.d.ts +11 -0
- package/ts_build/src/chat/modules/VoiceModule.js +57 -0
- package/ts_build/src/chat/modules/VoiceModule.js.map +1 -0
- package/ts_build/src/chat/types.d.ts +83 -0
- package/ts_build/src/chat/types.js +3 -0
- package/ts_build/src/chat/types.js.map +1 -0
- package/ts_build/src/chat.js +7 -1
- package/ts_build/src/chat.js.map +1 -1
- package/ts_build/src/chat2.d.ts +3 -0
- package/ts_build/src/chat2.js +47 -0
- package/ts_build/src/chat2.js.map +1 -0
- package/ts_build/src/cli.js +218 -37
- package/ts_build/src/cli.js.map +1 -1
- package/ts_build/src/clients/anthropic.d.ts +5 -2
- package/ts_build/src/clients/anthropic.js +12 -7
- package/ts_build/src/clients/anthropic.js.map +1 -1
- package/ts_build/src/clients/gemini.d.ts +6 -3
- package/ts_build/src/clients/gemini.js +13 -7
- package/ts_build/src/clients/gemini.js.map +1 -1
- package/ts_build/src/clients/http.d.ts +1 -0
- package/ts_build/src/clients/http.js +12 -5
- package/ts_build/src/clients/http.js.map +1 -1
- package/ts_build/src/clients/index.d.ts +10 -0
- package/ts_build/src/clients/index.js +74 -4
- package/ts_build/src/clients/index.js.map +1 -1
- package/ts_build/src/clients/knowhow.d.ts +3 -1
- package/ts_build/src/clients/knowhow.js +8 -2
- package/ts_build/src/clients/knowhow.js.map +1 -1
- package/ts_build/src/clients/knowhowMcp.d.ts +20 -0
- package/ts_build/src/clients/knowhowMcp.js +86 -0
- package/ts_build/src/clients/knowhowMcp.js.map +1 -0
- package/ts_build/src/clients/openai.d.ts +5 -2
- package/ts_build/src/clients/openai.js +29 -8
- package/ts_build/src/clients/openai.js.map +1 -1
- package/ts_build/src/clients/types.d.ts +1 -0
- package/ts_build/src/clients/xai.d.ts +5 -2
- package/ts_build/src/clients/xai.js +15 -5
- package/ts_build/src/clients/xai.js.map +1 -1
- package/ts_build/src/config.js +24 -3
- package/ts_build/src/config.js.map +1 -1
- package/ts_build/src/conversion.js +6 -4
- package/ts_build/src/conversion.js.map +1 -1
- package/ts_build/src/embeddings.d.ts +2 -1
- package/ts_build/src/embeddings.js +62 -17
- package/ts_build/src/embeddings.js.map +1 -1
- package/ts_build/src/login.d.ts +1 -1
- package/ts_build/src/login.js +21 -7
- package/ts_build/src/login.js.map +1 -1
- package/ts_build/src/microphone.js.map +1 -1
- package/ts_build/src/plugins/downloader/downloader.d.ts +4 -5
- package/ts_build/src/plugins/downloader/downloader.js +55 -26
- package/ts_build/src/plugins/downloader/downloader.js.map +1 -1
- package/ts_build/src/plugins/downloader/plugin.js +5 -3
- package/ts_build/src/plugins/downloader/plugin.js.map +1 -1
- package/ts_build/src/plugins/plugins.js +3 -0
- package/ts_build/src/plugins/plugins.js.map +1 -1
- package/ts_build/src/processors/CustomVariables.d.ts +32 -0
- package/ts_build/src/processors/CustomVariables.js +297 -0
- package/ts_build/src/processors/CustomVariables.js.map +1 -0
- package/ts_build/src/processors/HarmonyToolProcessor.d.ts +15 -0
- package/ts_build/src/processors/HarmonyToolProcessor.js +154 -0
- package/ts_build/src/processors/HarmonyToolProcessor.js.map +1 -0
- package/ts_build/src/processors/XmlToolCallProcessor.d.ts +14 -0
- package/ts_build/src/processors/XmlToolCallProcessor.js +357 -0
- package/ts_build/src/processors/XmlToolCallProcessor.js.map +1 -0
- package/ts_build/src/processors/index.d.ts +3 -0
- package/ts_build/src/processors/index.js +7 -1
- package/ts_build/src/processors/index.js.map +1 -1
- package/ts_build/src/prompts/KnowhowConfigExamples.d.ts +2 -0
- package/ts_build/src/prompts/KnowhowConfigExamples.js +379 -0
- package/ts_build/src/prompts/KnowhowConfigExamples.js.map +1 -0
- package/ts_build/src/services/KnowhowClient.d.ts +22 -0
- package/ts_build/src/services/KnowhowClient.js +14 -2
- package/ts_build/src/services/KnowhowClient.js.map +1 -1
- package/ts_build/src/services/Mcp.d.ts +1 -0
- package/ts_build/src/services/Mcp.js +20 -3
- package/ts_build/src/services/Mcp.js.map +1 -1
- package/ts_build/src/services/McpServer.d.ts +1 -1
- package/ts_build/src/services/McpServer.js +8 -4
- package/ts_build/src/services/McpServer.js.map +1 -1
- package/ts_build/src/services/McpWebsocketTransport.js +17 -7
- package/ts_build/src/services/McpWebsocketTransport.js.map +1 -1
- package/ts_build/src/services/MessageProcessor.d.ts +1 -1
- package/ts_build/src/services/MessageProcessor.js +4 -4
- package/ts_build/src/services/MessageProcessor.js.map +1 -1
- package/ts_build/src/services/index.d.ts +2 -0
- package/ts_build/src/services/index.js +4 -0
- package/ts_build/src/services/index.js.map +1 -1
- package/ts_build/src/services/script-execution/ScriptExecutor.d.ts +1 -0
- package/ts_build/src/services/script-execution/ScriptExecutor.js +23 -0
- package/ts_build/src/services/script-execution/ScriptExecutor.js.map +1 -1
- package/ts_build/src/services/types.d.ts +2 -6
- package/ts_build/src/services/types.js +4 -4
- package/ts_build/src/services/types.js.map +1 -1
- package/ts_build/src/types.d.ts +11 -0
- package/ts_build/src/types.js +8 -0
- package/ts_build/src/types.js.map +1 -1
- package/ts_build/src/utils/index.d.ts +2 -0
- package/ts_build/src/utils/index.js +102 -1
- package/ts_build/src/utils/index.js.map +1 -1
- package/ts_build/tests/XmlToolCallProcessor.test.d.ts +1 -0
- package/ts_build/tests/XmlToolCallProcessor.test.js +376 -0
- package/ts_build/tests/XmlToolCallProcessor.test.js.map +1 -0
- package/ts_build/tests/manual/ycmd/debug_diagnostics_test.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/debug_diagnostics_test.js +114 -0
- package/ts_build/tests/manual/ycmd/debug_diagnostics_test.js.map +1 -0
- package/ts_build/tests/manual/ycmd/minimal_advanced_test.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/minimal_advanced_test.js +104 -0
- package/ts_build/tests/manual/ycmd/minimal_advanced_test.js.map +1 -0
- package/ts_build/tests/manual/ycmd/simple_diagnostics_test.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/simple_diagnostics_test.js +74 -0
- package/ts_build/tests/manual/ycmd/simple_diagnostics_test.js.map +1 -0
- package/ts_build/tests/manual/ycmd/simple_test.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/simple_test.js +82 -0
- package/ts_build/tests/manual/ycmd/simple_test.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test-typescript-sample.d.ts +14 -0
- package/ts_build/tests/manual/ycmd/test-typescript-sample.js +20 -0
- package/ts_build/tests/manual/ycmd/test-typescript-sample.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_advanced_features.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_advanced_features.js +297 -0
- package/ts_build/tests/manual/ycmd/test_advanced_features.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_advanced_with_tools.d.ts +3 -0
- package/ts_build/tests/manual/ycmd/test_advanced_with_tools.js +262 -0
- package/ts_build/tests/manual/ycmd/test_advanced_with_tools.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_comprehensive_typescript.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_comprehensive_typescript.js +186 -0
- package/ts_build/tests/manual/ycmd/test_comprehensive_typescript.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_file_changes.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_file_changes.js +174 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_file_changes.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_fix.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_fix.js +106 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_fix.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_simple.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_simple.js +104 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_simple.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_timing.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_timing.js +119 -0
- package/ts_build/tests/manual/ycmd/test_diagnostics_timing.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_discover_commands.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_discover_commands.js +243 -0
- package/ts_build/tests/manual/ycmd/test_discover_commands.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_endpoints.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_endpoints.js +120 -0
- package/ts_build/tests/manual/ycmd/test_endpoints.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_final_comprehensive.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_final_comprehensive.js +221 -0
- package/ts_build/tests/manual/ycmd/test_final_comprehensive.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_final_validation.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_final_validation.js +160 -0
- package/ts_build/tests/manual/ycmd/test_final_validation.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_individual_ycmd_tool.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_individual_ycmd_tool.js +37 -0
- package/ts_build/tests/manual/ycmd/test_individual_ycmd_tool.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_server_manager.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_server_manager.js +38 -0
- package/ts_build/tests/manual/ycmd/test_server_manager.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_simple_debug.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_simple_debug.js +99 -0
- package/ts_build/tests/manual/ycmd/test_simple_debug.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_tsserver_workflow.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_tsserver_workflow.js +128 -0
- package/ts_build/tests/manual/ycmd/test_tsserver_workflow.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_typescript_simple.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_typescript_simple.js +66 -0
- package/ts_build/tests/manual/ycmd/test_typescript_simple.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_typescript_ycmd.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_typescript_ycmd.js +105 -0
- package/ts_build/tests/manual/ycmd/test_typescript_ycmd.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_workspace_config.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_workspace_config.js +89 -0
- package/ts_build/tests/manual/ycmd/test_workspace_config.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_auto_start.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_auto_start.js +130 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_auto_start.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_comprehensive.d.ts +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_comprehensive.js +83 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_comprehensive.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_direct.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_direct.js +149 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_direct.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_experiment.d.ts +15 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_experiment.js +58 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_experiment.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_final.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_final.js +195 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_final.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_integration.d.ts +3 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_integration.js +110 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_integration.js.map +1 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_simple.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_simple.js +36 -0
- package/ts_build/tests/manual/ycmd/test_ycmd_simple.js.map +1 -0
- package/ts_build/tests/manual/ycmd/working_simple_test.d.ts +2 -0
- package/ts_build/tests/manual/ycmd/working_simple_test.js +134 -0
- package/ts_build/tests/manual/ycmd/working_simple_test.js.map +1 -0
- package/tsconfig.json +3 -1
|
@@ -0,0 +1,980 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent Chat Module - Handles agent interactions
|
|
3
|
+
*/
|
|
4
|
+
import { KnowhowSimpleClient } from "../../services/KnowhowClient";
|
|
5
|
+
import * as fs from "fs";
|
|
6
|
+
import * as path from "path";
|
|
7
|
+
|
|
8
|
+
import { formatChatInput } from "../../chat";
|
|
9
|
+
import { BaseChatModule } from "./BaseChatModule";
|
|
10
|
+
import { services } from "../../services/index";
|
|
11
|
+
import { BaseAgent } from "../../agents/index";
|
|
12
|
+
import { ChatCommand, ChatMode, ChatContext } from "../types";
|
|
13
|
+
import { ChatInteraction } from "../../types";
|
|
14
|
+
import { Marked } from "../../utils/index";
|
|
15
|
+
import { TokenCompressor } from "../../processors/TokenCompressor";
|
|
16
|
+
import { ToolResponseCache } from "../../processors/ToolResponseCache";
|
|
17
|
+
import {
|
|
18
|
+
CustomVariables,
|
|
19
|
+
XmlToolCallProcessor,
|
|
20
|
+
HarmonyToolProcessor,
|
|
21
|
+
} from "../../processors/index";
|
|
22
|
+
import { TaskInfo, ChatSession } from "../types";
|
|
23
|
+
import { agents } from "../../agents";
|
|
24
|
+
|
|
25
|
+
export class AgentModule extends BaseChatModule {
|
|
26
|
+
name = "agent";
|
|
27
|
+
description = "Agent interaction functionality";
|
|
28
|
+
|
|
29
|
+
// Enhanced task registry for managing agents with metadata
|
|
30
|
+
private taskRegistry = new Map<string, TaskInfo>();
|
|
31
|
+
|
|
32
|
+
// Sessions directory path
|
|
33
|
+
private sessionsDir = "./.knowhow/chats/sessions";
|
|
34
|
+
|
|
35
|
+
constructor() {
|
|
36
|
+
super();
|
|
37
|
+
// Ensure sessions directory exists
|
|
38
|
+
if (!fs.existsSync(this.sessionsDir)) {
|
|
39
|
+
fs.mkdirSync(this.sessionsDir, { recursive: true });
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
getCommands(): ChatCommand[] {
|
|
44
|
+
return [
|
|
45
|
+
{
|
|
46
|
+
name: "agent",
|
|
47
|
+
description: "Start an agent by name",
|
|
48
|
+
handler: this.handleAgentCommand.bind(this),
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: "agents",
|
|
52
|
+
description: "List available agents",
|
|
53
|
+
handler: this.handleAgentsCommand.bind(this),
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: "attach",
|
|
57
|
+
description: "Attach to a running session or resume an old session",
|
|
58
|
+
handler: this.handleAttachCommand.bind(this),
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
name: "sessions",
|
|
62
|
+
description: "List active tasks and saved sessions",
|
|
63
|
+
handler: this.handleSessionsCommand.bind(this),
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
getModes(): ChatMode[] {
|
|
69
|
+
return [
|
|
70
|
+
{
|
|
71
|
+
name: "agent",
|
|
72
|
+
description: "Agent interaction mode",
|
|
73
|
+
active: true,
|
|
74
|
+
},
|
|
75
|
+
];
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
async handleAgentCommand(args: string[]): Promise<void> {
|
|
79
|
+
const context = this.chatService?.getContext();
|
|
80
|
+
|
|
81
|
+
// If no args provided, toggle agent mode
|
|
82
|
+
if (args.length === 0) {
|
|
83
|
+
if (context?.agentMode) {
|
|
84
|
+
// Disable agent mode
|
|
85
|
+
if (context) {
|
|
86
|
+
context.agentMode = false;
|
|
87
|
+
context.selectedAgent = undefined;
|
|
88
|
+
context.currentAgent = undefined;
|
|
89
|
+
}
|
|
90
|
+
console.log("Agent mode disabled. Switched to chat mode.");
|
|
91
|
+
return;
|
|
92
|
+
} else {
|
|
93
|
+
// Show usage when not in agent mode and no args
|
|
94
|
+
console.log(
|
|
95
|
+
"Agent mode is currently disabled. Use /agent <agent_name> to enable it, or /agents to list available agents."
|
|
96
|
+
);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const agentName = args[0];
|
|
102
|
+
const allAgents = agents();
|
|
103
|
+
|
|
104
|
+
try {
|
|
105
|
+
if (allAgents && allAgents[agentName]) {
|
|
106
|
+
// Set selected agent in context and enable agent mode
|
|
107
|
+
if (context) {
|
|
108
|
+
context.selectedAgent = allAgents[agentName];
|
|
109
|
+
context.agentMode = true;
|
|
110
|
+
context.currentAgent = agentName;
|
|
111
|
+
}
|
|
112
|
+
console.log(
|
|
113
|
+
`Agent mode enabled. Selected agent: ${agentName}. Type your task to get started.`
|
|
114
|
+
);
|
|
115
|
+
} else {
|
|
116
|
+
console.log(
|
|
117
|
+
`Agent "${agentName}" not found. Use /agents to list available agents.`
|
|
118
|
+
);
|
|
119
|
+
}
|
|
120
|
+
} catch (error) {
|
|
121
|
+
console.error(`Error selecting agent ${agentName}:`, error);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async handleAttachCommand(args: string[]): Promise<void> {
|
|
126
|
+
if (args.length === 0) {
|
|
127
|
+
// Get both running tasks and saved sessions
|
|
128
|
+
const runningTasks = Array.from(this.taskRegistry.values());
|
|
129
|
+
const savedSessions = await this.listAvailableSessions();
|
|
130
|
+
|
|
131
|
+
if (runningTasks.length === 0 && savedSessions.length === 0) {
|
|
132
|
+
console.log("No active tasks or saved sessions found to attach to.");
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Show available options for selection
|
|
137
|
+
console.log("\n📋 Available Sessions & Tasks:");
|
|
138
|
+
console.log("─".repeat(80));
|
|
139
|
+
console.log(
|
|
140
|
+
"ID".padEnd(25) + "Agent".padEnd(15) + "Status".padEnd(12) + "Type"
|
|
141
|
+
);
|
|
142
|
+
console.log("─".repeat(80));
|
|
143
|
+
|
|
144
|
+
// Show saved sessions
|
|
145
|
+
savedSessions.forEach((session) => {
|
|
146
|
+
console.log(
|
|
147
|
+
session.sessionId.padEnd(25) +
|
|
148
|
+
session.agentName.padEnd(15) +
|
|
149
|
+
session.status.padEnd(12) +
|
|
150
|
+
"saved"
|
|
151
|
+
);
|
|
152
|
+
});
|
|
153
|
+
|
|
154
|
+
// Show running tasks
|
|
155
|
+
runningTasks.forEach((task) => {
|
|
156
|
+
console.log(
|
|
157
|
+
task.taskId.padEnd(25) +
|
|
158
|
+
task.agentName.padEnd(15) +
|
|
159
|
+
task.status.padEnd(12) +
|
|
160
|
+
"running"
|
|
161
|
+
);
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
console.log("─".repeat(80));
|
|
165
|
+
|
|
166
|
+
// Interactive selection for both types
|
|
167
|
+
const allIds = [
|
|
168
|
+
...savedSessions.map((s) => s.sessionId),
|
|
169
|
+
...runningTasks.map((t) => t.taskId),
|
|
170
|
+
];
|
|
171
|
+
|
|
172
|
+
const selectedId = await this.chatService?.getInput(
|
|
173
|
+
"Select a session/task to attach to (or press Enter to skip): ",
|
|
174
|
+
allIds
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
if (
|
|
178
|
+
selectedId &&
|
|
179
|
+
selectedId.trim() &&
|
|
180
|
+
allIds.includes(selectedId.trim())
|
|
181
|
+
) {
|
|
182
|
+
await this.handleAttachById(selectedId.trim());
|
|
183
|
+
}
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const taskId = args[0];
|
|
188
|
+
await this.handleAttachById(taskId);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Display single task details
|
|
193
|
+
*/
|
|
194
|
+
private displaySingleTask(task: TaskInfo): void {
|
|
195
|
+
console.log(`\n📋 Task Details: ${task.taskId}`);
|
|
196
|
+
console.log("─".repeat(50));
|
|
197
|
+
console.log(`Agent: ${task.agentName}`);
|
|
198
|
+
console.log(`Status: ${task.status}`);
|
|
199
|
+
console.log(`Initial Input: ${task.initialInput}`);
|
|
200
|
+
console.log(`Start Time: ${new Date(task.startTime).toLocaleString()}`);
|
|
201
|
+
if (task.endTime) {
|
|
202
|
+
console.log(`End Time: ${new Date(task.endTime).toLocaleString()}`);
|
|
203
|
+
console.log(
|
|
204
|
+
`Duration: ${Math.round((task.endTime - task.startTime) / 1000)}s`
|
|
205
|
+
);
|
|
206
|
+
} else {
|
|
207
|
+
console.log(
|
|
208
|
+
`Running for: ${Math.round((Date.now() - task.startTime) / 1000)}s`
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
console.log(`Total Cost: $${task.totalCost.toFixed(3)}`);
|
|
212
|
+
console.log("─".repeat(50));
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
async handleAgentsCommand(args: string[]): Promise<void> {
|
|
216
|
+
try {
|
|
217
|
+
const allAgents = agents();
|
|
218
|
+
|
|
219
|
+
if (allAgents && Object.keys(allAgents).length > 0) {
|
|
220
|
+
const agentNames = Object.keys(allAgents);
|
|
221
|
+
|
|
222
|
+
console.log("\nAvailable agents:");
|
|
223
|
+
Object.entries(allAgents).forEach(([name, agent]: [string, any]) => {
|
|
224
|
+
console.log(` - ${name}: ${agent.description || "No description"}`);
|
|
225
|
+
});
|
|
226
|
+
console.log("─".repeat(80), "\n");
|
|
227
|
+
|
|
228
|
+
// Interactive selection with autocomplete
|
|
229
|
+
const selectedAgent = await this.chatService?.getInput(
|
|
230
|
+
"Select an agent to start: ",
|
|
231
|
+
agentNames // Pass agent names as autocomplete options
|
|
232
|
+
);
|
|
233
|
+
|
|
234
|
+
if (
|
|
235
|
+
selectedAgent &&
|
|
236
|
+
selectedAgent.trim() &&
|
|
237
|
+
agentNames.includes(selectedAgent.trim())
|
|
238
|
+
) {
|
|
239
|
+
// Start the selected agent
|
|
240
|
+
await this.handleAgentCommand([selectedAgent.trim()]);
|
|
241
|
+
} else if (selectedAgent && selectedAgent.trim()) {
|
|
242
|
+
console.log(`Agent "${selectedAgent.trim()}" not found.`);
|
|
243
|
+
}
|
|
244
|
+
} else {
|
|
245
|
+
console.log("No agents available.");
|
|
246
|
+
}
|
|
247
|
+
} catch (error) {
|
|
248
|
+
console.error("Error listing agents:", error);
|
|
249
|
+
console.log("Could not load agents list.");
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
async logSessionTable() {
|
|
254
|
+
// Display unified table
|
|
255
|
+
const runningTasks = Array.from(this.taskRegistry.values());
|
|
256
|
+
const savedSessions = await this.listAvailableSessions();
|
|
257
|
+
console.log("\n📋 Sessions & Tasks:");
|
|
258
|
+
|
|
259
|
+
const data = [];
|
|
260
|
+
// Display saved sessions first (historical)
|
|
261
|
+
savedSessions.forEach((session) => {
|
|
262
|
+
const lastUpdated = new Date(session.lastUpdated).toLocaleString();
|
|
263
|
+
const inputPreview =
|
|
264
|
+
session.initialInput && session.initialInput.length > 30
|
|
265
|
+
? session.initialInput.substring(0, 27) + "..."
|
|
266
|
+
: session.initialInput || "[No input]";
|
|
267
|
+
const cost = session.totalCost
|
|
268
|
+
? `$${session.totalCost.toFixed(3)}`
|
|
269
|
+
: "$0.000";
|
|
270
|
+
|
|
271
|
+
data.push({
|
|
272
|
+
ID: session.sessionId,
|
|
273
|
+
Agent: session.agentName,
|
|
274
|
+
Status: session.status,
|
|
275
|
+
Type: "saved",
|
|
276
|
+
Time: lastUpdated,
|
|
277
|
+
Cost: cost,
|
|
278
|
+
"Initial Input": inputPreview,
|
|
279
|
+
});
|
|
280
|
+
});
|
|
281
|
+
|
|
282
|
+
// Display running tasks at the bottom
|
|
283
|
+
runningTasks.forEach((task) => {
|
|
284
|
+
const elapsed = task.endTime
|
|
285
|
+
? `${Math.round((task.endTime - task.startTime) / 1000)}s`
|
|
286
|
+
: `${Math.round((Date.now() - task.startTime) / 1000)}s`;
|
|
287
|
+
const cost = `$${task.totalCost.toFixed(3)}`;
|
|
288
|
+
const inputPreview =
|
|
289
|
+
task.initialInput.length > 30
|
|
290
|
+
? task.initialInput.substring(0, 27) + "..."
|
|
291
|
+
: task.initialInput;
|
|
292
|
+
data.push({
|
|
293
|
+
ID: task.taskId,
|
|
294
|
+
Agent: task.agentName,
|
|
295
|
+
Status: task.status,
|
|
296
|
+
Type: "running",
|
|
297
|
+
Time: elapsed,
|
|
298
|
+
Cost: cost,
|
|
299
|
+
"Initial Input": inputPreview,
|
|
300
|
+
});
|
|
301
|
+
});
|
|
302
|
+
|
|
303
|
+
console.table(data);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
async handleSessionsCommand(args: string[]): Promise<void> {
|
|
307
|
+
try {
|
|
308
|
+
// Get both running tasks and saved sessions
|
|
309
|
+
const runningTasks = Array.from(this.taskRegistry.values());
|
|
310
|
+
const savedSessions = await this.listAvailableSessions();
|
|
311
|
+
|
|
312
|
+
if (runningTasks.length === 0 && savedSessions.length === 0) {
|
|
313
|
+
console.log("No active tasks or saved sessions found.");
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
await this.logSessionTable();
|
|
318
|
+
|
|
319
|
+
// Interactive selection for both types
|
|
320
|
+
const allIds = [
|
|
321
|
+
...savedSessions.map((s) => s.sessionId),
|
|
322
|
+
...runningTasks.map((t) => t.taskId),
|
|
323
|
+
];
|
|
324
|
+
|
|
325
|
+
if (allIds.length > 0) {
|
|
326
|
+
const selectedId = await this.chatService?.getInput(
|
|
327
|
+
"Select a session/task to attach to (or press Enter to skip): ",
|
|
328
|
+
allIds
|
|
329
|
+
);
|
|
330
|
+
|
|
331
|
+
if (
|
|
332
|
+
selectedId &&
|
|
333
|
+
selectedId.trim() &&
|
|
334
|
+
allIds.includes(selectedId.trim())
|
|
335
|
+
) {
|
|
336
|
+
await this.handleAttachById(selectedId.trim());
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
} catch (error) {
|
|
340
|
+
console.error("Error listing sessions and tasks:", error);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Handle attachment by ID - works for both running tasks and saved sessions
|
|
346
|
+
*/
|
|
347
|
+
private async handleAttachById(id: string): Promise<void> {
|
|
348
|
+
// Check if it's a running task first
|
|
349
|
+
if (this.taskRegistry.has(id)) {
|
|
350
|
+
const taskInfo = this.taskRegistry.get(id);
|
|
351
|
+
if (taskInfo) {
|
|
352
|
+
// Switch to agent mode and set the selected agent
|
|
353
|
+
const context = this.chatService?.getContext();
|
|
354
|
+
const allAgents = agents();
|
|
355
|
+
const selectedAgent = allAgents[taskInfo.agentName];
|
|
356
|
+
|
|
357
|
+
if (context && selectedAgent) {
|
|
358
|
+
context.selectedAgent = selectedAgent;
|
|
359
|
+
context.agentMode = true;
|
|
360
|
+
context.currentAgent = taskInfo.agentName;
|
|
361
|
+
console.log(`🔄 Switched to agent mode with ${taskInfo.agentName}`);
|
|
362
|
+
console.log(`📋 Attached to running task: ${id}`);
|
|
363
|
+
console.log(`Task: ${taskInfo.initialInput}`);
|
|
364
|
+
console.log(`Status: ${taskInfo.status}`);
|
|
365
|
+
return;
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
console.log(Marked.parse(`**Attached to running task: ${id}**`));
|
|
369
|
+
return;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Check if it's a saved session
|
|
373
|
+
try {
|
|
374
|
+
const sessionPath = path.join(this.sessionsDir, `${id}.json`);
|
|
375
|
+
if (fs.existsSync(sessionPath)) {
|
|
376
|
+
console.log(Marked.parse(`**Resuming saved session: ${id}**`));
|
|
377
|
+
// Read session to get agent information
|
|
378
|
+
const content = fs.readFileSync(sessionPath, "utf-8");
|
|
379
|
+
const session: ChatSession = JSON.parse(content);
|
|
380
|
+
|
|
381
|
+
// Switch to agent mode and set the selected agent
|
|
382
|
+
const context = this.chatService?.getContext();
|
|
383
|
+
const allAgents = agents();
|
|
384
|
+
const selectedAgent = allAgents[session.agentName];
|
|
385
|
+
|
|
386
|
+
if (context && selectedAgent) {
|
|
387
|
+
context.selectedAgent = selectedAgent;
|
|
388
|
+
context.agentMode = true;
|
|
389
|
+
console.log(`🔄 Switched to agent mode with ${session.agentName}`);
|
|
390
|
+
console.log(`📋 Resuming saved session: ${id}`);
|
|
391
|
+
console.log(`Original task: ${session.initialInput}`);
|
|
392
|
+
console.log(`Status: ${session.status}`);
|
|
393
|
+
|
|
394
|
+
const addedContext = await this.chatService.getInput(
|
|
395
|
+
"Add any additional context for resuming this session (or press Enter to skip): "
|
|
396
|
+
);
|
|
397
|
+
await this.resumeSession(id);
|
|
398
|
+
return;
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
} catch (error) {
|
|
402
|
+
// Session file doesn't exist or error reading it
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
console.log(Marked.parse(`**Session/Task ${id} not found.**`));
|
|
406
|
+
}
|
|
407
|
+
|
|
408
|
+
/**
|
|
409
|
+
* List available session files
|
|
410
|
+
*/
|
|
411
|
+
public async listAvailableSessions(): Promise<ChatSession[]> {
|
|
412
|
+
try {
|
|
413
|
+
const files = fs.readdirSync(this.sessionsDir);
|
|
414
|
+
const sessionFiles = files.filter((f) => f.endsWith(".json"));
|
|
415
|
+
|
|
416
|
+
const sessions: ChatSession[] = [];
|
|
417
|
+
const thresholdTime = 15 * 60 * 1000; // 15 minutes
|
|
418
|
+
for (const file of sessionFiles) {
|
|
419
|
+
const filePath = path.join(this.sessionsDir, file);
|
|
420
|
+
try {
|
|
421
|
+
const content = fs.readFileSync(filePath, "utf8");
|
|
422
|
+
const session = JSON.parse(content) as ChatSession;
|
|
423
|
+
|
|
424
|
+
// Cleanup check: mark stale running sessions as failed
|
|
425
|
+
const isStale = Date.now() - session.lastUpdated > thresholdTime;
|
|
426
|
+
const isRunningAndNotInRegistry =
|
|
427
|
+
session.status === "running" &&
|
|
428
|
+
!this.taskRegistry.has(session.sessionId);
|
|
429
|
+
|
|
430
|
+
if (isRunningAndNotInRegistry && isStale) {
|
|
431
|
+
console.log(
|
|
432
|
+
`🧹 Marking stale session ${
|
|
433
|
+
session.sessionId
|
|
434
|
+
} as failed (last updated: ${new Date(
|
|
435
|
+
session.lastUpdated
|
|
436
|
+
).toLocaleString()})`
|
|
437
|
+
);
|
|
438
|
+
session.status = "failed";
|
|
439
|
+
session.lastUpdated = Date.now();
|
|
440
|
+
// Update the session file with failed status
|
|
441
|
+
fs.writeFileSync(filePath, JSON.stringify(session, null, 2));
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
sessions.push(session);
|
|
445
|
+
} catch (error) {
|
|
446
|
+
console.warn(
|
|
447
|
+
`Failed to read session file ${file}:`,
|
|
448
|
+
(error as Error).message
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
return sessions.sort((a, b) => b.lastUpdated - a.lastUpdated);
|
|
454
|
+
} catch (error) {
|
|
455
|
+
console.warn("Failed to list sessions:", (error as Error).message);
|
|
456
|
+
return [];
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
/**
|
|
461
|
+
* List both active tasks and saved sessions for CLI usage
|
|
462
|
+
*/
|
|
463
|
+
public async listSessionsAndTasks(): Promise<{
|
|
464
|
+
runningTasks: TaskInfo[];
|
|
465
|
+
savedSessions: ChatSession[];
|
|
466
|
+
}> {
|
|
467
|
+
const runningTasks = Array.from(this.taskRegistry.values());
|
|
468
|
+
const savedSessions = await this.listAvailableSessions();
|
|
469
|
+
return {
|
|
470
|
+
runningTasks,
|
|
471
|
+
savedSessions,
|
|
472
|
+
};
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Get the task registry for CLI access
|
|
477
|
+
*/
|
|
478
|
+
public getTaskRegistry(): Map<string, TaskInfo> {
|
|
479
|
+
return this.taskRegistry;
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
/**
|
|
483
|
+
* Resume a session from saved state
|
|
484
|
+
*/
|
|
485
|
+
private async resumeSession(
|
|
486
|
+
sessionId: string,
|
|
487
|
+
resumeReason?: string
|
|
488
|
+
): Promise<void> {
|
|
489
|
+
try {
|
|
490
|
+
const sessionPath = path.join(this.sessionsDir, `${sessionId}.json`);
|
|
491
|
+
const content = fs.readFileSync(sessionPath, "utf-8");
|
|
492
|
+
const session: ChatSession = JSON.parse(content);
|
|
493
|
+
const lastThread = session.threads[session.threads.length - 1];
|
|
494
|
+
console.log(`\n🔄 Resuming session: ${sessionId}`);
|
|
495
|
+
console.log(`Agent: ${session.agentName}`);
|
|
496
|
+
console.log(`Original task: ${session.initialInput}`);
|
|
497
|
+
console.log(`Status: ${session.status}`);
|
|
498
|
+
|
|
499
|
+
const reason = resumeReason
|
|
500
|
+
? `Reason for resuming: ${resumeReason}`
|
|
501
|
+
: "";
|
|
502
|
+
|
|
503
|
+
// Create resume prompt
|
|
504
|
+
const resumePrompt = `You are resuming a previously started task. Here's the context:
|
|
505
|
+
ORIGINAL REQUEST:
|
|
506
|
+
${session.initialInput}
|
|
507
|
+
|
|
508
|
+
LAST Progress State:
|
|
509
|
+
${JSON.stringify(lastThread)}
|
|
510
|
+
|
|
511
|
+
Please continue from where you left off and complete the original request.
|
|
512
|
+
${reason}
|
|
513
|
+
|
|
514
|
+
`;
|
|
515
|
+
|
|
516
|
+
console.log("🚀 Session resumption would restart the agent here...");
|
|
517
|
+
const context = this.chatService?.getContext() || {};
|
|
518
|
+
const allAgents = agents();
|
|
519
|
+
const selectedAgent =
|
|
520
|
+
allAgents[session.agentName] || allAgents[context.currentAgent];
|
|
521
|
+
|
|
522
|
+
if (!selectedAgent) {
|
|
523
|
+
console.error(`Agent ${session.agentName} not found.`);
|
|
524
|
+
return;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// Start agent with Knowhow task context if available
|
|
528
|
+
const { agent, taskId } = await this.setupAgent({
|
|
529
|
+
agentName: selectedAgent.name,
|
|
530
|
+
input: resumePrompt,
|
|
531
|
+
messageId: session.knowhowMessageId,
|
|
532
|
+
existingKnowhowTaskId: session.knowhowTaskId,
|
|
533
|
+
chatHistory: [],
|
|
534
|
+
run: true,
|
|
535
|
+
});
|
|
536
|
+
await this.attachedAgentChatLoop(taskId, agent);
|
|
537
|
+
} catch (error) {
|
|
538
|
+
console.error(
|
|
539
|
+
`Failed to resume session ${sessionId}:`,
|
|
540
|
+
(error as Error).message
|
|
541
|
+
);
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
async handleInput(input: string, context: ChatContext): Promise<boolean> {
|
|
546
|
+
// If in agent mode, start agent with the input as initial task (like original chat.ts)
|
|
547
|
+
if (context.agentMode && context.selectedAgent) {
|
|
548
|
+
const result = await this.startAgent(
|
|
549
|
+
context.selectedAgent,
|
|
550
|
+
input,
|
|
551
|
+
context.chatHistory || []
|
|
552
|
+
);
|
|
553
|
+
return result;
|
|
554
|
+
}
|
|
555
|
+
return false;
|
|
556
|
+
}
|
|
557
|
+
|
|
558
|
+
/**
|
|
559
|
+
* Setup and run an agent directly with CLI options (for CLI usage)
|
|
560
|
+
*/
|
|
561
|
+
public async setupAgent(options: {
|
|
562
|
+
agentName: string;
|
|
563
|
+
input: string;
|
|
564
|
+
messageId?: string;
|
|
565
|
+
existingKnowhowTaskId?: string;
|
|
566
|
+
provider?: string;
|
|
567
|
+
model?: string;
|
|
568
|
+
maxTimeLimit?: number; // in minutes
|
|
569
|
+
maxSpendLimit?: number; // in dollars
|
|
570
|
+
chatHistory?: ChatInteraction[];
|
|
571
|
+
run?: boolean; // whether to run immediately
|
|
572
|
+
}) {
|
|
573
|
+
const allAgents = agents();
|
|
574
|
+
|
|
575
|
+
if (!allAgents[options.agentName]) {
|
|
576
|
+
throw new Error(
|
|
577
|
+
`Agent "${
|
|
578
|
+
options.agentName
|
|
579
|
+
}" not found. Available agents: ${Object.keys(allAgents).join(", ")}`
|
|
580
|
+
);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
const { input, chatHistory = [], agentName } = options;
|
|
584
|
+
const agent = allAgents[options.agentName] as BaseAgent;
|
|
585
|
+
|
|
586
|
+
let done = false;
|
|
587
|
+
let output = "Done";
|
|
588
|
+
const taskId = this.generateTaskId(input);
|
|
589
|
+
let knowhowTaskId: string | undefined;
|
|
590
|
+
|
|
591
|
+
try {
|
|
592
|
+
// Create task info object
|
|
593
|
+
let taskInfo: TaskInfo = {
|
|
594
|
+
taskId,
|
|
595
|
+
knowhowMessageId: options.messageId,
|
|
596
|
+
knowhowTaskId: options.existingKnowhowTaskId, // Use existing or will be set after creating chat task
|
|
597
|
+
agentName,
|
|
598
|
+
agent,
|
|
599
|
+
initialInput: input,
|
|
600
|
+
status: "running",
|
|
601
|
+
startTime: Date.now(),
|
|
602
|
+
totalCost: 0,
|
|
603
|
+
};
|
|
604
|
+
|
|
605
|
+
// Add to task registry
|
|
606
|
+
this.taskRegistry.set(taskId, taskInfo);
|
|
607
|
+
|
|
608
|
+
// Save initial session
|
|
609
|
+
this.saveSession(taskId, taskInfo, []);
|
|
610
|
+
|
|
611
|
+
// Create Knowhow chat task if messageId provided
|
|
612
|
+
const baseUrl = process.env.KNOWHOW_API_URL;
|
|
613
|
+
console.log(
|
|
614
|
+
`Base URL for Knowhow API: ${baseUrl}, Message ID: ${options.messageId}`
|
|
615
|
+
);
|
|
616
|
+
const client = new KnowhowSimpleClient(baseUrl);
|
|
617
|
+
if (options.messageId && !options.existingKnowhowTaskId && baseUrl) {
|
|
618
|
+
try {
|
|
619
|
+
const response = await client.createChatTask({
|
|
620
|
+
messageId: options.messageId,
|
|
621
|
+
prompt: input,
|
|
622
|
+
});
|
|
623
|
+
knowhowTaskId = response.data.id;
|
|
624
|
+
console.log(`✅ Created Knowhow chat task: ${knowhowTaskId}`);
|
|
625
|
+
|
|
626
|
+
// Update TaskInfo with the created knowhowTaskId
|
|
627
|
+
taskInfo.knowhowTaskId = knowhowTaskId;
|
|
628
|
+
this.taskRegistry.set(taskId, taskInfo);
|
|
629
|
+
} catch (error) {
|
|
630
|
+
console.error(`❌ Failed to create Knowhow chat task:`, error);
|
|
631
|
+
// Continue execution even if task creation fails
|
|
632
|
+
}
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
// Set up session update listener
|
|
636
|
+
agent.agentEvents.on("threadUpdate", async (threadState) => {
|
|
637
|
+
// Update task cost from agent's current total cost
|
|
638
|
+
taskInfo.totalCost = agent.getTotalCostUsd();
|
|
639
|
+
this.updateSession(taskId, threadState);
|
|
640
|
+
|
|
641
|
+
// Update Knowhow chat task if created
|
|
642
|
+
if (knowhowTaskId && options.messageId && baseUrl) {
|
|
643
|
+
await client
|
|
644
|
+
.updateChatTask(knowhowTaskId, {
|
|
645
|
+
threads: agent.getThreads(),
|
|
646
|
+
totalCostUsd: agent.getTotalCostUsd(),
|
|
647
|
+
inProgress: true,
|
|
648
|
+
})
|
|
649
|
+
.catch((error) => {
|
|
650
|
+
console.error(`❌ Failed to update Knowhow chat task:`, error);
|
|
651
|
+
});
|
|
652
|
+
console.log(`✅ Updated Knowhow chat task: ${knowhowTaskId}`);
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
|
|
656
|
+
console.log(
|
|
657
|
+
Marked.parse(`**Starting ${agent.name} with task ID: ${taskId}...**`)
|
|
658
|
+
);
|
|
659
|
+
console.log(Marked.parse(`**Task:** ${input}`));
|
|
660
|
+
|
|
661
|
+
// Initialize new task
|
|
662
|
+
await agent.newTask();
|
|
663
|
+
|
|
664
|
+
// Get context for plugins
|
|
665
|
+
const context = this.chatService?.getContext();
|
|
666
|
+
const plugins = context?.plugins || [];
|
|
667
|
+
|
|
668
|
+
// Format the prompt with plugins and chat history
|
|
669
|
+
const formattedPrompt = await formatChatInput(
|
|
670
|
+
input,
|
|
671
|
+
plugins,
|
|
672
|
+
chatHistory
|
|
673
|
+
);
|
|
674
|
+
|
|
675
|
+
// Set up message processors like in original startAgent
|
|
676
|
+
|
|
677
|
+
agent.messageProcessor.setProcessors("pre_call", [
|
|
678
|
+
new ToolResponseCache(agent.tools).createProcessor(),
|
|
679
|
+
new TokenCompressor(agent.tools).createProcessor((msg) =>
|
|
680
|
+
Boolean(msg.role === "tool" && msg.tool_call_id)
|
|
681
|
+
),
|
|
682
|
+
new CustomVariables(agent.tools).createProcessor(),
|
|
683
|
+
]);
|
|
684
|
+
|
|
685
|
+
agent.messageProcessor.setProcessors("post_call", [
|
|
686
|
+
new XmlToolCallProcessor().createProcessor(),
|
|
687
|
+
new HarmonyToolProcessor().createProcessor(),
|
|
688
|
+
]);
|
|
689
|
+
|
|
690
|
+
// Set up event listeners
|
|
691
|
+
if (!agent.agentEvents.listenerCount(agent.eventTypes.toolUsed)) {
|
|
692
|
+
agent.agentEvents.on(agent.eventTypes.toolUsed, (responseMsg) => {
|
|
693
|
+
console.log(` 🔨 Tool used: ${JSON.stringify(responseMsg, null, 2)}`);
|
|
694
|
+
});
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
const taskCompleted = new Promise<string>((resolve) => {
|
|
698
|
+
agent.agentEvents.once(agent.eventTypes.done, async (doneMsg) => {
|
|
699
|
+
console.log("Agent has finished.");
|
|
700
|
+
done = true;
|
|
701
|
+
output = doneMsg || "No response from the AI";
|
|
702
|
+
// Update task info
|
|
703
|
+
taskInfo = this.taskRegistry.get(taskId);
|
|
704
|
+
if (taskInfo) {
|
|
705
|
+
taskInfo.status = "completed";
|
|
706
|
+
// Update final cost from agent
|
|
707
|
+
taskInfo.totalCost = agent.getTotalCostUsd();
|
|
708
|
+
// Update session with final state
|
|
709
|
+
this.updateSession(taskId, agent.getThreads());
|
|
710
|
+
taskInfo.endTime = Date.now();
|
|
711
|
+
|
|
712
|
+
// Final update to Knowhow chat task
|
|
713
|
+
if (knowhowTaskId && options.messageId) {
|
|
714
|
+
console.log(
|
|
715
|
+
`Updating Knowhow chat task on completion..., ${knowhowTaskId}, ${options.messageId}`
|
|
716
|
+
);
|
|
717
|
+
await client
|
|
718
|
+
.updateChatTask(knowhowTaskId, {
|
|
719
|
+
inProgress: false,
|
|
720
|
+
threads: agent.getThreads(),
|
|
721
|
+
totalCostUsd: agent.getTotalCostUsd(),
|
|
722
|
+
result: output,
|
|
723
|
+
})
|
|
724
|
+
.catch((error) => {
|
|
725
|
+
console.error(
|
|
726
|
+
`❌ Failed to update Knowhow chat task on completion:`,
|
|
727
|
+
error
|
|
728
|
+
);
|
|
729
|
+
});
|
|
730
|
+
console.log(`✅ Completed Knowhow chat task: ${knowhowTaskId}`);
|
|
731
|
+
}
|
|
732
|
+
}
|
|
733
|
+
console.log(Marked.parse(output));
|
|
734
|
+
resolve(doneMsg);
|
|
735
|
+
});
|
|
736
|
+
});
|
|
737
|
+
|
|
738
|
+
// Set up time limit if provided
|
|
739
|
+
if (options.maxTimeLimit) {
|
|
740
|
+
agent.setMaxRunTime(options.maxTimeLimit * 60 * 1000); // Convert minutes to milliseconds
|
|
741
|
+
}
|
|
742
|
+
|
|
743
|
+
console.log(`🤖 Starting agent: ${options.agentName}`);
|
|
744
|
+
console.log(`📝 Task: ${options.input}`);
|
|
745
|
+
|
|
746
|
+
if (options.maxTimeLimit) {
|
|
747
|
+
console.log(`⏱️ Time limit: ${options.maxTimeLimit} minutes`);
|
|
748
|
+
}
|
|
749
|
+
if (options.maxSpendLimit) {
|
|
750
|
+
console.log(`💰 Spend limit: $${options.maxSpendLimit}`);
|
|
751
|
+
}
|
|
752
|
+
console.log("─".repeat(50));
|
|
753
|
+
|
|
754
|
+
if (options.run) {
|
|
755
|
+
agent.call(formattedPrompt);
|
|
756
|
+
}
|
|
757
|
+
|
|
758
|
+
return { agent, taskId, formattedPrompt, taskCompleted };
|
|
759
|
+
} catch (error) {
|
|
760
|
+
console.error("Agent setup failed:", error);
|
|
761
|
+
this.taskRegistry.delete(taskId);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
/**
|
|
766
|
+
* Get list of active agent tasks
|
|
767
|
+
*/
|
|
768
|
+
getActiveTasks(): { taskId: string; agent: TaskInfo }[] {
|
|
769
|
+
return Array.from(this.taskRegistry.entries()).map(
|
|
770
|
+
([taskId, taskInfo]) => ({
|
|
771
|
+
taskId,
|
|
772
|
+
agent: taskInfo,
|
|
773
|
+
})
|
|
774
|
+
);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
/**
|
|
778
|
+
* Attach to an existing agent task
|
|
779
|
+
*/
|
|
780
|
+
attachToTask(taskId: string): boolean {
|
|
781
|
+
if (this.taskRegistry.has(taskId)) {
|
|
782
|
+
console.log(Marked.parse(`**Attached to agent task: ${taskId}**`));
|
|
783
|
+
return true;
|
|
784
|
+
}
|
|
785
|
+
console.log(
|
|
786
|
+
Marked.parse(`**Task ${taskId} not found or already completed.**`)
|
|
787
|
+
);
|
|
788
|
+
return false;
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
/**
|
|
792
|
+
* Generate human-readable task ID from initial input
|
|
793
|
+
*/
|
|
794
|
+
private generateTaskId(initialInput: string): string {
|
|
795
|
+
const words = initialInput
|
|
796
|
+
.toLowerCase()
|
|
797
|
+
.replace(/[^\w\s]/g, "")
|
|
798
|
+
.split(/\s+/)
|
|
799
|
+
.filter((word) => word.length > 2)
|
|
800
|
+
.slice(0, 3);
|
|
801
|
+
|
|
802
|
+
const wordPart = words.join("-") || "task";
|
|
803
|
+
const timestamp = Date.now().toString().slice(-6);
|
|
804
|
+
return `${wordPart}-${timestamp}`;
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
/**
|
|
808
|
+
* Save session to file
|
|
809
|
+
*/
|
|
810
|
+
private saveSession(
|
|
811
|
+
taskId: string,
|
|
812
|
+
taskInfo: TaskInfo,
|
|
813
|
+
threads: any[]
|
|
814
|
+
): void {
|
|
815
|
+
try {
|
|
816
|
+
const sessionPath = path.join(this.sessionsDir, `${taskId}.json`);
|
|
817
|
+
const session: ChatSession = {
|
|
818
|
+
sessionId: taskId,
|
|
819
|
+
knowhowMessageId: taskInfo.knowhowMessageId,
|
|
820
|
+
knowhowTaskId: taskInfo.knowhowTaskId,
|
|
821
|
+
taskId,
|
|
822
|
+
agentName: taskInfo.agentName,
|
|
823
|
+
initialInput: taskInfo.initialInput,
|
|
824
|
+
status: taskInfo.status,
|
|
825
|
+
startTime: taskInfo.startTime,
|
|
826
|
+
endTime: taskInfo.endTime,
|
|
827
|
+
totalCost: taskInfo.totalCost,
|
|
828
|
+
threads,
|
|
829
|
+
currentThread: 0,
|
|
830
|
+
lastUpdated: Date.now(),
|
|
831
|
+
};
|
|
832
|
+
|
|
833
|
+
fs.writeFileSync(sessionPath, JSON.stringify(session, null, 2));
|
|
834
|
+
} catch (error) {
|
|
835
|
+
console.error(`Error saving session ${taskId}:`, error);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
/**
|
|
840
|
+
* Update existing session with new thread state
|
|
841
|
+
*/
|
|
842
|
+
private updateSession(taskId: string, threads: any[]): void {
|
|
843
|
+
try {
|
|
844
|
+
const sessionPath = path.join(this.sessionsDir, `${taskId}.json`);
|
|
845
|
+
if (fs.existsSync(sessionPath)) {
|
|
846
|
+
const session: ChatSession = JSON.parse(
|
|
847
|
+
fs.readFileSync(sessionPath, "utf8")
|
|
848
|
+
);
|
|
849
|
+
const taskInfo = this.taskRegistry.get(taskId);
|
|
850
|
+
|
|
851
|
+
// Update session with current state
|
|
852
|
+
session.threads = threads;
|
|
853
|
+
session.lastUpdated = Date.now();
|
|
854
|
+
if (taskInfo) {
|
|
855
|
+
session.status = taskInfo.status;
|
|
856
|
+
session.endTime = taskInfo.endTime;
|
|
857
|
+
session.totalCost = taskInfo.totalCost;
|
|
858
|
+
|
|
859
|
+
// Update Knowhow task fields if they exist in TaskInfo
|
|
860
|
+
session.knowhowMessageId = taskInfo.knowhowMessageId;
|
|
861
|
+
session.knowhowTaskId = taskInfo.knowhowTaskId;
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
fs.writeFileSync(sessionPath, JSON.stringify(session, null, 2));
|
|
865
|
+
}
|
|
866
|
+
} catch (error) {
|
|
867
|
+
console.error(`Error updating session ${taskId}:`, error);
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
|
|
871
|
+
/**
|
|
872
|
+
* Start an agent with an initial task (simplified version for now)
|
|
873
|
+
*/
|
|
874
|
+
private async startAgent(
|
|
875
|
+
selectedAgent: BaseAgent,
|
|
876
|
+
initialInput: string,
|
|
877
|
+
chatHistory: ChatInteraction[] = []
|
|
878
|
+
): Promise<boolean> {
|
|
879
|
+
try {
|
|
880
|
+
const { agent, taskId } = await this.setupAgent({
|
|
881
|
+
agentName: selectedAgent.name,
|
|
882
|
+
input: initialInput,
|
|
883
|
+
chatHistory,
|
|
884
|
+
run: true,
|
|
885
|
+
});
|
|
886
|
+
return await this.attachedAgentChatLoop(taskId, agent);
|
|
887
|
+
} catch (error) {
|
|
888
|
+
console.error("Error starting agent:", error);
|
|
889
|
+
return false;
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
async attachedAgentChatLoop(taskId: string, agent: BaseAgent) {
|
|
894
|
+
try {
|
|
895
|
+
let done = false;
|
|
896
|
+
let output = "Done";
|
|
897
|
+
|
|
898
|
+
// Define available commands
|
|
899
|
+
const commands = ["pause", "unpause", "kill", "detach"];
|
|
900
|
+
const history: string[] = [];
|
|
901
|
+
|
|
902
|
+
let input =
|
|
903
|
+
(await this.chatService?.getInput(
|
|
904
|
+
`Enter command or message for ${agent.name}: `,
|
|
905
|
+
commands
|
|
906
|
+
)) || "";
|
|
907
|
+
|
|
908
|
+
history.push(input);
|
|
909
|
+
|
|
910
|
+
let finished = false;
|
|
911
|
+
const donePromise = new Promise<string>((resolve) => {
|
|
912
|
+
agent.agentEvents.once(agent.eventTypes.done, (doneMsg) => {
|
|
913
|
+
console.log("Agent has completed the task.");
|
|
914
|
+
finished = true;
|
|
915
|
+
resolve("done");
|
|
916
|
+
});
|
|
917
|
+
});
|
|
918
|
+
|
|
919
|
+
while (!done) {
|
|
920
|
+
switch (input) {
|
|
921
|
+
case "":
|
|
922
|
+
if (finished) {
|
|
923
|
+
output = "Agent has completed the task.";
|
|
924
|
+
done = true;
|
|
925
|
+
}
|
|
926
|
+
break;
|
|
927
|
+
case "done":
|
|
928
|
+
output = "Exited agent interaction.";
|
|
929
|
+
done = true;
|
|
930
|
+
break;
|
|
931
|
+
case "pause":
|
|
932
|
+
await agent.pause();
|
|
933
|
+
console.log("Agent paused.");
|
|
934
|
+
break;
|
|
935
|
+
case "unpause":
|
|
936
|
+
await agent.unpause();
|
|
937
|
+
console.log("Agent unpaused.");
|
|
938
|
+
break;
|
|
939
|
+
case "kill":
|
|
940
|
+
await agent.kill();
|
|
941
|
+
console.log("Agent terminated.");
|
|
942
|
+
done = true;
|
|
943
|
+
break;
|
|
944
|
+
case "detach":
|
|
945
|
+
console.log("Detached from agent");
|
|
946
|
+
return true;
|
|
947
|
+
default:
|
|
948
|
+
agent.addPendingUserMessage({
|
|
949
|
+
role: "user",
|
|
950
|
+
content: input,
|
|
951
|
+
});
|
|
952
|
+
}
|
|
953
|
+
|
|
954
|
+
if (!done) {
|
|
955
|
+
input = await this.chatService?.getInput(
|
|
956
|
+
`Enter command or message for ${agent.name}: `,
|
|
957
|
+
commands
|
|
958
|
+
);
|
|
959
|
+
}
|
|
960
|
+
}
|
|
961
|
+
|
|
962
|
+
// Update final task status and save session
|
|
963
|
+
const finalTaskInfo = this.taskRegistry.get(taskId);
|
|
964
|
+
if (finalTaskInfo) {
|
|
965
|
+
if (finalTaskInfo.status === "running") {
|
|
966
|
+
finalTaskInfo.status = "completed";
|
|
967
|
+
// Ensure final cost is captured
|
|
968
|
+
finalTaskInfo.totalCost = agent.getTotalCostUsd();
|
|
969
|
+
finalTaskInfo.endTime = Date.now();
|
|
970
|
+
}
|
|
971
|
+
}
|
|
972
|
+
|
|
973
|
+
return true;
|
|
974
|
+
} catch (error) {
|
|
975
|
+
console.error("Agent execution failed:", error);
|
|
976
|
+
this.taskRegistry.delete(taskId);
|
|
977
|
+
return false;
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
}
|