@tyvm/knowhow 0.0.33 → 0.0.35
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 +182 -24
- 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 +985 -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 +191 -49
- 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 +15 -1
- package/ts_build/src/agents/base/base.js +121 -20
- 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 +57 -0
- package/ts_build/src/chat/modules/AgentModule.js +709 -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 +7 -5
- package/ts_build/src/plugins/downloader/downloader.js +147 -44
- 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
|
@@ -5,14 +5,14 @@ import Logger from "progress-estimator";
|
|
|
5
5
|
import { DownloadInfo, KeyframeInfo, TranscriptChunk } from "./types";
|
|
6
6
|
import { visionTool } from "../../agents/tools/visionTool";
|
|
7
7
|
import { execAsync, fileExists, readFile, mkdir } from "../../utils";
|
|
8
|
-
import
|
|
8
|
+
import OpenAI from "openai";
|
|
9
9
|
import { Clients } from "../../clients";
|
|
10
10
|
import { Models } from "../../types";
|
|
11
11
|
|
|
12
12
|
const logger = Logger();
|
|
13
13
|
|
|
14
14
|
export class DownloaderService {
|
|
15
|
-
constructor(private openAi:
|
|
15
|
+
constructor(private openAi: OpenAI, private clients: typeof Clients) {}
|
|
16
16
|
|
|
17
17
|
async askGptVision(
|
|
18
18
|
imageUrl: string,
|
|
@@ -65,6 +65,36 @@ export class DownloaderService {
|
|
|
65
65
|
return info;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
private async acquireLock(
|
|
69
|
+
lockPath: string,
|
|
70
|
+
timeoutMs = 30000
|
|
71
|
+
): Promise<() => void> {
|
|
72
|
+
const startTime = Date.now();
|
|
73
|
+
|
|
74
|
+
while (Date.now() - startTime < timeoutMs) {
|
|
75
|
+
try {
|
|
76
|
+
await fs.promises.writeFile(lockPath, process.pid.toString(), {
|
|
77
|
+
flag: "wx",
|
|
78
|
+
});
|
|
79
|
+
console.log(`Lock acquired: ${lockPath}`);
|
|
80
|
+
return async () => {
|
|
81
|
+
try {
|
|
82
|
+
await fs.promises.unlink(lockPath);
|
|
83
|
+
console.log(`Lock released: ${lockPath}`);
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.warn(`Failed to release lock ${lockPath}:`, error);
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
} catch (error) {
|
|
89
|
+
if (error.code !== "EEXIST") {
|
|
90
|
+
throw error;
|
|
91
|
+
}
|
|
92
|
+
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
throw new Error(`Failed to acquire lock ${lockPath} within ${timeoutMs}ms`);
|
|
96
|
+
}
|
|
97
|
+
|
|
68
98
|
public async chunk(
|
|
69
99
|
filePath: string,
|
|
70
100
|
outputDir: string,
|
|
@@ -77,44 +107,120 @@ export class DownloaderService {
|
|
|
77
107
|
console.log({ fileName, fileExt });
|
|
78
108
|
console.log("Chunking file", filePath);
|
|
79
109
|
|
|
80
|
-
//
|
|
81
|
-
const
|
|
82
|
-
await
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
110
|
+
// Create lock to prevent concurrent chunking of the same file
|
|
111
|
+
const lockPath = path.join(outputDir, `${fileName}.chunking.lock`);
|
|
112
|
+
const releaseLock = await this.acquireLock(lockPath);
|
|
113
|
+
|
|
114
|
+
try {
|
|
115
|
+
// create a temp directory
|
|
116
|
+
const outputDirPath = path.join(outputDir, `${fileName}/chunks`);
|
|
117
|
+
await fs.promises.mkdir(outputDirPath, { recursive: true });
|
|
118
|
+
const existingFolderFiles = await fs.promises.readdir(outputDirPath);
|
|
119
|
+
const existingChunkNames = existingFolderFiles.filter(
|
|
120
|
+
(f) => f.includes("chunk") && f.endsWith(".mp3")
|
|
121
|
+
);
|
|
87
122
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
123
|
+
if (existingChunkNames.length > 0) {
|
|
124
|
+
if (reuseExistingChunks) {
|
|
125
|
+
console.log("Chunks already exist, skipping");
|
|
126
|
+
await releaseLock();
|
|
127
|
+
const names = existingChunkNames.map((chunkName) =>
|
|
128
|
+
path.join(outputDirPath, chunkName)
|
|
129
|
+
);
|
|
130
|
+
return names;
|
|
131
|
+
} else {
|
|
132
|
+
for (const file of existingFolderFiles) {
|
|
133
|
+
fs.rmSync(path.join(outputDirPath, file), { recursive: true });
|
|
134
|
+
}
|
|
98
135
|
}
|
|
99
136
|
}
|
|
100
|
-
}
|
|
101
137
|
|
|
102
|
-
|
|
103
|
-
|
|
138
|
+
const command = `ffmpeg -i "${filePath}" -f segment -segment_time ${CHUNK_LENGTH_SECONDS} -map 0:a:0 -acodec mp3 -vn "${outputDirPath}/chunk%04d.mp3"`;
|
|
139
|
+
await execAsync(command);
|
|
104
140
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
141
|
+
const folderFiles = await fs.promises.readdir(outputDirPath);
|
|
142
|
+
const chunkNames = folderFiles.filter(
|
|
143
|
+
(f) => f.includes("chunk") && f.endsWith(".mp3")
|
|
144
|
+
);
|
|
145
|
+
console.log("Chunked into", chunkNames.length, "chunks");
|
|
146
|
+
return chunkNames.map((chunkName) => path.join(outputDirPath, chunkName));
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error("Error during chunking:", error);
|
|
149
|
+
throw error;
|
|
150
|
+
} finally {
|
|
151
|
+
await releaseLock();
|
|
152
|
+
}
|
|
111
153
|
}
|
|
112
154
|
|
|
155
|
+
// Add transcription locking to prevent race conditions
|
|
156
|
+
private transcriptionLocks = new Map<string, Promise<TranscriptChunk[]>>();
|
|
157
|
+
|
|
113
158
|
public async *streamTranscription(
|
|
114
159
|
files: string[],
|
|
115
160
|
outputPath: string,
|
|
116
161
|
reusePreviousTranscript = true
|
|
117
162
|
): AsyncGenerator<TranscriptChunk> {
|
|
163
|
+
const exists = await fileExists(outputPath);
|
|
164
|
+
if (exists && reusePreviousTranscript) {
|
|
165
|
+
console.log("Transcription already exists, using cached data");
|
|
166
|
+
const contents = await readFile(outputPath);
|
|
167
|
+
const data = JSON.parse(contents.toString()) as TranscriptChunk[];
|
|
168
|
+
for (const item of data) {
|
|
169
|
+
yield item;
|
|
170
|
+
}
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
// Prevent concurrent transcription of the same output file
|
|
175
|
+
const lockKey = outputPath;
|
|
176
|
+
if (this.transcriptionLocks.has(lockKey)) {
|
|
177
|
+
console.log("Waiting for concurrent transcription to complete...");
|
|
178
|
+
await this.transcriptionLocks.get(lockKey);
|
|
179
|
+
// After waiting, check again if file exists
|
|
180
|
+
const existsNow = await fileExists(outputPath);
|
|
181
|
+
if (existsNow && reusePreviousTranscript) {
|
|
182
|
+
console.log(
|
|
183
|
+
"Transcription completed by concurrent process, using cached data"
|
|
184
|
+
);
|
|
185
|
+
const contents = await readFile(outputPath);
|
|
186
|
+
const data = JSON.parse(contents.toString()) as TranscriptChunk[];
|
|
187
|
+
for (const item of data) {
|
|
188
|
+
yield item;
|
|
189
|
+
}
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
// Create a promise for this transcription operation
|
|
195
|
+
const transcriptionPromise = (async () => {
|
|
196
|
+
const results: TranscriptChunk[] = [];
|
|
197
|
+
for await (const chunk of this.performTranscription(
|
|
198
|
+
files,
|
|
199
|
+
outputPath,
|
|
200
|
+
reusePreviousTranscript
|
|
201
|
+
)) {
|
|
202
|
+
results.push(chunk);
|
|
203
|
+
}
|
|
204
|
+
return results;
|
|
205
|
+
})();
|
|
206
|
+
this.transcriptionLocks.set(lockKey, transcriptionPromise);
|
|
207
|
+
|
|
208
|
+
try {
|
|
209
|
+
const results = await transcriptionPromise;
|
|
210
|
+
for (const chunk of results) {
|
|
211
|
+
yield chunk;
|
|
212
|
+
}
|
|
213
|
+
} finally {
|
|
214
|
+
this.transcriptionLocks.delete(lockKey);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
private async *performTranscription(
|
|
219
|
+
files: string[],
|
|
220
|
+
outputPath: string,
|
|
221
|
+
reusePreviousTranscript: boolean
|
|
222
|
+
): AsyncGenerator<TranscriptChunk> {
|
|
223
|
+
const allTranscripts = [];
|
|
118
224
|
for (const file of files) {
|
|
119
225
|
const chunkName = path.parse(file).name;
|
|
120
226
|
const chunkTranscriptPath = path.join(
|
|
@@ -124,13 +230,19 @@ export class DownloaderService {
|
|
|
124
230
|
const chunkExists = await fileExists(chunkTranscriptPath);
|
|
125
231
|
|
|
126
232
|
if (chunkExists && reusePreviousTranscript) {
|
|
127
|
-
console.log(
|
|
233
|
+
console.log(
|
|
234
|
+
chunkTranscriptPath,
|
|
235
|
+
" transcription already exists, using cached data"
|
|
236
|
+
);
|
|
128
237
|
const contents = await readFile(chunkTranscriptPath);
|
|
129
|
-
|
|
238
|
+
const cached = {
|
|
130
239
|
chunkPath: chunkTranscriptPath,
|
|
131
240
|
text: contents.toString(),
|
|
132
241
|
usd_cost: 0,
|
|
133
242
|
};
|
|
243
|
+
|
|
244
|
+
yield cached;
|
|
245
|
+
allTranscripts.push(cached);
|
|
134
246
|
continue;
|
|
135
247
|
}
|
|
136
248
|
|
|
@@ -149,12 +261,16 @@ export class DownloaderService {
|
|
|
149
261
|
await fs.promises.writeFile(chunkTranscriptPath, transcript.text);
|
|
150
262
|
|
|
151
263
|
// save chunk transcript to file
|
|
152
|
-
|
|
264
|
+
const data = {
|
|
153
265
|
chunkPath: chunkTranscriptPath,
|
|
154
266
|
text: transcript.text,
|
|
155
267
|
usd_cost: 30 * 0.0001, // assume 30 seconds,
|
|
156
268
|
};
|
|
269
|
+
yield data;
|
|
270
|
+
allTranscripts.push(data);
|
|
157
271
|
}
|
|
272
|
+
|
|
273
|
+
fs.writeFileSync(outputPath, JSON.stringify(allTranscripts, null, 2));
|
|
158
274
|
}
|
|
159
275
|
|
|
160
276
|
public async transcribeChunks(
|
|
@@ -164,7 +280,7 @@ export class DownloaderService {
|
|
|
164
280
|
): Promise<string[]> {
|
|
165
281
|
const exists = await fileExists(outputPath);
|
|
166
282
|
if (exists && reusePreviousTranscript) {
|
|
167
|
-
console.log("Transcription already exists,
|
|
283
|
+
console.log("Transcription already exists, using cached data");
|
|
168
284
|
const contents = await readFile(outputPath);
|
|
169
285
|
return JSON.parse(contents.toString()) as string[];
|
|
170
286
|
}
|
|
@@ -185,12 +301,13 @@ export class DownloaderService {
|
|
|
185
301
|
|
|
186
302
|
public async *streamKeyFrameExtraction(
|
|
187
303
|
filePath: string,
|
|
188
|
-
|
|
304
|
+
videoJsonPath: string,
|
|
305
|
+
reusePreviousKeyframes: boolean = true,
|
|
189
306
|
interval: number = 10
|
|
190
307
|
): AsyncGenerator<KeyframeInfo> {
|
|
191
|
-
if (fs.existsSync(
|
|
192
|
-
console.log("Keyframes already exist,
|
|
193
|
-
const contents = await readFile(
|
|
308
|
+
if (reusePreviousKeyframes && fs.existsSync(videoJsonPath)) {
|
|
309
|
+
console.log("Keyframes already exist, using cached data");
|
|
310
|
+
const contents = await readFile(videoJsonPath);
|
|
194
311
|
const data = JSON.parse(contents.toString()) as KeyframeInfo[];
|
|
195
312
|
for (const keyframe of data) {
|
|
196
313
|
yield { ...keyframe, usd_cost: 0 };
|
|
@@ -199,16 +316,18 @@ export class DownloaderService {
|
|
|
199
316
|
}
|
|
200
317
|
|
|
201
318
|
const parsed = path.parse(filePath);
|
|
202
|
-
const outputDir = path.dirname(
|
|
319
|
+
const outputDir = path.dirname(videoJsonPath);
|
|
203
320
|
const fileName = parsed.name;
|
|
204
321
|
const keyframesDir = path.join(outputDir, `/keyframes`);
|
|
205
322
|
await fs.promises.mkdir(keyframesDir, { recursive: true });
|
|
206
323
|
|
|
207
324
|
const command = `ffmpeg -i "${filePath}" -vf "fps=1/${interval},scale=640:-1" "${keyframesDir}/frame%04d.jpg"`;
|
|
208
325
|
await execAsync(command);
|
|
326
|
+
console.log("Extracting keyframe:", command);
|
|
209
327
|
|
|
210
328
|
const keyframes = await fs.promises.readdir(keyframesDir);
|
|
211
329
|
|
|
330
|
+
const allKeyframes = [];
|
|
212
331
|
for (const keyframe of keyframes) {
|
|
213
332
|
const keyframePath = path.join(keyframesDir, keyframe);
|
|
214
333
|
const keyframeName = path.parse(keyframe).name;
|
|
@@ -218,10 +337,11 @@ export class DownloaderService {
|
|
|
218
337
|
);
|
|
219
338
|
const descriptionExists = await fileExists(keyframeDescriptionPath);
|
|
220
339
|
|
|
221
|
-
if (descriptionExists) {
|
|
340
|
+
if (descriptionExists && reusePreviousKeyframes) {
|
|
222
341
|
const cached = await readFile(keyframeDescriptionPath);
|
|
223
342
|
const cachedJson = JSON.parse(cached.toString()) as KeyframeInfo;
|
|
224
343
|
yield { ...cachedJson, usd_cost: 0 };
|
|
344
|
+
allKeyframes.push(cachedJson);
|
|
225
345
|
continue;
|
|
226
346
|
}
|
|
227
347
|
|
|
@@ -237,18 +357,26 @@ export class DownloaderService {
|
|
|
237
357
|
JSON.stringify(keyframeJson, null, 2)
|
|
238
358
|
);
|
|
239
359
|
yield keyframeJson;
|
|
360
|
+
allKeyframes.push(keyframeJson);
|
|
240
361
|
}
|
|
362
|
+
|
|
363
|
+
await fs.promises.writeFile(
|
|
364
|
+
videoJsonPath,
|
|
365
|
+
JSON.stringify(allKeyframes, null, 2)
|
|
366
|
+
);
|
|
241
367
|
}
|
|
242
368
|
|
|
243
369
|
public async extractKeyframes(
|
|
244
370
|
filePath: string,
|
|
245
371
|
outputPath: string,
|
|
372
|
+
reusePreviousKeyframes: boolean = true,
|
|
246
373
|
interval: number = 10
|
|
247
374
|
): Promise<KeyframeInfo[]> {
|
|
248
375
|
const keyframes: KeyframeInfo[] = [];
|
|
249
376
|
for await (const keyframe of this.streamKeyFrameExtraction(
|
|
250
377
|
filePath,
|
|
251
378
|
outputPath,
|
|
379
|
+
reusePreviousKeyframes,
|
|
252
380
|
interval
|
|
253
381
|
)) {
|
|
254
382
|
keyframes.push(keyframe);
|
|
@@ -265,6 +393,7 @@ export class DownloaderService {
|
|
|
265
393
|
encoding: "base64",
|
|
266
394
|
});
|
|
267
395
|
const image = `data:image/jpeg;base64,${base64}`;
|
|
396
|
+
console.log("Describing keyframe:", keyframePath);
|
|
268
397
|
const response = await this.askGptVision(image, question);
|
|
269
398
|
return response;
|
|
270
399
|
}
|
|
@@ -285,7 +414,9 @@ export class DownloaderService {
|
|
|
285
414
|
// Skip chunking if the full output exists
|
|
286
415
|
const exists = await fileExists(outputPath);
|
|
287
416
|
if (exists && reusePreviousTranscript) {
|
|
288
|
-
console.log(
|
|
417
|
+
console.log(
|
|
418
|
+
`Transcription ${outputPath} already exists, using cached data`
|
|
419
|
+
);
|
|
289
420
|
const fileContent = await readFile(outputPath, "utf8");
|
|
290
421
|
return outputPath.endsWith("txt")
|
|
291
422
|
? fileContent.split("\n")
|
|
@@ -318,14 +449,21 @@ export class DownloaderService {
|
|
|
318
449
|
// Skip chunking if the full output exists
|
|
319
450
|
const exists = await fileExists(outputPath);
|
|
320
451
|
if (exists && reusePreviousTranscript) {
|
|
321
|
-
console.log(
|
|
452
|
+
console.log(
|
|
453
|
+
`Transcription ${outputPath} already exists, using cached data`
|
|
454
|
+
);
|
|
322
455
|
const fileContent = await readFile(outputPath, "utf8");
|
|
323
456
|
const lines = outputPath.endsWith("txt")
|
|
324
457
|
? fileContent.split("\n")
|
|
325
458
|
: JSON.parse(fileContent);
|
|
326
459
|
|
|
327
|
-
for (const line of lines)
|
|
328
|
-
|
|
460
|
+
for (const line of lines) {
|
|
461
|
+
if (typeof line === "string") {
|
|
462
|
+
yield { chunkPath: "", text: line, usd_cost: 0 };
|
|
463
|
+
} else {
|
|
464
|
+
yield line as TranscriptChunk;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
329
467
|
return;
|
|
330
468
|
}
|
|
331
469
|
|
|
@@ -364,6 +502,7 @@ export class DownloaderService {
|
|
|
364
502
|
const videoAnalysis = await this.extractKeyframes(
|
|
365
503
|
filePath,
|
|
366
504
|
outputPath,
|
|
505
|
+
reusePreviousTranscript,
|
|
367
506
|
chunkTime
|
|
368
507
|
);
|
|
369
508
|
|
|
@@ -381,19 +520,20 @@ export class DownloaderService {
|
|
|
381
520
|
chunkTime = 30
|
|
382
521
|
) {
|
|
383
522
|
const parsed = path.parse(filePath);
|
|
384
|
-
const
|
|
523
|
+
const videoJson = `${parsed.dir}/${parsed.name}/video.json`;
|
|
385
524
|
|
|
386
525
|
console.log("Processing audio...");
|
|
387
|
-
const transcriptions =
|
|
526
|
+
const transcriptions = this.streamProcessAudio(
|
|
388
527
|
filePath,
|
|
389
528
|
reusePreviousTranscript,
|
|
390
529
|
chunkTime
|
|
391
530
|
);
|
|
392
531
|
|
|
393
532
|
console.log("Extracting keyframes...");
|
|
394
|
-
const videoAnalysis =
|
|
533
|
+
const videoAnalysis = this.streamKeyFrameExtraction(
|
|
395
534
|
filePath,
|
|
396
|
-
|
|
535
|
+
videoJson,
|
|
536
|
+
reusePreviousTranscript,
|
|
397
537
|
chunkTime
|
|
398
538
|
);
|
|
399
539
|
|
|
@@ -402,10 +542,12 @@ export class DownloaderService {
|
|
|
402
542
|
?.value as TranscriptChunk;
|
|
403
543
|
yield {
|
|
404
544
|
frame,
|
|
405
|
-
transcription
|
|
545
|
+
transcription: transcription || {
|
|
546
|
+
chunkPath: "",
|
|
547
|
+
text: "[missing transcript]",
|
|
548
|
+
usd_cost: 0,
|
|
549
|
+
},
|
|
406
550
|
};
|
|
407
551
|
}
|
|
408
552
|
}
|
|
409
553
|
}
|
|
410
|
-
|
|
411
|
-
export const Downloader = new DownloaderService(openai, Clients);
|
|
@@ -2,7 +2,7 @@ import fs from "fs";
|
|
|
2
2
|
import { PluginBase, PluginMeta } from "../PluginBase";
|
|
3
3
|
import { MinimalEmbedding } from "../../types";
|
|
4
4
|
import { convertToText, processVideo } from "../../conversion";
|
|
5
|
-
import {
|
|
5
|
+
import { services } from "../../services";
|
|
6
6
|
|
|
7
7
|
export class DownloaderPlugin extends PluginBase {
|
|
8
8
|
static readonly meta: PluginMeta = {
|
|
@@ -40,6 +40,7 @@ export class DownloaderPlugin extends PluginBase {
|
|
|
40
40
|
try {
|
|
41
41
|
console.log("DOWNLOADER PLUGIN: attempting", url);
|
|
42
42
|
const downloadDir = ".knowhow/downloads/";
|
|
43
|
+
const { Downloader } = services();
|
|
43
44
|
const fileInfo = await Downloader.download(url, downloadDir);
|
|
44
45
|
const filePath = `${downloadDir}${fileInfo.id}.${fileInfo.ext}`;
|
|
45
46
|
transcript += await convertToText(filePath);
|
|
@@ -59,6 +60,7 @@ export class DownloaderPlugin extends PluginBase {
|
|
|
59
60
|
const embeddings: MinimalEmbedding[] = [];
|
|
60
61
|
for (const url of urls) {
|
|
61
62
|
const downloadDir = ".knowhow/downloads/";
|
|
63
|
+
const { Downloader } = services();
|
|
62
64
|
const fileInfo = await Downloader.download(url, downloadDir);
|
|
63
65
|
const filePath = `${downloadDir}${fileInfo.id}.${fileInfo.ext}`;
|
|
64
66
|
const processed = await processVideo(filePath);
|
package/src/plugins/plugins.ts
CHANGED