@tyvm/knowhow 0.0.33 → 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/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/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,533 @@
|
|
|
1
|
+
import { Message, ToolCall } from "../clients/types";
|
|
2
|
+
import { MessageProcessorFunction } from "../services/MessageProcessor";
|
|
3
|
+
|
|
4
|
+
export class XmlToolCallProcessor {
|
|
5
|
+
private static instance: XmlToolCallProcessor;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Get singleton instance
|
|
9
|
+
*/
|
|
10
|
+
static getInstance(): XmlToolCallProcessor {
|
|
11
|
+
if (!XmlToolCallProcessor.instance) {
|
|
12
|
+
XmlToolCallProcessor.instance = new XmlToolCallProcessor();
|
|
13
|
+
}
|
|
14
|
+
return XmlToolCallProcessor.instance;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Detects XML tool call patterns in text content
|
|
19
|
+
* Supports various XML formats that might appear in assistant outputs
|
|
20
|
+
*/
|
|
21
|
+
private detectXmlToolCalls(content: string): RegExpMatchArray[] {
|
|
22
|
+
// Pattern to match XML tool calls with various formats:
|
|
23
|
+
// Look for tool_call tags specifically
|
|
24
|
+
const toolCallMatches = content.match(/<tool_call>/g);
|
|
25
|
+
// <tool_call name="toolName">arguments</tool_call>
|
|
26
|
+
// <tool_call name="toolName" arguments="json_args"/>
|
|
27
|
+
// <toolCall name="toolName">arguments</toolCall>
|
|
28
|
+
// <function_call name="toolName">arguments</function_call>
|
|
29
|
+
// Pattern for self-closing attribute-based tool calls:
|
|
30
|
+
// <tool_call name="toolName" arguments="json_args"/>
|
|
31
|
+
const xmlToolCallPattern1SelfClosing =
|
|
32
|
+
/<(?:tool_call|toolCall|function_call)\s+name=["']([^"']+)["']\s+arguments=(['"])((?:\\.|(?!\2)[^\\])*?)\2[^>]*\/>/g;
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
// <tool_call>{"name": "toolName", "arguments": {...}}</tool_call>
|
|
36
|
+
const xmlToolCallPattern1 =
|
|
37
|
+
/<(?:tool_call|toolCall|function_call)\s+name=["']([^"']+)["'](?:\s+arguments=["']([^"']*)["'])?[^>]*>([^<]*)<\/(?:tool_call|toolCall|function_call)>/g;
|
|
38
|
+
|
|
39
|
+
// Pattern for JSON-based tool calls:
|
|
40
|
+
// <tool_call>{"name": "toolName", "arguments": {...}}</tool_call>
|
|
41
|
+
// Updated to handle complex nested JSON with braces and multiline content
|
|
42
|
+
const xmlToolCallPattern2 =
|
|
43
|
+
/<(?:tool_call|toolCall|function_call)>\s*(\{(?:[^{}]|{[^{}]*})*?"name"\s*:\s*"([^"]+)"(?:[^{}]|{[^{}]*})*?\})\s*<\/(?:tool_call|toolCall|function_call)>/gs;
|
|
44
|
+
|
|
45
|
+
// Fallback pattern for very complex nested JSON
|
|
46
|
+
const xmlToolCallPattern2Complex = /<(?:tool_call|toolCall|function_call)>\s*(\{[\s\S]*?\})\s*<\/(?:tool_call|toolCall|function_call)>/g;
|
|
47
|
+
|
|
48
|
+
// Pattern for nested XML tool calls:
|
|
49
|
+
// <tool_call><invoke name="toolName"><parameter name="paramName">value</parameter></invoke></tool_call>
|
|
50
|
+
const xmlToolCallPattern3 =
|
|
51
|
+
/<(?:tool_call|toolCall|function_call)>\s*<invoke\s+name=["']([^"']+)["']>\s*(.*?)\s*<\/invoke>\s*<\/(?:tool_call|toolCall|function_call)>/gs;
|
|
52
|
+
const processedRanges: Array<{start: number, end: number}> = [];
|
|
53
|
+
|
|
54
|
+
const matches: RegExpMatchArray[] = [];
|
|
55
|
+
let match;
|
|
56
|
+
|
|
57
|
+
// Reset regex lastIndex for self-closing pattern
|
|
58
|
+
xmlToolCallPattern1SelfClosing.lastIndex = 0;
|
|
59
|
+
|
|
60
|
+
// Self-closing attribute-based pattern
|
|
61
|
+
while ((match = xmlToolCallPattern1SelfClosing.exec(content)) !== null) {
|
|
62
|
+
// For self-closing tags, there's no inner content, so set it to empty string
|
|
63
|
+
const [fullMatch, toolName, quoteChar, argsAttribute] = match;
|
|
64
|
+
const selfClosingMatch = [fullMatch, toolName, argsAttribute, ""] as RegExpMatchArray;
|
|
65
|
+
selfClosingMatch.index = match.index;
|
|
66
|
+
selfClosingMatch.input = match.input;
|
|
67
|
+
matches.push(selfClosingMatch);
|
|
68
|
+
processedRanges.push({start: match.index!, end: match.index! + match[0].length});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// First pattern: attribute-based
|
|
72
|
+
while ((match = xmlToolCallPattern1.exec(content)) !== null) {
|
|
73
|
+
matches.push(match);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Reset regex lastIndex for second pattern
|
|
77
|
+
xmlToolCallPattern1.lastIndex = 0;
|
|
78
|
+
|
|
79
|
+
xmlToolCallPattern2.lastIndex = 0;
|
|
80
|
+
|
|
81
|
+
// Second pattern: JSON-based
|
|
82
|
+
while ((match = xmlToolCallPattern2.exec(content)) !== null) {
|
|
83
|
+
// For JSON-based matches, we need to extract just the arguments part
|
|
84
|
+
// Check if this range is already processed
|
|
85
|
+
const matchStart = match.index!;
|
|
86
|
+
const matchEnd = matchStart + match[0].length;
|
|
87
|
+
const alreadyProcessed = processedRanges.some(range =>
|
|
88
|
+
(matchStart >= range.start && matchStart < range.end) ||
|
|
89
|
+
(matchEnd > range.start && matchEnd <= range.end)
|
|
90
|
+
);
|
|
91
|
+
if (alreadyProcessed) continue;
|
|
92
|
+
|
|
93
|
+
const [fullMatch, jsonContent, toolName] = match;
|
|
94
|
+
|
|
95
|
+
try {
|
|
96
|
+
|
|
97
|
+
// Handle the case where arguments might be an unescaped JSON string
|
|
98
|
+
// First, try to fix common JSON parsing issues
|
|
99
|
+
let fixedJsonContent = jsonContent;
|
|
100
|
+
|
|
101
|
+
// Look for the pattern: "arguments": "{...}" where the inner JSON has unescaped quotes
|
|
102
|
+
const argumentsStringMatch = jsonContent.match(/"arguments"\s*:\s*"(\{.*\})"/);
|
|
103
|
+
if (argumentsStringMatch) {
|
|
104
|
+
// Extract the inner JSON string and properly escape it
|
|
105
|
+
const innerJson = argumentsStringMatch[1];
|
|
106
|
+
const escapedInnerJson = innerJson.replace(/"/g, '\\"');
|
|
107
|
+
fixedJsonContent = jsonContent.replace(
|
|
108
|
+
/"arguments"\s*:\s*"\{.*\}"/,
|
|
109
|
+
`"arguments": "${escapedInnerJson}"`
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
const parsed = JSON.parse(fixedJsonContent);
|
|
114
|
+
let argumentsContent = parsed.arguments || "{}";
|
|
115
|
+
|
|
116
|
+
// If arguments is a string, it might be a JSON string that needs parsing
|
|
117
|
+
if (typeof argumentsContent === 'string') {
|
|
118
|
+
// Try to parse the string as JSON to validate it
|
|
119
|
+
try {
|
|
120
|
+
const parsedArgs = JSON.parse(argumentsContent);
|
|
121
|
+
// If it parses successfully, use the original string
|
|
122
|
+
argumentsContent = argumentsContent;
|
|
123
|
+
} catch {
|
|
124
|
+
// If it doesn't parse, it might need to be wrapped as a string value
|
|
125
|
+
argumentsContent = JSON.stringify({ input: argumentsContent });
|
|
126
|
+
}
|
|
127
|
+
} else {
|
|
128
|
+
argumentsContent = JSON.stringify(argumentsContent);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Restructure match to fit expected format [fullMatch, toolName, argsAttribute, innerContent]
|
|
132
|
+
const restructuredMatch = [
|
|
133
|
+
fullMatch,
|
|
134
|
+
toolName,
|
|
135
|
+
undefined,
|
|
136
|
+
argumentsContent,
|
|
137
|
+
] as RegExpMatchArray;
|
|
138
|
+
restructuredMatch.index = match.index;
|
|
139
|
+
restructuredMatch.input = match.input;
|
|
140
|
+
matches.push(restructuredMatch);
|
|
141
|
+
processedRanges.push({start: matchStart, end: matchEnd});
|
|
142
|
+
} catch (error) {
|
|
143
|
+
// Try string-based parsing as fallback when JSON.parse fails
|
|
144
|
+
try {
|
|
145
|
+
const stringBlocks = this.extractToolCallBlocks(fullMatch);
|
|
146
|
+
if (stringBlocks.length > 0) {
|
|
147
|
+
const block = stringBlocks[0]; // Take the first block found
|
|
148
|
+
const restructuredMatch = [fullMatch, block.name, block.arguments, ""] as RegExpMatchArray;
|
|
149
|
+
restructuredMatch.index = match.index;
|
|
150
|
+
restructuredMatch.input = match.input;
|
|
151
|
+
matches.push(restructuredMatch);
|
|
152
|
+
processedRanges.push({start: matchStart, end: matchEnd});
|
|
153
|
+
} else {
|
|
154
|
+
// If string-based parsing also fails, skip this match
|
|
155
|
+
continue;
|
|
156
|
+
}
|
|
157
|
+
} catch (stringError) {
|
|
158
|
+
// If both JSON and string parsing fail, skip this match
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Reset regex lastIndex for complex pattern
|
|
165
|
+
xmlToolCallPattern2Complex.lastIndex = 0;
|
|
166
|
+
|
|
167
|
+
// Fallback: Try complex pattern for deeply nested JSON
|
|
168
|
+
while ((match = xmlToolCallPattern2Complex.exec(content)) !== null) {
|
|
169
|
+
// Check if this range is already processed
|
|
170
|
+
const matchStart = match.index!;
|
|
171
|
+
const matchEnd = matchStart + match[0].length;
|
|
172
|
+
const alreadyProcessed = processedRanges.some(range =>
|
|
173
|
+
(matchStart >= range.start && matchStart < range.end) ||
|
|
174
|
+
(matchEnd > range.start && matchEnd <= range.end)
|
|
175
|
+
);
|
|
176
|
+
if (alreadyProcessed) continue;
|
|
177
|
+
|
|
178
|
+
const [fullMatch, jsonContent, ...rest] = match;
|
|
179
|
+
|
|
180
|
+
try {
|
|
181
|
+
const parsed = JSON.parse(jsonContent);
|
|
182
|
+
const toolName = parsed.name;
|
|
183
|
+
|
|
184
|
+
if (toolName) {
|
|
185
|
+
let argumentsContent = parsed.arguments || "{}";
|
|
186
|
+
|
|
187
|
+
// Convert arguments to string if it's an object
|
|
188
|
+
if (typeof argumentsContent === 'object') {
|
|
189
|
+
argumentsContent = JSON.stringify(argumentsContent);
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
const restructuredMatch = [fullMatch, toolName, argumentsContent, ""] as RegExpMatchArray;
|
|
193
|
+
restructuredMatch.index = match.index;
|
|
194
|
+
restructuredMatch.input = match.input;
|
|
195
|
+
matches.push(restructuredMatch);
|
|
196
|
+
processedRanges.push({start: matchStart, end: matchEnd});
|
|
197
|
+
}
|
|
198
|
+
} catch (error) {
|
|
199
|
+
// Skip this match if JSON parsing fails
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// Reset regex lastIndex for third pattern
|
|
205
|
+
xmlToolCallPattern3.lastIndex = 0;
|
|
206
|
+
|
|
207
|
+
// Third pattern: nested XML-based
|
|
208
|
+
while ((match = xmlToolCallPattern3.exec(content)) !== null) {
|
|
209
|
+
// Restructure match to fit expected format [fullMatch, toolName, argsAttribute, innerContent]
|
|
210
|
+
const [fullMatch, toolName, innerXml] = match;
|
|
211
|
+
const restructuredMatch = [
|
|
212
|
+
fullMatch,
|
|
213
|
+
toolName,
|
|
214
|
+
undefined,
|
|
215
|
+
innerXml,
|
|
216
|
+
] as RegExpMatchArray;
|
|
217
|
+
restructuredMatch.index = match.index;
|
|
218
|
+
restructuredMatch.input = match.input;
|
|
219
|
+
matches.push(restructuredMatch);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return matches;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Parses XML tool call arguments from various formats
|
|
227
|
+
*/
|
|
228
|
+
private parseToolCallArguments(
|
|
229
|
+
argsAttribute: string | undefined,
|
|
230
|
+
innerContent: string | any
|
|
231
|
+
): string {
|
|
232
|
+
// Handle non-string innerContent (can happen with restructured matches)
|
|
233
|
+
if (innerContent && typeof innerContent !== 'string') {
|
|
234
|
+
return typeof innerContent === 'object' ? JSON.stringify(innerContent) : String(innerContent);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// For JSON-based XML calls, innerContent is now already the arguments part
|
|
238
|
+
if (innerContent && typeof innerContent === 'string' && innerContent.trim()) {
|
|
239
|
+
const trimmedContent = innerContent.trim();
|
|
240
|
+
|
|
241
|
+
// If it's already valid JSON, return it
|
|
242
|
+
try {
|
|
243
|
+
JSON.parse(trimmedContent);
|
|
244
|
+
return trimmedContent;
|
|
245
|
+
} catch {
|
|
246
|
+
// If it's not valid JSON, we'll handle it below
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Check if innerContent contains nested XML parameters (like <parameter name="key">value</parameter>)
|
|
251
|
+
if (innerContent && innerContent.includes("<parameter")) {
|
|
252
|
+
try {
|
|
253
|
+
const parameterPattern =
|
|
254
|
+
/<parameter\s+name=["']([^"']+)["']>([^<]*)<\/parameter>/g;
|
|
255
|
+
const parameters: any = {};
|
|
256
|
+
let paramMatch;
|
|
257
|
+
|
|
258
|
+
while ((paramMatch = parameterPattern.exec(innerContent)) !== null) {
|
|
259
|
+
const [, paramName, paramValue] = paramMatch;
|
|
260
|
+
parameters[paramName] = paramValue.trim();
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
if (Object.keys(parameters).length > 0) {
|
|
264
|
+
return JSON.stringify(parameters);
|
|
265
|
+
}
|
|
266
|
+
} catch (error) {
|
|
267
|
+
// Fall through to existing logic
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
// If arguments are in attribute, use that
|
|
272
|
+
if (argsAttribute && argsAttribute.trim()) {
|
|
273
|
+
return argsAttribute.trim();
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Otherwise, try to parse inner content
|
|
277
|
+
if (innerContent && innerContent.trim()) {
|
|
278
|
+
const trimmedContent = innerContent.trim();
|
|
279
|
+
|
|
280
|
+
// Check if it's already JSON
|
|
281
|
+
try {
|
|
282
|
+
JSON.parse(trimmedContent);
|
|
283
|
+
return trimmedContent;
|
|
284
|
+
} catch {
|
|
285
|
+
// If not JSON, try to extract key-value pairs or treat as single argument
|
|
286
|
+
if (trimmedContent.includes("=") || trimmedContent.includes(":")) {
|
|
287
|
+
// Try to convert key=value pairs to JSON
|
|
288
|
+
try {
|
|
289
|
+
const jsonArgs: any = {};
|
|
290
|
+
const pairs = trimmedContent.split(/[,\n]/);
|
|
291
|
+
|
|
292
|
+
for (const pair of pairs) {
|
|
293
|
+
const trimmedPair = pair.trim();
|
|
294
|
+
if (trimmedPair.includes("=")) {
|
|
295
|
+
const [key, ...valueParts] = trimmedPair.split("=");
|
|
296
|
+
const value = valueParts.join("=").trim();
|
|
297
|
+
jsonArgs[key.trim()] = value.replace(/^["']|["']$/g, ""); // Remove quotes
|
|
298
|
+
} else if (trimmedPair.includes(":")) {
|
|
299
|
+
const [key, ...valueParts] = trimmedPair.split(":");
|
|
300
|
+
const value = valueParts.join(":").trim();
|
|
301
|
+
jsonArgs[key.trim()] = value.replace(/^["']|["']$/g, ""); // Remove quotes
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
if (Object.keys(jsonArgs).length > 0) {
|
|
306
|
+
return JSON.stringify(jsonArgs);
|
|
307
|
+
}
|
|
308
|
+
} catch {
|
|
309
|
+
// Fall through to default handling
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
// If all else fails, wrap in a generic argument structure
|
|
314
|
+
return JSON.stringify({ input: trimmedContent });
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Default empty arguments
|
|
319
|
+
return "{}";
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Generates a unique tool call ID
|
|
324
|
+
*/
|
|
325
|
+
private generateToolCallId(): string {
|
|
326
|
+
return `call_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
/**
|
|
330
|
+
* Converts XML tool call matches to proper ToolCall objects
|
|
331
|
+
*/
|
|
332
|
+
private convertXmlToToolCalls(matches: RegExpMatchArray[]): ToolCall[] {
|
|
333
|
+
const toolCalls: ToolCall[] = [];
|
|
334
|
+
|
|
335
|
+
for (const match of matches) {
|
|
336
|
+
const [fullMatch, toolName, argsAttribute, innerContent] = match;
|
|
337
|
+
|
|
338
|
+
if (!toolName) continue;
|
|
339
|
+
|
|
340
|
+
const toolCall: ToolCall = {
|
|
341
|
+
id: this.generateToolCallId(),
|
|
342
|
+
type: "function",
|
|
343
|
+
function: {
|
|
344
|
+
name: toolName,
|
|
345
|
+
arguments: this.parseToolCallArguments(argsAttribute, innerContent),
|
|
346
|
+
},
|
|
347
|
+
};
|
|
348
|
+
|
|
349
|
+
toolCalls.push(toolCall);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
return toolCalls;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/**
|
|
356
|
+
* Detects incomplete XML tool calls that are missing closing tags
|
|
357
|
+
* This handles cases where the AI finishes the JSON but not the closing tag
|
|
358
|
+
*/
|
|
359
|
+
private detectIncompleteToolCalls(content: string): { name: string; arguments: string }[] {
|
|
360
|
+
const blocks: { name: string; arguments: string }[] = [];
|
|
361
|
+
let startIndex = 0;
|
|
362
|
+
|
|
363
|
+
while (true) {
|
|
364
|
+
const toolCallStart = content.indexOf('<tool_call>', startIndex);
|
|
365
|
+
if (toolCallStart === -1) break;
|
|
366
|
+
|
|
367
|
+
const toolCallEnd = content.indexOf('</tool_call>', toolCallStart);
|
|
368
|
+
|
|
369
|
+
// If no closing tag found, check if we have complete JSON at the end
|
|
370
|
+
if (toolCallEnd === -1) {
|
|
371
|
+
const jsonStart = toolCallStart + '<tool_call>'.length;
|
|
372
|
+
const remainingContent = content.substring(jsonStart).trim();
|
|
373
|
+
|
|
374
|
+
// Try to parse the remaining content as JSON
|
|
375
|
+
try {
|
|
376
|
+
const parsed = JSON.parse(remainingContent);
|
|
377
|
+
if (parsed.name && parsed.arguments !== undefined) {
|
|
378
|
+
blocks.push({
|
|
379
|
+
name: parsed.name,
|
|
380
|
+
arguments: typeof parsed.arguments === 'string' ? parsed.arguments : JSON.stringify(parsed.arguments),
|
|
381
|
+
});
|
|
382
|
+
}
|
|
383
|
+
} catch (error) {
|
|
384
|
+
// If JSON parsing fails, this might be incomplete or malformed
|
|
385
|
+
// We'll skip it for now
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Move past this opening tag for next iteration
|
|
389
|
+
startIndex = toolCallStart + '<tool_call>'.length;
|
|
390
|
+
continue;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// If we found a closing tag, move past it for next iteration
|
|
394
|
+
startIndex = toolCallEnd + '</tool_call>'.length;
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
return blocks;
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
/**
|
|
401
|
+
* Simple string-based extractor for tool call blocks
|
|
402
|
+
*/
|
|
403
|
+
private extractToolCallBlocks(content: string): { name: string; arguments: string }[] {
|
|
404
|
+
const blocks: { name: string; arguments: string }[] = [];
|
|
405
|
+
let startIndex = 0;
|
|
406
|
+
|
|
407
|
+
while (true) {
|
|
408
|
+
const toolCallStart = content.indexOf('<tool_call>', startIndex);
|
|
409
|
+
if (toolCallStart === -1) break;
|
|
410
|
+
|
|
411
|
+
const toolCallEnd = content.indexOf('</tool_call>', toolCallStart);
|
|
412
|
+
if (toolCallEnd === -1) break;
|
|
413
|
+
|
|
414
|
+
// Extract JSON content between tags
|
|
415
|
+
const jsonStart = toolCallStart + '<tool_call>'.length;
|
|
416
|
+
const jsonContent = content.substring(jsonStart, toolCallEnd).trim();
|
|
417
|
+
|
|
418
|
+
try {
|
|
419
|
+
// Try to parse the JSON content directly first
|
|
420
|
+
const parsed = JSON.parse(jsonContent);
|
|
421
|
+
if (parsed.name && parsed.arguments !== undefined) {
|
|
422
|
+
blocks.push({
|
|
423
|
+
name: parsed.name,
|
|
424
|
+
arguments: typeof parsed.arguments === 'string' ? parsed.arguments : JSON.stringify(parsed.arguments),
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
} catch (error: any) {
|
|
428
|
+
|
|
429
|
+
// Try to fix common JSON issues like unescaped newlines
|
|
430
|
+
try {
|
|
431
|
+
// More robust approach: escape all control characters in JSON string values
|
|
432
|
+
let fixedContent = jsonContent;
|
|
433
|
+
|
|
434
|
+
// Find all JSON string values and escape control characters within them
|
|
435
|
+
fixedContent = fixedContent.replace(/"((?:[^"\\]|\\.)*)"/g, (match, content) => {
|
|
436
|
+
const escapedContent = content
|
|
437
|
+
.replace(/\\/g, '\\\\') // Escape backslashes first
|
|
438
|
+
.replace(/\n/g, '\\n') // Escape newlines
|
|
439
|
+
.replace(/\r/g, '\\r') // Escape carriage returns
|
|
440
|
+
.replace(/\t/g, '\\t'); // Escape tabs
|
|
441
|
+
return `"${escapedContent}"`;
|
|
442
|
+
});
|
|
443
|
+
|
|
444
|
+
const parsed = JSON.parse(fixedContent);
|
|
445
|
+
if (parsed.name && parsed.arguments !== undefined) {
|
|
446
|
+
blocks.push({
|
|
447
|
+
name: parsed.name,
|
|
448
|
+
arguments: typeof parsed.arguments === 'string' ? parsed.arguments : JSON.stringify(parsed.arguments),
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
} catch (secondError) {
|
|
452
|
+
// Silent failure - couldn't parse this tool call
|
|
453
|
+
}
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
startIndex = toolCallEnd + '</tool_call>'.length;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
return blocks;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
/**
|
|
463
|
+
* Processes a single message to detect and transform XML tool calls
|
|
464
|
+
*/
|
|
465
|
+
private processMessage(message: Message): void {
|
|
466
|
+
// Only process assistant messages that might contain XML tool calls
|
|
467
|
+
if (message.role !== "assistant") {
|
|
468
|
+
return;
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
// Only process string content
|
|
472
|
+
if (typeof message.content !== "string") {
|
|
473
|
+
return;
|
|
474
|
+
}
|
|
475
|
+
if (message?.tool_calls?.length) {
|
|
476
|
+
return;
|
|
477
|
+
}
|
|
478
|
+
const matches = this.detectXmlToolCalls(message.content);
|
|
479
|
+
|
|
480
|
+
let toolCalls: ToolCall[] = [];
|
|
481
|
+
|
|
482
|
+
if (matches.length === 0) {
|
|
483
|
+
// If no matches found with regex, try the simple string-based extractor first
|
|
484
|
+
const blocks = this.extractToolCallBlocks(message.content);
|
|
485
|
+
|
|
486
|
+
// If still no blocks found, try to detect incomplete tool calls
|
|
487
|
+
let allBlocks = blocks;
|
|
488
|
+
if (blocks.length === 0) {
|
|
489
|
+
allBlocks = this.detectIncompleteToolCalls(message.content);
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
toolCalls = allBlocks.map(block => {
|
|
493
|
+
return {
|
|
494
|
+
id: this.generateToolCallId(),
|
|
495
|
+
type: 'function' as const,
|
|
496
|
+
function: {
|
|
497
|
+
name: block.name,
|
|
498
|
+
arguments: block.arguments,
|
|
499
|
+
},
|
|
500
|
+
};
|
|
501
|
+
});
|
|
502
|
+
} else {
|
|
503
|
+
// Convert XML matches to proper tool calls using existing method
|
|
504
|
+
toolCalls = this.convertXmlToToolCalls(matches);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
if (toolCalls.length === 0) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
// Add tool calls to the message (merge with existing if any)
|
|
512
|
+
if (message.tool_calls) {
|
|
513
|
+
message.tool_calls.push(...toolCalls);
|
|
514
|
+
} else {
|
|
515
|
+
message.tool_calls = toolCalls;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
/**
|
|
520
|
+
* Creates a message processor function for post_call processing
|
|
521
|
+
*/
|
|
522
|
+
createProcessor(): MessageProcessorFunction {
|
|
523
|
+
return (originalMessages: Message[], modifiedMessages: Message[]): void => {
|
|
524
|
+
// Process each message in the modified messages array
|
|
525
|
+
for (const message of modifiedMessages) {
|
|
526
|
+
this.processMessage(message);
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
// Global instance for easy access
|
|
533
|
+
export const globalXmlToolCallProcessor = new XmlToolCallProcessor();
|
package/src/processors/index.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
export { Base64ImageDetector } from "./Base64ImageDetector";
|
|
2
|
+
export { CustomVariables } from "./CustomVariables";
|
|
2
3
|
export { TokenCompressor } from "./TokenCompressor";
|
|
3
4
|
export { ToolResponseCache } from "./ToolResponseCache";
|
|
5
|
+
export { XmlToolCallProcessor } from "./XmlToolCallProcessor";
|
|
6
|
+
export { HarmonyToolProcessor } from "./HarmonyToolProcessor";
|