profclaw 2.0.0 → 2.3.0
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/.env.example +14 -2
- package/CHANGELOG.md +37 -0
- package/CONTRIBUTING.md +20 -0
- package/Dockerfile +39 -23
- package/README.md +174 -40
- package/dist/agents/agent-summary.d.ts +44 -0
- package/dist/agents/agent-summary.js +176 -0
- package/dist/agents/auto-memory.d.ts +59 -0
- package/dist/agents/auto-memory.js +310 -0
- package/dist/agents/checkpoint-manager.d.ts +76 -0
- package/dist/agents/checkpoint-manager.js +156 -0
- package/dist/agents/circuit-breaker.d.ts +54 -0
- package/dist/agents/circuit-breaker.js +153 -0
- package/dist/agents/context-compactor.d.ts +70 -0
- package/dist/agents/context-compactor.js +361 -0
- package/dist/agents/conversation-branch.d.ts +55 -0
- package/dist/agents/conversation-branch.js +115 -0
- package/dist/agents/error-recovery.d.ts +44 -0
- package/dist/agents/error-recovery.js +197 -0
- package/dist/agents/events.d.ts +76 -0
- package/dist/agents/events.js +8 -0
- package/dist/agents/executor.d.ts +35 -1
- package/dist/agents/executor.js +573 -124
- package/dist/agents/file-snapshots.d.ts +72 -0
- package/dist/agents/file-snapshots.js +182 -0
- package/dist/agents/index.d.ts +2 -0
- package/dist/agents/orchestrator.d.ts +183 -0
- package/dist/agents/orchestrator.js +495 -0
- package/dist/agents/permissions.d.ts +63 -0
- package/dist/agents/permissions.js +138 -0
- package/dist/agents/plan-mode.d.ts +71 -0
- package/dist/agents/plan-mode.js +186 -0
- package/dist/agents/prompt-suggestions.d.ts +33 -0
- package/dist/agents/prompt-suggestions.js +208 -0
- package/dist/agents/rate-limit-monitor.d.ts +56 -0
- package/dist/agents/rate-limit-monitor.js +224 -0
- package/dist/agents/result-store.d.ts +37 -0
- package/dist/agents/result-store.js +104 -0
- package/dist/agents/session-diff.d.ts +43 -0
- package/dist/agents/session-diff.js +258 -0
- package/dist/agents/tool-loader.d.ts +65 -0
- package/dist/agents/tool-loader.js +273 -0
- package/dist/agents/transcript.d.ts +96 -0
- package/dist/agents/transcript.js +267 -0
- package/dist/agents/worktree-manager.d.ts +80 -0
- package/dist/agents/worktree-manager.js +203 -0
- package/dist/auth/middleware.js +14 -0
- package/dist/chat/agentic-executor.d.ts +7 -0
- package/dist/chat/agentic-executor.js +253 -30
- package/dist/chat/conversations.d.ts +2 -0
- package/dist/chat/conversations.js +8 -0
- package/dist/chat/execution/executor.d.ts +8 -0
- package/dist/chat/execution/executor.js +157 -103
- package/dist/chat/execution/index.js +5 -1
- package/dist/chat/execution/tool-router.js +40 -14
- package/dist/chat/execution/tools/canvas.d.ts +2 -2
- package/dist/chat/execution/tools/code-tools.d.ts +66 -0
- package/dist/chat/execution/tools/code-tools.js +353 -0
- package/dist/chat/execution/tools/complete-task.d.ts +2 -2
- package/dist/chat/execution/tools/cron-tool.d.ts +26 -10
- package/dist/chat/execution/tools/cron-tool.js +48 -3
- package/dist/chat/execution/tools/decompose-task.d.ts +58 -0
- package/dist/chat/execution/tools/decompose-task.js +166 -0
- package/dist/chat/execution/tools/exec.d.ts +5 -2
- package/dist/chat/execution/tools/exec.js +294 -155
- package/dist/chat/execution/tools/feed-tools.d.ts +77 -0
- package/dist/chat/execution/tools/feed-tools.js +142 -0
- package/dist/chat/execution/tools/file-ops.d.ts +1 -1
- package/dist/chat/execution/tools/github.d.ts +2 -2
- package/dist/chat/execution/tools/index.d.ts +14 -2
- package/dist/chat/execution/tools/index.js +86 -12
- package/dist/chat/execution/tools/integrations.d.ts +8 -8
- package/dist/chat/execution/tools/multi-patch.d.ts +53 -0
- package/dist/chat/execution/tools/multi-patch.js +373 -0
- package/dist/chat/execution/tools/openai-image-gen.d.ts +2 -2
- package/dist/chat/execution/tools/plan-tools.d.ts +80 -0
- package/dist/chat/execution/tools/plan-tools.js +134 -0
- package/dist/chat/execution/tools/profclaw-ops.d.ts +6 -6
- package/dist/chat/execution/tools/repl-tool.d.ts +46 -0
- package/dist/chat/execution/tools/repl-tool.js +207 -0
- package/dist/chat/execution/tools/sessions-send.d.ts +2 -2
- package/dist/chat/execution/tools/slack-actions.d.ts +2 -2
- package/dist/chat/execution/tools/system.d.ts +4 -4
- package/dist/chat/execution/tools/todo-tool.d.ts +72 -0
- package/dist/chat/execution/tools/todo-tool.js +152 -0
- package/dist/chat/execution/tools/tool-search.d.ts +50 -0
- package/dist/chat/execution/tools/tool-search.js +155 -0
- package/dist/chat/execution/types.d.ts +21 -14
- package/dist/chat/execution/workflows/executor.d.ts +11 -0
- package/dist/chat/execution/workflows/executor.js +99 -1
- package/dist/chat/execution/workflows/types.d.ts +35 -2
- package/dist/chat/format/index.d.ts +1 -0
- package/dist/chat/format/index.js +1 -0
- package/dist/chat/format/markdown-convert.d.ts +23 -0
- package/dist/chat/format/markdown-convert.js +149 -0
- package/dist/chat/index.d.ts +1 -1
- package/dist/chat/index.js +1 -1
- package/dist/chat/message-handler.js +58 -6
- package/dist/chat/proactive/index.d.ts +62 -0
- package/dist/chat/proactive/index.js +147 -0
- package/dist/chat/prompt-adapter.js +2 -0
- package/dist/chat/providers/irc/index.d.ts +2 -2
- package/dist/chat/providers/telegram/index.d.ts +2 -0
- package/dist/chat/providers/telegram/index.js +21 -2
- package/dist/chat/system-prompts.d.ts +3 -3
- package/dist/chat/system-prompts.js +116 -61
- package/dist/chat/tools.d.ts +6 -6
- package/dist/cli/commands/auth.js +64 -1
- package/dist/cli/commands/chat.js +1327 -138
- package/dist/cli/commands/doctor.js +222 -16
- package/dist/cli/commands/history.d.ts +3 -0
- package/dist/cli/commands/history.js +138 -0
- package/dist/cli/commands/import.d.ts +44 -0
- package/dist/cli/commands/import.js +526 -0
- package/dist/cli/commands/init.d.ts +13 -0
- package/dist/cli/commands/init.js +381 -0
- package/dist/cli/commands/onboard.js +210 -30
- package/dist/cli/commands/plan.d.ts +13 -0
- package/dist/cli/commands/plan.js +184 -0
- package/dist/cli/commands/serve.d.ts +7 -0
- package/dist/cli/commands/serve.js +77 -18
- package/dist/cli/commands/setup.js +84 -3
- package/dist/cli/commands/status.js +54 -0
- package/dist/cli/commands/tools.js +13 -13
- package/dist/cli/commands/tui.js +26 -1
- package/dist/cli/index.js +19 -0
- package/dist/cli/ink/App.d.ts +13 -0
- package/dist/cli/ink/App.js +6 -0
- package/dist/cli/ink/ChatApp.d.ts +60 -0
- package/dist/cli/ink/ChatApp.js +325 -0
- package/dist/cli/ink/DashboardApp.d.ts +3 -0
- package/dist/cli/ink/DashboardApp.js +143 -0
- package/dist/cli/ink/components/AgentStatus.d.ts +17 -0
- package/dist/cli/ink/components/AgentStatus.js +33 -0
- package/dist/cli/ink/components/ChannelList.d.ts +17 -0
- package/dist/cli/ink/components/ChannelList.js +33 -0
- package/dist/cli/ink/components/ConnectionStatus.d.ts +19 -0
- package/dist/cli/ink/components/ConnectionStatus.js +50 -0
- package/dist/cli/ink/components/CostBar.d.ts +19 -0
- package/dist/cli/ink/components/CostBar.js +35 -0
- package/dist/cli/ink/components/HookStatus.d.ts +15 -0
- package/dist/cli/ink/components/HookStatus.js +7 -0
- package/dist/cli/ink/components/PermissionPrompt.d.ts +21 -0
- package/dist/cli/ink/components/PermissionPrompt.js +51 -0
- package/dist/cli/ink/components/PlanView.d.ts +23 -0
- package/dist/cli/ink/components/PlanView.js +26 -0
- package/dist/cli/ink/components/ProviderList.d.ts +16 -0
- package/dist/cli/ink/components/ProviderList.js +16 -0
- package/dist/cli/ink/components/SessionHeader.d.ts +15 -0
- package/dist/cli/ink/components/SessionHeader.js +15 -0
- package/dist/cli/ink/components/StreamingMessage.d.ts +20 -0
- package/dist/cli/ink/components/StreamingMessage.js +27 -0
- package/dist/cli/ink/components/SuggestionBar.d.ts +15 -0
- package/dist/cli/ink/components/SuggestionBar.js +28 -0
- package/dist/cli/ink/components/SystemHealth.d.ts +20 -0
- package/dist/cli/ink/components/SystemHealth.js +39 -0
- package/dist/cli/ink/components/TaskList.d.ts +17 -0
- package/dist/cli/ink/components/TaskList.js +59 -0
- package/dist/cli/ink/components/ToolCall.d.ts +17 -0
- package/dist/cli/ink/components/ToolCall.js +43 -0
- package/dist/cli/ink/index.d.ts +23 -0
- package/dist/cli/ink/index.js +15 -0
- package/dist/cli/ink/keybindings.d.ts +35 -0
- package/dist/cli/ink/keybindings.js +105 -0
- package/dist/cli/ink/markdown-renderer.d.ts +47 -0
- package/dist/cli/ink/markdown-renderer.js +380 -0
- package/dist/cli/ink/output-styles.d.ts +39 -0
- package/dist/cli/ink/output-styles.js +119 -0
- package/dist/cli/interactive/auto-serve.d.ts +38 -0
- package/dist/cli/interactive/auto-serve.js +209 -0
- package/dist/cli/interactive/index.d.ts +25 -0
- package/dist/cli/interactive/index.js +23 -0
- package/dist/cli/interactive/picker.d.ts +28 -0
- package/dist/cli/interactive/picker.js +153 -0
- package/dist/cli/interactive/renderer.d.ts +26 -0
- package/dist/cli/interactive/renderer.js +555 -0
- package/dist/cli/interactive/repl.d.ts +14 -0
- package/dist/cli/interactive/repl.js +1516 -0
- package/dist/cli/interactive/stream-client.d.ts +59 -0
- package/dist/cli/interactive/stream-client.js +506 -0
- package/dist/cli/interactive/types.d.ts +121 -0
- package/dist/cli/interactive/types.js +10 -0
- package/dist/cli/utils/api.d.ts +9 -0
- package/dist/cli/utils/api.js +58 -2
- package/dist/cron/natural-language.d.ts +54 -0
- package/dist/cron/natural-language.js +569 -0
- package/dist/cron/scheduler.d.ts +34 -4
- package/dist/cron/scheduler.js +141 -9
- package/dist/cron/templates.d.ts +1 -1
- package/dist/cron/templates.js +219 -0
- package/dist/feeds/feed-engine.d.ts +149 -0
- package/dist/feeds/feed-engine.js +600 -0
- package/dist/feeds/index.d.ts +9 -0
- package/dist/feeds/index.js +8 -0
- package/dist/gateway/router.js +6 -1
- package/dist/hooks/built-in/audit-log.d.ts +11 -0
- package/dist/hooks/built-in/audit-log.js +84 -0
- package/dist/hooks/built-in/cost-warning.d.ts +10 -0
- package/dist/hooks/built-in/cost-warning.js +59 -0
- package/dist/hooks/built-in/dangerous-tool.d.ts +32 -0
- package/dist/hooks/built-in/dangerous-tool.js +80 -0
- package/dist/hooks/built-in/index.d.ts +14 -0
- package/dist/hooks/built-in/index.js +20 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/index.js +6 -0
- package/dist/hooks/loader.d.ts +17 -0
- package/dist/hooks/loader.js +142 -0
- package/dist/hooks/registry.d.ts +62 -0
- package/dist/hooks/registry.js +127 -0
- package/dist/integrations/web-search.js +6 -3
- package/dist/memory/index.d.ts +1 -0
- package/dist/memory/index.js +2 -0
- package/dist/memory/memory-service.js +14 -13
- package/dist/memory/observational.d.ts +62 -0
- package/dist/memory/observational.js +396 -0
- package/dist/middleware/content-filter.d.ts +22 -0
- package/dist/middleware/content-filter.js +69 -0
- package/dist/middleware/request-validator.d.ts +159 -0
- package/dist/middleware/request-validator.js +93 -0
- package/dist/plugins/sdk.d.ts +22 -0
- package/dist/plugins/sdk.js +17 -1
- package/dist/projects/types.d.ts +10 -10
- package/dist/providers/ai-sdk.d.ts +11 -0
- package/dist/providers/ai-sdk.js +78 -19
- package/dist/providers/core/models.js +67 -1
- package/dist/providers/core/types.d.ts +3 -0
- package/dist/providers/index.d.ts +1 -0
- package/dist/providers/index.js +1 -0
- package/dist/providers/smart-router.d.ts +118 -0
- package/dist/providers/smart-router.js +685 -0
- package/dist/providers/types.d.ts +16 -16
- package/dist/routes/agents.js +50 -0
- package/dist/routes/auth.js +8 -1
- package/dist/routes/chat.js +259 -14
- package/dist/routes/costs.js +32 -0
- package/dist/routes/cron.js +80 -5
- package/dist/routes/feeds.d.ts +10 -0
- package/dist/routes/feeds.js +168 -0
- package/dist/routes/mcp.js +21 -0
- package/dist/routes/memory.js +130 -0
- package/dist/routes/skills.js +129 -0
- package/dist/routes/teams.d.ts +9 -0
- package/dist/routes/teams.js +210 -0
- package/dist/routes/tools.js +14 -0
- package/dist/routes/users.js +2 -0
- package/dist/server/route-loader.js +3 -1
- package/dist/server/stream-bridge.d.ts +19 -0
- package/dist/server/stream-bridge.js +38 -0
- package/dist/server.js +310 -36
- package/dist/skills/marketplace.d.ts +87 -0
- package/dist/skills/marketplace.js +268 -0
- package/dist/storage/index.d.ts +14 -0
- package/dist/storage/index.js +64 -3
- package/dist/storage/schema.d.ts +4 -4
- package/dist/storage/schema.js +1 -1
- package/dist/teams/index.d.ts +110 -0
- package/dist/teams/index.js +365 -0
- package/dist/tickets/types.d.ts +39 -39
- package/dist/types/summary.d.ts +5 -5
- package/dist/utils/auto-update.d.ts +23 -0
- package/dist/utils/auto-update.js +157 -0
- package/dist/utils/offline-detect.d.ts +55 -0
- package/dist/utils/offline-detect.js +121 -0
- package/dist/utils/pid-file.d.ts +36 -0
- package/dist/utils/pid-file.js +125 -0
- package/dist/utils/prevent-sleep.d.ts +27 -0
- package/dist/utils/prevent-sleep.js +95 -0
- package/dist/utils/sanitizer.d.ts +57 -0
- package/dist/utils/sanitizer.js +174 -0
- package/docker-compose.yml +13 -137
- package/package.json +31 -6
- package/skills/deploy-cloudflare/SKILL.md +62 -0
- package/skills/deploy-vercel/SKILL.md +67 -0
- package/skills/docker-deploy/SKILL.md +158 -0
- package/skills/full-stack-builder/SKILL.md +92 -0
- package/skills/humanizer/SKILL.md +488 -0
- package/skills/profclaw-assistant/SKILL.md +85 -56
- package/ui/dist/assets/ActivityView-Da6HQ8ws.js +1 -0
- package/ui/dist/assets/AgentList-H58R0kX3.js +1 -0
- package/ui/dist/assets/AnalyticsDashboard-B28AeRsc.js +1 -0
- package/ui/dist/assets/AreaChart-DwLzeAQ8.js +1 -0
- package/ui/dist/assets/CartesianChart-piKQsTAR.js +36 -0
- package/ui/dist/assets/ChatView-Dbj8rxU5.js +10 -0
- package/ui/dist/assets/CostsDashboard-C6F5df0F.js +1 -0
- package/ui/dist/assets/EstimateSelect-wga0rUKX.js +1 -0
- package/ui/dist/assets/FeedDashboard-Ef6FEzEf.js +1 -0
- package/ui/dist/assets/FloatingChatbot-0yhkUeCq.js +2 -0
- package/ui/dist/assets/InviteCodeManagement-tUXfx4Bc.js +2 -0
- package/ui/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
- package/ui/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
- package/ui/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
- package/ui/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
- package/ui/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
- package/ui/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
- package/ui/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
- package/ui/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
- package/ui/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
- package/ui/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
- package/ui/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
- package/ui/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
- package/ui/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
- package/ui/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
- package/ui/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
- package/ui/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
- package/ui/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
- package/ui/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
- package/ui/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
- package/ui/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
- package/ui/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
- package/ui/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
- package/ui/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
- package/ui/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
- package/ui/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
- package/ui/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
- package/ui/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
- package/ui/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
- package/ui/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
- package/ui/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
- package/ui/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
- package/ui/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
- package/ui/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
- package/ui/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
- package/ui/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
- package/ui/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
- package/ui/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
- package/ui/dist/assets/MarketplacePage-DGrLtolR.js +1 -0
- package/ui/dist/assets/{ProjectDetail--gPfvATB.js → ProjectDetail-BgWvA6UP.js} +2 -2
- package/ui/dist/assets/ProjectIcon-TDuliqwg.js +1 -0
- package/ui/dist/assets/ProjectList-DXgM4187.js +1 -0
- package/ui/dist/assets/{Settings-1kaf7VHE.js → Settings-xA8Zhi3p.js} +3 -3
- package/ui/dist/assets/StatusIndicator-B8vfFAxg.js +1 -0
- package/ui/dist/assets/{SummaryDetail-DV3AmONk.js → SummaryDetail-eedRfTtF.js} +2 -2
- package/ui/dist/assets/SummaryList-CLNX2P84.js +1 -0
- package/ui/dist/assets/TaskDetail-BtWclNiR.js +1 -0
- package/ui/dist/assets/TaskList-JjODAgSc.js +1 -0
- package/ui/dist/assets/TeamsPage-CBK5iAyx.js +1 -0
- package/ui/dist/assets/TicketBoard-C9aJNNYp.js +1 -0
- package/ui/dist/assets/TicketDetail-CV5JmL31.js +1 -0
- package/ui/dist/assets/TicketList-68V4lzUz.js +1 -0
- package/ui/dist/assets/UserManagement-DKTb6UpE.js +2 -0
- package/ui/dist/assets/ViewSwitcher-BvdQht2Y.js +1 -0
- package/ui/dist/assets/alert-dialog-O6qBOv_f.js +1 -0
- package/ui/dist/assets/{archive-BsLa7brF.js → archive-CX7UvZpf.js} +1 -1
- package/ui/dist/assets/badge-BbfnwDJP.js +1 -0
- package/ui/dist/assets/{bug-CmZI7jqM.js → bug-3WX0394-.js} +1 -1
- package/ui/dist/assets/{calendar-Bf0t2B82.js → calendar-buq77TaS.js} +1 -1
- package/ui/dist/assets/{chevron-up-CoUsOvZj.js → chevron-up-4ymsBJRo.js} +1 -1
- package/ui/dist/assets/{circle-x-Dgw11LgT.js → circle-x-ByXtwR6Y.js} +1 -1
- package/ui/dist/assets/constants-CVdDh7p0.js +1 -0
- package/ui/dist/assets/{cpu-DiPMQICV.js → cpu-CiuoCeDY.js} +1 -1
- package/ui/dist/assets/{database-BwTfupDi.js → database-BWXSBg5a.js} +1 -1
- package/ui/dist/assets/dialog-lDg4NvMV.js +1 -0
- package/ui/dist/assets/dollar-sign-Dmijd6DP.js +1 -0
- package/ui/dist/assets/{ellipsis-UJx4Xnf6.js → ellipsis-vT-5SVIp.js} +1 -1
- package/ui/dist/assets/{ellipsis-vertical-DoULYEKn.js → ellipsis-vertical-B4tAX_bL.js} +1 -1
- package/ui/dist/assets/feature-markdown-DBo5Q7uq.js +289 -0
- package/ui/dist/assets/{file-code-B2UrJLwi.js → file-code-ChOWdKXf.js} +1 -1
- package/ui/dist/assets/{folder-open-BJi577JH.js → folder-open-CkOUbIiP.js} +1 -1
- package/ui/dist/assets/{funnel-PkaD_HSR.js → funnel-uZkoSPP-.js} +1 -1
- package/ui/dist/assets/{git-branch-C_K30am0.js → git-branch-CwvUxj7C.js} +1 -1
- package/ui/dist/assets/{git-commit-horizontal-IT6ecxWQ.js → git-commit-horizontal-lxPzCvhD.js} +1 -1
- package/ui/dist/assets/{globe-f-jjCa_g.js → globe-D_WpJdsj.js} +1 -1
- package/ui/dist/assets/{hash-DNEv8Elo.js → hash-CA0hJ7vh.js} +1 -1
- package/ui/dist/assets/{history-BQSBo_1Q.js → history-CEWMLELs.js} +1 -1
- package/ui/dist/assets/inbox-ehtOptTV.js +1 -0
- package/ui/dist/assets/{index-nS3EErDg.js → index-C1rhbml4.js} +3 -3
- package/ui/dist/assets/index-CR8gfCHv.js +1 -0
- package/ui/dist/assets/index-DVXMpWai.js +1 -0
- package/ui/dist/assets/index-DaDJMM2v.js +1 -0
- package/ui/dist/assets/index-Djdq_0xu.js +1 -0
- package/ui/dist/assets/index-M46Gcb8K.css +1 -0
- package/ui/dist/assets/index-sEBN7w8J.js +109 -0
- package/ui/dist/assets/layers-C6Mhf8Nk.js +1 -0
- package/ui/dist/assets/{layout-dashboard-CcKt1hXw.js → layout-dashboard-BRUM0kpT.js} +1 -1
- package/ui/dist/assets/{lightbulb-Jhp7FvbU.js → lightbulb-CN2q1O5l.js} +1 -1
- package/ui/dist/assets/{link-2-DdO7ostF.js → link-2-CC4E28yJ.js} +1 -1
- package/ui/dist/assets/markdown-renderer-C6ENbB0u.js +10 -0
- package/ui/dist/assets/markdown-renderer-CfVKi3_s.css +1 -0
- package/ui/dist/assets/{message-square-CBgH65X7.js → message-square-Bbb241am.js} +1 -1
- package/ui/dist/assets/package-CwT3IzFx.js +1 -0
- package/ui/dist/assets/{pencil-CYXCEPQh.js → pencil-CDmiHzoj.js} +1 -1
- package/ui/dist/assets/{play-d1ONaH0-.js → play-tjy5jMQX.js} +1 -1
- package/ui/dist/assets/popover-CFHZf3pE.js +1 -0
- package/ui/dist/assets/progress-BboUHuLf.js +1 -0
- package/ui/dist/assets/{rocket-DhvUetsk.js → rocket--8ZHgdXJ.js} +1 -1
- package/ui/dist/assets/select-n108rXny.js +1 -0
- package/ui/dist/assets/{send-P0r5D7td.js → send-Cu7MR2Qh.js} +1 -1
- package/ui/dist/assets/server-DmodxZp-.js +1 -0
- package/ui/dist/assets/{settings-2-ocj5uHGx.js → settings-2-CkRNqkxj.js} +1 -1
- package/ui/dist/assets/sheet-7aUJkyzU.js +1 -0
- package/ui/dist/assets/{shield-check-DfVdE34l.js → shield-check-ViI3nMKE.js} +1 -1
- package/ui/dist/assets/{shield-off-8l0J6R-8.js → shield-off-DN3tagkn.js} +1 -1
- package/ui/dist/assets/skeleton-C0E1Nfro.js +1 -0
- package/ui/dist/assets/{smartphone-77_g3SQn.js → smartphone-5FghiXpA.js} +1 -1
- package/ui/dist/assets/{square-Ckzsr3Rn.js → square-DiNSx8K7.js} +1 -1
- package/ui/dist/assets/star-DhdFVidS.js +1 -0
- package/ui/dist/assets/switch-CIgVbZqQ.js +1 -0
- package/ui/dist/assets/table-BC56FVMV.js +1 -0
- package/ui/dist/assets/{tag-C35mgoEv.js → tag-CH_vQliw.js} +1 -1
- package/ui/dist/assets/textarea-CxDiKFXZ.js +1 -0
- package/ui/dist/assets/{timer-DHJBS2w1.js → timer-CdGVTb60.js} +1 -1
- package/ui/dist/assets/tooltip-BuW9A5UO.js +1 -0
- package/ui/dist/assets/{trash-2-keO5tKPE.js → trash-2-CucZJL0N.js} +1 -1
- package/ui/dist/assets/trending-down-BCezC1z2.js +1 -0
- package/ui/dist/assets/{trending-up-BBv8KbrY.js → trending-up-C5OYX2k2.js} +1 -1
- package/ui/dist/assets/vendor-query-C0p7b53x.js +4 -0
- package/ui/dist/assets/vendor-react-Mc5_kfYG.js +12 -0
- package/ui/dist/assets/vendor-ui-CXPAUBFv.js +51 -0
- package/ui/dist/assets/{wand-sparkles-BusQ52ZK.js → wand-sparkles-BaH6pJnc.js} +1 -1
- package/ui/dist/assets/{wrench-02YaOSiK.js → wrench-CjxjP6ok.js} +1 -1
- package/ui/dist/index.html +5 -2
- package/ui/dist/assets/ActivityView-BeshZXmE.js +0 -1
- package/ui/dist/assets/AgentList-QVHeldPi.js +0 -1
- package/ui/dist/assets/AnalyticsDashboard-C9R97dXE.js +0 -1
- package/ui/dist/assets/AreaChart-B73gaiVQ.js +0 -1
- package/ui/dist/assets/CartesianChart-CXYL2R-A.js +0 -36
- package/ui/dist/assets/ChatView-qjZErlrp.js +0 -10
- package/ui/dist/assets/CostsDashboard-O4DCLy1i.js +0 -1
- package/ui/dist/assets/EstimateSelect-1hQf4Osk.js +0 -1
- package/ui/dist/assets/FloatingChatbot-BZBzrJxd.js +0 -2
- package/ui/dist/assets/InviteCodeManagement-LEoGqYeA.js +0 -2
- package/ui/dist/assets/ProjectIcon-Chd_ofsw.js +0 -1
- package/ui/dist/assets/ProjectList-BvUfVB6c.js +0 -4
- package/ui/dist/assets/StatusIndicator-pRfkNcdV.js +0 -1
- package/ui/dist/assets/SummaryList-B6kXiTxL.js +0 -1
- package/ui/dist/assets/TaskDetail-CV6CzbOS.js +0 -1
- package/ui/dist/assets/TaskList-DL7brQKd.js +0 -1
- package/ui/dist/assets/TicketBoard-CrkkFj7C.js +0 -1
- package/ui/dist/assets/TicketDetail-hnnYclpD.js +0 -1
- package/ui/dist/assets/TicketList-CsDAyQCL.js +0 -1
- package/ui/dist/assets/UserManagement-BGFQyTSr.js +0 -2
- package/ui/dist/assets/ViewSwitcher-CnL0OqA8.js +0 -1
- package/ui/dist/assets/alert-dialog-SKM6Gjz4.js +0 -7
- package/ui/dist/assets/badge-CVHH1a-v.js +0 -1
- package/ui/dist/assets/brain-6o_RHVpe.js +0 -1
- package/ui/dist/assets/constants-Q5Zivl-a.js +0 -1
- package/ui/dist/assets/dialog-BUqN9Psj.js +0 -1
- package/ui/dist/assets/index-BUmnwPQr.js +0 -1
- package/ui/dist/assets/index-BfF5G4Cw.js +0 -1
- package/ui/dist/assets/index-C8N375c2.js +0 -1
- package/ui/dist/assets/index-CuxnqVVz.css +0 -1
- package/ui/dist/assets/index-CzMM3QOk.js +0 -1
- package/ui/dist/assets/index-lJlNPFVJ.js +0 -67
- package/ui/dist/assets/layers-jFqVrWMD.js +0 -1
- package/ui/dist/assets/markdown-renderer-n1ToC4XQ.js +0 -36
- package/ui/dist/assets/popover-CrmZgoWu.js +0 -1
- package/ui/dist/assets/progress-uv4SPkL5.js +0 -1
- package/ui/dist/assets/select-CeQ8AHGy.js +0 -1
- package/ui/dist/assets/server-CVHTZB72.js +0 -1
- package/ui/dist/assets/sheet-DuQExSho.js +0 -1
- package/ui/dist/assets/skeleton-TFiFJ3nB.js +0 -1
- package/ui/dist/assets/switch-CAePkd6k.js +0 -1
- package/ui/dist/assets/table-ZjAZ7hkt.js +0 -1
- package/ui/dist/assets/textarea-DsVPnSgR.js +0 -1
- package/ui/dist/assets/tooltip-BYmQ331W.js +0 -1
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checkpoint Manager
|
|
3
|
+
*
|
|
4
|
+
* Saves and restores executor state so long-running agentic sessions can be
|
|
5
|
+
* interrupted and resumed without losing progress. Checkpoints live at
|
|
6
|
+
* .profclaw/checkpoints/<sessionId>.json relative to the project root (or the
|
|
7
|
+
* current working directory when no root is supplied).
|
|
8
|
+
*/
|
|
9
|
+
import { mkdir, readFile, writeFile, unlink, readdir } from 'node:fs/promises';
|
|
10
|
+
import { existsSync } from 'node:fs';
|
|
11
|
+
import { join, resolve } from 'node:path';
|
|
12
|
+
import { logger } from '../utils/logger.js';
|
|
13
|
+
// ─── CheckpointManager ────────────────────────────────────────────────────────
|
|
14
|
+
export class CheckpointManager {
|
|
15
|
+
checkpointsDir;
|
|
16
|
+
constructor(projectRoot) {
|
|
17
|
+
const root = projectRoot ? resolve(projectRoot) : process.cwd();
|
|
18
|
+
this.checkpointsDir = join(root, '.profclaw', 'checkpoints');
|
|
19
|
+
}
|
|
20
|
+
// ── Private helpers ──────────────────────────────────────────────────────
|
|
21
|
+
filePath(sessionId) {
|
|
22
|
+
return join(this.checkpointsDir, `${sessionId}.json`);
|
|
23
|
+
}
|
|
24
|
+
async ensureDir() {
|
|
25
|
+
if (!existsSync(this.checkpointsDir)) {
|
|
26
|
+
await mkdir(this.checkpointsDir, { recursive: true });
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// ── Public API ───────────────────────────────────────────────────────────
|
|
30
|
+
/**
|
|
31
|
+
* Persist a checkpoint to disk. Creates .profclaw/checkpoints/ if needed.
|
|
32
|
+
*/
|
|
33
|
+
async save(checkpoint) {
|
|
34
|
+
await this.ensureDir();
|
|
35
|
+
const path = this.filePath(checkpoint.sessionId);
|
|
36
|
+
const payload = JSON.stringify({ ...checkpoint, updatedAt: Date.now() }, null, 2);
|
|
37
|
+
await writeFile(path, payload, 'utf-8');
|
|
38
|
+
logger.debug('[CheckpointManager] Saved checkpoint', {
|
|
39
|
+
sessionId: checkpoint.sessionId,
|
|
40
|
+
step: checkpoint.currentStep,
|
|
41
|
+
path,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Load a previously saved checkpoint. Returns null when none exists.
|
|
46
|
+
*/
|
|
47
|
+
async load(sessionId) {
|
|
48
|
+
const path = this.filePath(sessionId);
|
|
49
|
+
try {
|
|
50
|
+
const raw = await readFile(path, 'utf-8');
|
|
51
|
+
const parsed = JSON.parse(raw);
|
|
52
|
+
logger.debug('[CheckpointManager] Loaded checkpoint', {
|
|
53
|
+
sessionId,
|
|
54
|
+
step: parsed.currentStep,
|
|
55
|
+
});
|
|
56
|
+
return parsed;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* List all checkpoints, sorted newest first.
|
|
64
|
+
*/
|
|
65
|
+
async list() {
|
|
66
|
+
if (!existsSync(this.checkpointsDir))
|
|
67
|
+
return [];
|
|
68
|
+
let files;
|
|
69
|
+
try {
|
|
70
|
+
files = await readdir(this.checkpointsDir);
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
return [];
|
|
74
|
+
}
|
|
75
|
+
const summaries = [];
|
|
76
|
+
for (const file of files) {
|
|
77
|
+
if (!file.endsWith('.json'))
|
|
78
|
+
continue;
|
|
79
|
+
try {
|
|
80
|
+
const raw = await readFile(join(this.checkpointsDir, file), 'utf-8');
|
|
81
|
+
const cp = JSON.parse(raw);
|
|
82
|
+
summaries.push({
|
|
83
|
+
sessionId: cp.sessionId,
|
|
84
|
+
taskDescription: cp.taskDescription,
|
|
85
|
+
step: cp.currentStep,
|
|
86
|
+
updatedAt: cp.updatedAt,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
// Skip malformed files
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return summaries.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Delete a checkpoint after the session has completed successfully.
|
|
97
|
+
*/
|
|
98
|
+
async remove(sessionId) {
|
|
99
|
+
const path = this.filePath(sessionId);
|
|
100
|
+
try {
|
|
101
|
+
await unlink(path);
|
|
102
|
+
logger.debug('[CheckpointManager] Removed checkpoint', { sessionId });
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
// Already gone — not an error
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Find a resumable checkpoint whose taskDescription loosely matches the
|
|
110
|
+
* given description (case-insensitive substring + word overlap heuristic).
|
|
111
|
+
* Returns the most recently updated match, or null if nothing qualifies.
|
|
112
|
+
*/
|
|
113
|
+
async findResumable(taskDescription) {
|
|
114
|
+
const all = await this.list();
|
|
115
|
+
if (all.length === 0)
|
|
116
|
+
return null;
|
|
117
|
+
const needle = taskDescription.toLowerCase();
|
|
118
|
+
const needleWords = new Set(needle.split(/\W+/).filter(Boolean));
|
|
119
|
+
let bestScore = 0;
|
|
120
|
+
let bestId = null;
|
|
121
|
+
for (const summary of all) {
|
|
122
|
+
if (!summary.taskDescription)
|
|
123
|
+
continue;
|
|
124
|
+
const hay = summary.taskDescription.toLowerCase();
|
|
125
|
+
// Substring match is a strong signal
|
|
126
|
+
if (hay.includes(needle) || needle.includes(hay)) {
|
|
127
|
+
// Prefer the most recently updated substring match
|
|
128
|
+
if (summary.updatedAt > (bestScore === 2 ? 0 : -1)) {
|
|
129
|
+
bestScore = 2;
|
|
130
|
+
bestId = summary.sessionId;
|
|
131
|
+
}
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
// Word-overlap fallback
|
|
135
|
+
const hayWords = hay.split(/\W+/).filter(Boolean);
|
|
136
|
+
const overlap = hayWords.filter((w) => needleWords.has(w)).length;
|
|
137
|
+
const ratio = needleWords.size > 0 ? overlap / needleWords.size : 0;
|
|
138
|
+
if (ratio >= 0.5 && ratio > bestScore) {
|
|
139
|
+
bestScore = ratio;
|
|
140
|
+
bestId = summary.sessionId;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
if (!bestId)
|
|
144
|
+
return null;
|
|
145
|
+
return this.load(bestId);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// ─── Singleton ────────────────────────────────────────────────────────────────
|
|
149
|
+
let _instance;
|
|
150
|
+
export function getCheckpointManager(projectRoot) {
|
|
151
|
+
if (!_instance) {
|
|
152
|
+
_instance = new CheckpointManager(projectRoot);
|
|
153
|
+
}
|
|
154
|
+
return _instance;
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=checkpoint-manager.js.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Circuit Breaker
|
|
3
|
+
*
|
|
4
|
+
* Prevents tools from being called repeatedly when they are failing.
|
|
5
|
+
* Implements the standard circuit breaker pattern:
|
|
6
|
+
* closed → (3 failures in 2 min) → open → (cooldown expires) → half-open
|
|
7
|
+
* half-open → (1 success) → closed
|
|
8
|
+
* half-open → (1 failure) → open (doubled cooldown)
|
|
9
|
+
*/
|
|
10
|
+
export type CircuitBreakerStateValue = 'closed' | 'open' | 'half-open';
|
|
11
|
+
export interface CircuitBreakerState {
|
|
12
|
+
state: CircuitBreakerStateValue;
|
|
13
|
+
failureCount: number;
|
|
14
|
+
lastFailureAt: number;
|
|
15
|
+
cooldownMs: number;
|
|
16
|
+
}
|
|
17
|
+
export interface CanExecuteResult {
|
|
18
|
+
allowed: boolean;
|
|
19
|
+
reason?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare class ToolCircuitBreaker {
|
|
22
|
+
private breakers;
|
|
23
|
+
private readonly failureThreshold;
|
|
24
|
+
private readonly windowMs;
|
|
25
|
+
constructor(failureThreshold?: number, windowMs?: number);
|
|
26
|
+
/**
|
|
27
|
+
* Check whether a tool is allowed to execute.
|
|
28
|
+
* Transitions open → half-open when the cooldown has expired.
|
|
29
|
+
*/
|
|
30
|
+
canExecute(toolName: string): CanExecuteResult;
|
|
31
|
+
/**
|
|
32
|
+
* Record a successful tool execution.
|
|
33
|
+
* In half-open state this closes the circuit.
|
|
34
|
+
*/
|
|
35
|
+
recordSuccess(toolName: string): void;
|
|
36
|
+
/**
|
|
37
|
+
* Record a failed tool execution.
|
|
38
|
+
* Counts failures within the time window and trips the breaker when the
|
|
39
|
+
* threshold is reached. In half-open state it immediately re-opens with
|
|
40
|
+
* a doubled cooldown.
|
|
41
|
+
*/
|
|
42
|
+
recordFailure(toolName: string): void;
|
|
43
|
+
/**
|
|
44
|
+
* Reset the circuit breaker for a specific tool, or all tools if no name is given.
|
|
45
|
+
*/
|
|
46
|
+
reset(toolName?: string): void;
|
|
47
|
+
/**
|
|
48
|
+
* Return a deep snapshot of all breaker states.
|
|
49
|
+
* Mutations to the live breakers do not affect the returned map.
|
|
50
|
+
*/
|
|
51
|
+
getStatus(): Map<string, CircuitBreakerState>;
|
|
52
|
+
private getOrCreate;
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=circuit-breaker.d.ts.map
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tool Circuit Breaker
|
|
3
|
+
*
|
|
4
|
+
* Prevents tools from being called repeatedly when they are failing.
|
|
5
|
+
* Implements the standard circuit breaker pattern:
|
|
6
|
+
* closed → (3 failures in 2 min) → open → (cooldown expires) → half-open
|
|
7
|
+
* half-open → (1 success) → closed
|
|
8
|
+
* half-open → (1 failure) → open (doubled cooldown)
|
|
9
|
+
*/
|
|
10
|
+
import { logger } from '../utils/logger.js';
|
|
11
|
+
// Constants
|
|
12
|
+
const DEFAULT_FAILURE_THRESHOLD = 3;
|
|
13
|
+
const DEFAULT_WINDOW_MS = 120_000; // 2 minutes
|
|
14
|
+
const INITIAL_COOLDOWN_MS = 5_000;
|
|
15
|
+
const MAX_COOLDOWN_MS = 60_000;
|
|
16
|
+
function defaultBreakerState() {
|
|
17
|
+
return {
|
|
18
|
+
state: 'closed',
|
|
19
|
+
failureCount: 0,
|
|
20
|
+
lastFailureAt: 0,
|
|
21
|
+
cooldownMs: INITIAL_COOLDOWN_MS,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
// Circuit Breaker
|
|
25
|
+
export class ToolCircuitBreaker {
|
|
26
|
+
breakers;
|
|
27
|
+
failureThreshold;
|
|
28
|
+
windowMs;
|
|
29
|
+
constructor(failureThreshold = DEFAULT_FAILURE_THRESHOLD, windowMs = DEFAULT_WINDOW_MS) {
|
|
30
|
+
this.breakers = new Map();
|
|
31
|
+
this.failureThreshold = failureThreshold;
|
|
32
|
+
this.windowMs = windowMs;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Check whether a tool is allowed to execute.
|
|
36
|
+
* Transitions open → half-open when the cooldown has expired.
|
|
37
|
+
*/
|
|
38
|
+
canExecute(toolName) {
|
|
39
|
+
const breaker = this.getOrCreate(toolName);
|
|
40
|
+
const now = Date.now();
|
|
41
|
+
if (breaker.state === 'closed') {
|
|
42
|
+
return { allowed: true };
|
|
43
|
+
}
|
|
44
|
+
if (breaker.state === 'open') {
|
|
45
|
+
const elapsed = now - breaker.lastFailureAt;
|
|
46
|
+
if (elapsed >= breaker.cooldownMs) {
|
|
47
|
+
// Transition to half-open to allow a probe call
|
|
48
|
+
breaker.state = 'half-open';
|
|
49
|
+
logger.debug('[CircuitBreaker] Transitioning to half-open', {
|
|
50
|
+
tool: toolName,
|
|
51
|
+
elapsed,
|
|
52
|
+
cooldownMs: breaker.cooldownMs,
|
|
53
|
+
});
|
|
54
|
+
return { allowed: true };
|
|
55
|
+
}
|
|
56
|
+
const remainingMs = breaker.cooldownMs - elapsed;
|
|
57
|
+
return {
|
|
58
|
+
allowed: false,
|
|
59
|
+
reason: `Circuit breaker open for ${toolName}: too many recent failures. Retry in ${Math.ceil(remainingMs / 1000)}s.`,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// half-open: allow one probe through
|
|
63
|
+
return { allowed: true };
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Record a successful tool execution.
|
|
67
|
+
* In half-open state this closes the circuit.
|
|
68
|
+
*/
|
|
69
|
+
recordSuccess(toolName) {
|
|
70
|
+
const breaker = this.getOrCreate(toolName);
|
|
71
|
+
if (breaker.state === 'half-open') {
|
|
72
|
+
logger.info('[CircuitBreaker] Probe succeeded, closing circuit', { tool: toolName });
|
|
73
|
+
breaker.state = 'closed';
|
|
74
|
+
breaker.failureCount = 0;
|
|
75
|
+
breaker.cooldownMs = INITIAL_COOLDOWN_MS;
|
|
76
|
+
}
|
|
77
|
+
else if (breaker.state === 'closed') {
|
|
78
|
+
// Reset failure count on success within the window
|
|
79
|
+
breaker.failureCount = 0;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Record a failed tool execution.
|
|
84
|
+
* Counts failures within the time window and trips the breaker when the
|
|
85
|
+
* threshold is reached. In half-open state it immediately re-opens with
|
|
86
|
+
* a doubled cooldown.
|
|
87
|
+
*/
|
|
88
|
+
recordFailure(toolName) {
|
|
89
|
+
const breaker = this.getOrCreate(toolName);
|
|
90
|
+
const now = Date.now();
|
|
91
|
+
if (breaker.state === 'half-open') {
|
|
92
|
+
// Probe failed — re-open with doubled cooldown
|
|
93
|
+
breaker.cooldownMs = Math.min(breaker.cooldownMs * 2, MAX_COOLDOWN_MS);
|
|
94
|
+
breaker.state = 'open';
|
|
95
|
+
breaker.lastFailureAt = now;
|
|
96
|
+
logger.warn('[CircuitBreaker] Probe failed, re-opening circuit', {
|
|
97
|
+
tool: toolName,
|
|
98
|
+
cooldownMs: breaker.cooldownMs,
|
|
99
|
+
});
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
// In closed state, check if previous failures are still within the window
|
|
103
|
+
const withinWindow = breaker.lastFailureAt > 0 && now - breaker.lastFailureAt <= this.windowMs;
|
|
104
|
+
if (withinWindow) {
|
|
105
|
+
breaker.failureCount++;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
// Failures outside the window don't count; start a fresh count
|
|
109
|
+
breaker.failureCount = 1;
|
|
110
|
+
}
|
|
111
|
+
breaker.lastFailureAt = now;
|
|
112
|
+
if (breaker.failureCount >= this.failureThreshold) {
|
|
113
|
+
breaker.state = 'open';
|
|
114
|
+
logger.warn('[CircuitBreaker] Threshold reached, opening circuit', {
|
|
115
|
+
tool: toolName,
|
|
116
|
+
failureCount: breaker.failureCount,
|
|
117
|
+
cooldownMs: breaker.cooldownMs,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Reset the circuit breaker for a specific tool, or all tools if no name is given.
|
|
123
|
+
*/
|
|
124
|
+
reset(toolName) {
|
|
125
|
+
if (toolName !== undefined) {
|
|
126
|
+
this.breakers.set(toolName, defaultBreakerState());
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
this.breakers.clear();
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Return a deep snapshot of all breaker states.
|
|
134
|
+
* Mutations to the live breakers do not affect the returned map.
|
|
135
|
+
*/
|
|
136
|
+
getStatus() {
|
|
137
|
+
const snapshot = new Map();
|
|
138
|
+
for (const [key, value] of this.breakers) {
|
|
139
|
+
snapshot.set(key, { ...value });
|
|
140
|
+
}
|
|
141
|
+
return snapshot;
|
|
142
|
+
}
|
|
143
|
+
// Private helpers
|
|
144
|
+
getOrCreate(toolName) {
|
|
145
|
+
let breaker = this.breakers.get(toolName);
|
|
146
|
+
if (!breaker) {
|
|
147
|
+
breaker = defaultBreakerState();
|
|
148
|
+
this.breakers.set(toolName, breaker);
|
|
149
|
+
}
|
|
150
|
+
return breaker;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=circuit-breaker.js.map
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context Compactor
|
|
3
|
+
*
|
|
4
|
+
* Compresses old conversation turns into a structured markdown summary when
|
|
5
|
+
* the estimated token count crosses a configurable threshold.
|
|
6
|
+
*
|
|
7
|
+
* Two modes:
|
|
8
|
+
* - Local heuristic (default): pure extraction, no LLM calls.
|
|
9
|
+
* - LLM-powered (opt-in): uses an injected apiCall function to produce a
|
|
10
|
+
* richer natural-language summary.
|
|
11
|
+
*/
|
|
12
|
+
import type { ModelMessage } from "ai";
|
|
13
|
+
export interface CompactionConfig {
|
|
14
|
+
/** Total token budget for the context window. Default: 100_000 */
|
|
15
|
+
maxContextTokens: number;
|
|
16
|
+
/** Trigger compaction once estimated tokens exceed this value. Default: 70_000 */
|
|
17
|
+
compactionThreshold: number;
|
|
18
|
+
/** Number of most-recent turns (user+assistant pairs) to preserve verbatim. Default: 5 */
|
|
19
|
+
preserveRecentTurns: number;
|
|
20
|
+
/** Maximum tokens for the generated summary message. Default: 2_000 */
|
|
21
|
+
summaryMaxTokens: number;
|
|
22
|
+
/**
|
|
23
|
+
* When true, `compact()` will delegate to `compactWithLLM()` if an
|
|
24
|
+
* `apiCall` function is provided at call time. Default: false.
|
|
25
|
+
*/
|
|
26
|
+
useLLM?: boolean;
|
|
27
|
+
/** Cheap model to use for LLM summarisation (e.g. 'llama3.2'). */
|
|
28
|
+
summaryModel?: string;
|
|
29
|
+
/** Provider for the summarisation model (e.g. 'ollama'). */
|
|
30
|
+
summaryProvider?: string;
|
|
31
|
+
}
|
|
32
|
+
export interface CompactionResult {
|
|
33
|
+
messages: ModelMessage[];
|
|
34
|
+
compacted: boolean;
|
|
35
|
+
originalTokens: number;
|
|
36
|
+
compactedTokens: number;
|
|
37
|
+
turnsCompacted: number;
|
|
38
|
+
}
|
|
39
|
+
export declare class ContextCompactor {
|
|
40
|
+
private config;
|
|
41
|
+
constructor(config?: Partial<CompactionConfig>);
|
|
42
|
+
/**
|
|
43
|
+
* Estimate the token count for a list of messages using the 4-chars-per-token
|
|
44
|
+
* heuristic.
|
|
45
|
+
*/
|
|
46
|
+
estimateTokens(messages: ModelMessage[]): number;
|
|
47
|
+
/**
|
|
48
|
+
* Compact the message list if it exceeds the compaction threshold.
|
|
49
|
+
*
|
|
50
|
+
* Strategy:
|
|
51
|
+
* 1. Identify the most-recent N turns to preserve verbatim.
|
|
52
|
+
* 2. Summarise all older messages into a single system-role summary message.
|
|
53
|
+
* 3. Return the summary + preserved recent messages.
|
|
54
|
+
*
|
|
55
|
+
* When `config.useLLM` is true and `apiCall` is provided, delegates to
|
|
56
|
+
* `compactWithLLM()` for a richer natural-language summary.
|
|
57
|
+
* Falls back to local heuristic summarisation if the LLM call fails.
|
|
58
|
+
*/
|
|
59
|
+
compact(messages: ModelMessage[], apiCall?: (prompt: string) => Promise<string>): Promise<CompactionResult>;
|
|
60
|
+
/**
|
|
61
|
+
* Compact using an injected LLM call for richer summarisation.
|
|
62
|
+
*
|
|
63
|
+
* The `apiCall` function is supplied by the caller so this class remains
|
|
64
|
+
* free of any specific API client dependency.
|
|
65
|
+
*/
|
|
66
|
+
compactWithLLM(messages: ModelMessage[], apiCall: (prompt: string) => Promise<string>): Promise<CompactionResult>;
|
|
67
|
+
/** Local heuristic compaction (no LLM). */
|
|
68
|
+
private _compactLocal;
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=context-compactor.d.ts.map
|