mia-code 0.2.0 → 0.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/.miette/260321.md +1 -0
- package/.miette/260323.md +9 -0
- package/.miette/260331.md +2 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/2604020008--d3417f2c-df12-4f0f-8a1b-d88e7968f822/d3417f2c-df12-4f0f-8a1b-d88e7968f822.md +63 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/2604020008--e6c3fc5d-4a70-4523-ba7d-a3250da4c235/e6c3fc5d-4a70-4523-ba7d-a3250da4c235.md +72 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/2604020008--efeb00a2-b17a-4d32-b1f0-b90c37a8d24e/efeb00a2-b17a-4d32-b1f0-b90c37a8d24e.md +62 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/83a2d7f9-24a5-4cf4-98d5-036c82f872e8.json +302 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/83a2d7f9-24a5-4cf4-98d5-036c82f872e8.md +149 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/AGENTS.md +31 -0
- package/.pde/2604011511--83a2d7f9-24a5-4cf4-98d5-036c82f872e8/meta-decomposition-3-children.md +67 -0
- package/.pde/2604040129--61f9dd4d-7aa6-45e6-a58b-e480b1aa6737/61f9dd4d-7aa6-45e6-a58b-e480b1aa6737--from-mia-openclaw-workspace.md +125 -0
- package/.pde/2604040129--61f9dd4d-7aa6-45e6-a58b-e480b1aa6737/STATUS.md +1 -0
- package/.pde/4f02ba94-9f52-422e-9389-b16f9b37f358.json +177 -0
- package/.pde/4f02ba94-9f52-422e-9389-b16f9b37f358.md +77 -0
- package/.pde/6ad9244d-5340-490f-b76c-c86728b9de52.json +222 -0
- package/.pde/6ad9244d-5340-490f-b76c-c86728b9de52.md +99 -0
- package/.pde/8b566792-ed15-4606-96f9-2b6f593d7e6b.json +111 -0
- package/.pde/8b566792-ed15-4606-96f9-2b6f593d7e6b.md +67 -0
- package/.pde/c7f1e74b-05a5-40e2-9f01-4cc48d2528f7.json +349 -0
- package/.pde/c7f1e74b-05a5-40e2-9f01-4cc48d2528f7.md +147 -0
- package/.pde/dfc00a78-1da0-4c09-8a16-c6982644051b.json +118 -0
- package/.pde/dfc00a78-1da0-4c09-8a16-c6982644051b.md +64 -0
- package/GUILLAUME.md +8 -0
- package/KINSHIP.md +9 -0
- package/MIA_CODE_ARCHITECTURE_REPORT.md +718 -0
- package/contextual_research/260119-MIA-CODE--98090899-8aff-4e11-9dc3-8b99466d1.md +1101 -0
- package/contextual_research/MIA.md +38 -0
- package/contextual_research/MIAWAPASCONE.md +59 -0
- package/contextual_research/MIETTE.md +38 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/2504.00218v2.pdf +7483 -12
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/2505.00212v3.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/CONTENT.md +1014 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/DESIGN.gemini.md +242 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/INDEX.md +45 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/2504.00218v2.md +2025 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/2504.00218v2.pdf +7483 -12
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/2505.00212v3.md +1755 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/2505.00212v3.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_12_decomposed_prompting.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_19_hugginggpt_planning.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_1_coordination_challenges.md +766 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_1_coordination_challenges.pdf +3431 -4
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_28_guardrails_multi_agent.md +260 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_28_guardrails_multi_agent.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_2_navigating_complexity.md +558 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_2_navigating_complexity.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_34_hierarchical_multi_agent.pdf +0 -0
- package/contextual_research/PDE-generalization--caefee82-efb1-4dbb-8733-691b01581464--260130/sources/footnote_1_5_open_intent_extraction.pdf +0 -0
- package/contextual_research/PODCAST.md +109 -0
- package/contextual_research/langchain-principles-roadmap.md +157 -0
- package/contextual_research/persona-to-narrative-character-inquiry_260201.md +50 -0
- package/dist/cli.js +35 -11
- package/dist/geminiHeadless.js +8 -2
- package/dist/index.js +2 -1
- package/dist/mcp/miaco-server.js +10 -1
- package/dist/mcp/miatel-server.js +10 -1
- package/dist/mcp/miawa-server.js +10 -1
- package/dist/mcp/utils.d.ts +6 -1
- package/dist/mcp/utils.js +24 -3
- package/dist/sessionStore.d.ts +8 -2
- package/dist/sessionStore.js +39 -3
- package/dist/types.d.ts +1 -0
- package/miaco/README.md +124 -0
- package/miaco/dist/commands/chart.d.ts +6 -0
- package/miaco/dist/commands/chart.d.ts.map +1 -0
- package/miaco/dist/commands/chart.js +222 -0
- package/miaco/dist/commands/chart.js.map +1 -0
- package/miaco/dist/commands/decompose.d.ts +6 -0
- package/miaco/dist/commands/decompose.d.ts.map +1 -0
- package/miaco/dist/commands/decompose.js +98 -0
- package/miaco/dist/commands/decompose.js.map +1 -0
- package/miaco/dist/commands/schema.d.ts +6 -0
- package/miaco/dist/commands/schema.d.ts.map +1 -0
- package/miaco/dist/commands/schema.js +66 -0
- package/miaco/dist/commands/schema.js.map +1 -0
- package/miaco/dist/commands/stc.d.ts +11 -0
- package/miaco/dist/commands/stc.d.ts.map +1 -0
- package/miaco/dist/commands/stc.js +590 -0
- package/miaco/dist/commands/stc.js.map +1 -0
- package/miaco/dist/commands/trace.d.ts +6 -0
- package/miaco/dist/commands/trace.d.ts.map +1 -0
- package/miaco/dist/commands/trace.js +83 -0
- package/miaco/dist/commands/trace.js.map +1 -0
- package/miaco/dist/commands/validate.d.ts +6 -0
- package/miaco/dist/commands/validate.d.ts.map +1 -0
- package/miaco/dist/commands/validate.js +58 -0
- package/miaco/dist/commands/validate.js.map +1 -0
- package/miaco/dist/decompose.d.ts +93 -0
- package/miaco/dist/decompose.d.ts.map +1 -0
- package/miaco/dist/decompose.js +562 -0
- package/miaco/dist/decompose.js.map +1 -0
- package/miaco/dist/index.d.ts +18 -0
- package/miaco/dist/index.d.ts.map +1 -0
- package/miaco/dist/index.js +83 -0
- package/miaco/dist/index.js.map +1 -0
- package/miaco/dist/storage.d.ts +60 -0
- package/miaco/dist/storage.d.ts.map +1 -0
- package/miaco/dist/storage.js +100 -0
- package/miaco/dist/storage.js.map +1 -0
- package/miaco/package-lock.json +4103 -0
- package/miaco/package.json +40 -0
- package/miaco/tsconfig.json +18 -0
- package/miaco/version-patch-commit-and-publish.sh +1 -0
- package/miatel/MISSION_251231.md +3 -0
- package/miatel/README.md +107 -0
- package/miatel/dist/commands/analyze.d.ts +6 -0
- package/miatel/dist/commands/analyze.d.ts.map +1 -0
- package/miatel/dist/commands/analyze.js +100 -0
- package/miatel/dist/commands/analyze.js.map +1 -0
- package/miatel/dist/commands/arc.d.ts +6 -0
- package/miatel/dist/commands/arc.d.ts.map +1 -0
- package/miatel/dist/commands/arc.js +71 -0
- package/miatel/dist/commands/arc.js.map +1 -0
- package/miatel/dist/commands/beat.d.ts +6 -0
- package/miatel/dist/commands/beat.d.ts.map +1 -0
- package/miatel/dist/commands/beat.js +165 -0
- package/miatel/dist/commands/beat.js.map +1 -0
- package/miatel/dist/commands/theme.d.ts +6 -0
- package/miatel/dist/commands/theme.d.ts.map +1 -0
- package/miatel/dist/commands/theme.js +54 -0
- package/miatel/dist/commands/theme.js.map +1 -0
- package/miatel/dist/index.d.ts +18 -0
- package/miatel/dist/index.d.ts.map +1 -0
- package/miatel/dist/index.js +80 -0
- package/miatel/dist/index.js.map +1 -0
- package/miatel/dist/storage.d.ts +55 -0
- package/miatel/dist/storage.d.ts.map +1 -0
- package/miatel/dist/storage.js +100 -0
- package/miatel/dist/storage.js.map +1 -0
- package/miatel/package-lock.json +4103 -0
- package/miatel/package.json +35 -0
- package/miatel/src/commands/analyze.ts +109 -0
- package/miatel/src/commands/arc.ts +78 -0
- package/miatel/src/commands/beat.ts +176 -0
- package/miatel/src/commands/theme.ts +60 -0
- package/miatel/src/index.ts +94 -0
- package/miatel/src/storage.ts +156 -0
- package/miatel/tsconfig.json +18 -0
- package/miawa/MISSION_251231.md +144 -0
- package/miawa/README.md +133 -0
- package/miawa/dist/commands/beat.d.ts +6 -0
- package/miawa/dist/commands/beat.d.ts.map +1 -0
- package/miawa/dist/commands/beat.js +69 -0
- package/miawa/dist/commands/beat.js.map +1 -0
- package/miawa/dist/commands/ceremony.d.ts +6 -0
- package/miawa/dist/commands/ceremony.d.ts.map +1 -0
- package/miawa/dist/commands/ceremony.js +239 -0
- package/miawa/dist/commands/ceremony.js.map +1 -0
- package/miawa/dist/commands/circle.d.ts +6 -0
- package/miawa/dist/commands/circle.d.ts.map +1 -0
- package/miawa/dist/commands/circle.js +75 -0
- package/miawa/dist/commands/circle.js.map +1 -0
- package/miawa/dist/commands/eva.d.ts +6 -0
- package/miawa/dist/commands/eva.d.ts.map +1 -0
- package/miawa/dist/commands/eva.js +73 -0
- package/miawa/dist/commands/eva.js.map +1 -0
- package/miawa/dist/commands/wound.d.ts +6 -0
- package/miawa/dist/commands/wound.d.ts.map +1 -0
- package/miawa/dist/commands/wound.js +74 -0
- package/miawa/dist/commands/wound.js.map +1 -0
- package/miawa/dist/index.d.ts +19 -0
- package/miawa/dist/index.d.ts.map +1 -0
- package/miawa/dist/index.js +91 -0
- package/miawa/dist/index.js.map +1 -0
- package/miawa/dist/storage.d.ts +73 -0
- package/miawa/dist/storage.d.ts.map +1 -0
- package/miawa/dist/storage.js +100 -0
- package/miawa/dist/storage.js.map +1 -0
- package/miawa/package-lock.json +4103 -0
- package/miawa/package.json +36 -0
- package/miawa/src/commands/beat.ts +74 -0
- package/miawa/src/commands/ceremony.ts +256 -0
- package/miawa/src/commands/circle.ts +83 -0
- package/miawa/src/commands/eva.ts +84 -0
- package/miawa/src/commands/wound.ts +79 -0
- package/miawa/src/index.ts +108 -0
- package/miawa/src/storage.ts +179 -0
- package/miawa/tsconfig.json +18 -0
- package/package.json +7 -5
- package/references/acp/CLAUDE.md +7 -0
- package/references/acp/agent-plan.md +84 -0
- package/references/acp/clients.md +31 -0
- package/references/acp/extensibility.md +137 -0
- package/references/acp/initialization.md +225 -0
- package/references/acp/prompt-turn.md +321 -0
- package/references/acp/proxy-chains.md +562 -0
- package/references/acp/schema.md +3171 -0
- package/references/acp/session-list.md +334 -0
- package/references/acp/session-modes.md +170 -0
- package/references/acp/slash-commands.md +99 -0
- package/references/acp/terminals.md +281 -0
- package/references/acp/tool-calls.md +311 -0
- package/references/acp/typescript.md +29 -0
- package/references/claude/agent-teams.md +399 -0
- package/references/claude/chrome.md +231 -0
- package/references/claude/headless.md +158 -0
- package/references/claude/hooks-guide.md +708 -0
- package/references/claude/output-styles.md +112 -0
- package/references/claude/plugins.md +432 -0
- package/references/claude/skills.md +693 -0
- package/references/claude/sub-agents.md +816 -0
- package/references/copilot/acp/agents.md +32 -0
- package/references/copilot/acp/architecture.md +37 -0
- package/references/copilot/acp/clients.md +31 -0
- package/references/copilot/acp/introduction.md +42 -0
- package/references/copilot/acp/registry.md +339 -0
- package/references/copilot/acp-server.md +117 -0
- package/references/copilot/create-copilot-instructions.md +840 -0
- package/references/langchain/llms.txt +833 -0
- package/references/langchain/python/agents.md +677 -0
- package/references/langchain/python/context-engineering.md +1195 -0
- package/references/langchain/python/human-in-the-loop.md +326 -0
- package/references/langchain/python/long-term-memory.md +168 -0
- package/references/langchain/python/mcp.md +949 -0
- package/references/langchain/python/multi-agents/custom-workflow.md +187 -0
- package/references/langchain/python/multi-agents/handoffs.md +436 -0
- package/references/langchain/python/multi-agents/overview.md +295 -0
- package/references/langchain/python/multi-agents/router.md +150 -0
- package/references/langchain/python/multi-agents/skills.md +92 -0
- package/references/langchain/python/multi-agents/subagents.md +486 -0
- package/references/langchain/python/retrieval.md +320 -0
- package/references/langchain/python/runtime.md +141 -0
- package/references/langchain/python/short-term-memory.md +658 -0
- package/references/langchain/python/structured-output.md +712 -0
- package/references/langfuse/llms.txt +148 -0
- package/references/langgraph/javascript/llms.txt +275 -0
- package/references/skills/home.md +259 -0
- package/references/skills/integrate-skills.md +103 -0
- package/references/skills/specification.md +254 -0
- package/references/skills/what-are-skills.md +74 -0
- package/rispecs/README.md +164 -0
- package/rispecs/_sync_/miadi-code/SPEC.md +313 -0
- package/rispecs/_sync_/miadi-code/STATUS.md +177 -0
- package/rispecs/_sync_/miadi-code/dashboard/SPEC.md +465 -0
- package/rispecs/_sync_/miadi-code/dashboard/STATUS.md +212 -0
- package/rispecs/_sync_/miadi-code/multiline-input/SPEC.md +232 -0
- package/rispecs/_sync_/miadi-code/multiline-input/STATUS.md +108 -0
- package/rispecs/_sync_/miadi-code/pde/SPEC.md +253 -0
- package/rispecs/_sync_/miadi-code/pde/STATUS.md +56 -0
- package/rispecs/_sync_/miadi-code/stc/SPEC.md +397 -0
- package/rispecs/_sync_/miadi-code/stc/STATUS.md +70 -0
- package/rispecs/ava-langstack/inquiry-routing-upgrade.spec.md +119 -0
- package/rispecs/borrowed_from_opencode/001-client-server-architecture.rispec.md +98 -0
- package/rispecs/borrowed_from_opencode/002-event-bus-system.rispec.md +125 -0
- package/rispecs/borrowed_from_opencode/003-instance-state-pattern.rispec.md +136 -0
- package/rispecs/borrowed_from_opencode/004-namespace-module-pattern.rispec.md +151 -0
- package/rispecs/borrowed_from_opencode/005-zod-schema-validation.rispec.md +139 -0
- package/rispecs/borrowed_from_opencode/006-named-error-system.rispec.md +155 -0
- package/rispecs/borrowed_from_opencode/007-structured-logging.rispec.md +138 -0
- package/rispecs/borrowed_from_opencode/008-lazy-initialization.rispec.md +127 -0
- package/rispecs/borrowed_from_opencode/009-multi-agent-system.rispec.md +97 -0
- package/rispecs/borrowed_from_opencode/010-agent-definition-config.rispec.md +135 -0
- package/rispecs/borrowed_from_opencode/011-agent-permission-rulesets.rispec.md +151 -0
- package/rispecs/borrowed_from_opencode/012-agent-prompt-templates.rispec.md +141 -0
- package/rispecs/borrowed_from_opencode/013-agent-generation.rispec.md +142 -0
- package/rispecs/borrowed_from_opencode/014-plan-build-mode-toggle.rispec.md +155 -0
- package/rispecs/borrowed_from_opencode/015-subagent-task-delegation.rispec.md +146 -0
- package/rispecs/borrowed_from_opencode/016-agent-model-selection.rispec.md +151 -0
- package/rispecs/borrowed_from_opencode/017-compaction-agent.rispec.md +150 -0
- package/rispecs/borrowed_from_opencode/018-session-persistence.rispec.md +125 -0
- package/rispecs/borrowed_from_opencode/019-session-compaction.rispec.md +132 -0
- package/rispecs/borrowed_from_opencode/020-session-forking.rispec.md +134 -0
- package/rispecs/borrowed_from_opencode/021-session-revert-snapshot.rispec.md +135 -0
- package/rispecs/borrowed_from_opencode/022-session-sharing.rispec.md +165 -0
- package/rispecs/borrowed_from_opencode/023-session-summary-diffs.rispec.md +165 -0
- package/rispecs/borrowed_from_opencode/024-child-sessions.rispec.md +164 -0
- package/rispecs/borrowed_from_opencode/025-session-title-generation.rispec.md +162 -0
- package/rispecs/borrowed_from_opencode/026-message-parts-model.rispec.md +201 -0
- package/rispecs/borrowed_from_opencode/027-streaming-message-deltas.rispec.md +212 -0
- package/rispecs/borrowed_from_opencode/028-multi-provider-architecture.rispec.md +184 -0
- package/rispecs/borrowed_from_opencode/029-provider-authentication.rispec.md +225 -0
- package/rispecs/borrowed_from_opencode/030-model-registry.rispec.md +222 -0
- package/rispecs/borrowed_from_opencode/031-cost-tracking.rispec.md +243 -0
- package/rispecs/borrowed_from_opencode/032-provider-transform-pipeline.rispec.md +282 -0
- package/rispecs/borrowed_from_opencode/033-provider-sdk-abstraction.rispec.md +338 -0
- package/rispecs/borrowed_from_opencode/034-tool-registry.rispec.md +110 -0
- package/rispecs/borrowed_from_opencode/035-tool-context-injection.rispec.md +155 -0
- package/rispecs/borrowed_from_opencode/036-tool-output-truncation.rispec.md +138 -0
- package/rispecs/borrowed_from_opencode/037-batch-tool.rispec.md +129 -0
- package/rispecs/borrowed_from_opencode/038-multi-edit-tool.rispec.md +167 -0
- package/rispecs/borrowed_from_opencode/039-apply-patch-tool.rispec.md +161 -0
- package/rispecs/borrowed_from_opencode/040-code-search-tool.rispec.md +143 -0
- package/rispecs/borrowed_from_opencode/041-web-fetch-tool.rispec.md +131 -0
- package/rispecs/borrowed_from_opencode/042-web-search-tool.rispec.md +159 -0
- package/rispecs/borrowed_from_opencode/043-todo-tool.rispec.md +156 -0
- package/rispecs/borrowed_from_opencode/044-plan-mode-tool.rispec.md +139 -0
- package/rispecs/borrowed_from_opencode/045-task-tool.rispec.md +146 -0
- package/rispecs/borrowed_from_opencode/046-question-tool.rispec.md +170 -0
- package/rispecs/borrowed_from_opencode/047-external-directory-tool.rispec.md +166 -0
- package/rispecs/borrowed_from_opencode/048-file-read-write-tools.rispec.md +205 -0
- package/rispecs/borrowed_from_opencode/049-lsp-server-management.rispec.md +104 -0
- package/rispecs/borrowed_from_opencode/050-lsp-hover-completion.rispec.md +102 -0
- package/rispecs/borrowed_from_opencode/051-lsp-diagnostics.rispec.md +86 -0
- package/rispecs/borrowed_from_opencode/052-lsp-root-detection.rispec.md +109 -0
- package/rispecs/borrowed_from_opencode/053-remote-mcp-servers.rispec.md +119 -0
- package/rispecs/borrowed_from_opencode/054-mcp-oauth-flow.rispec.md +107 -0
- package/rispecs/borrowed_from_opencode/055-mcp-tool-conversion.rispec.md +118 -0
- package/rispecs/borrowed_from_opencode/056-mcp-connection-monitoring.rispec.md +106 -0
- package/rispecs/borrowed_from_opencode/057-local-mcp-servers.rispec.md +116 -0
- package/rispecs/borrowed_from_opencode/058-rich-tui.rispec.md +108 -0
- package/rispecs/borrowed_from_opencode/059-streaming-display.rispec.md +116 -0
- package/rispecs/borrowed_from_opencode/060-permission-prompts.rispec.md +130 -0
- package/rispecs/borrowed_from_opencode/061-session-navigation.rispec.md +155 -0
- package/rispecs/borrowed_from_opencode/062-syntax-highlighting.rispec.md +151 -0
- package/rispecs/borrowed_from_opencode/063-keybinding-system.rispec.md +181 -0
- package/rispecs/borrowed_from_opencode/064-multi-level-config.rispec.md +155 -0
- package/rispecs/borrowed_from_opencode/065-jsonc-config.rispec.md +190 -0
- package/rispecs/borrowed_from_opencode/066-config-env-variables.rispec.md +153 -0
- package/rispecs/borrowed_from_opencode/067-config-deep-merging.rispec.md +178 -0
- package/rispecs/borrowed_from_opencode/068-remote-org-config.rispec.md +183 -0
- package/rispecs/borrowed_from_opencode/069-config-markdown-frontmatter.rispec.md +206 -0
- package/rispecs/borrowed_from_opencode/070-managed-config-directory.rispec.md +232 -0
- package/rispecs/borrowed_from_opencode/071-plugin-architecture.rispec.md +104 -0
- package/rispecs/borrowed_from_opencode/072-plugin-hooks.rispec.md +123 -0
- package/rispecs/borrowed_from_opencode/073-plugin-auto-install.rispec.md +115 -0
- package/rispecs/borrowed_from_opencode/074-permission-system.rispec.md +133 -0
- package/rispecs/borrowed_from_opencode/075-git-worktree-management.rispec.md +126 -0
- package/rispecs/borrowed_from_opencode/076-snapshot-system.rispec.md +124 -0
- package/rispecs/borrowed_from_opencode/077-snapshot-diff.rispec.md +117 -0
- package/rispecs/borrowed_from_opencode/078-snapshot-restore.rispec.md +128 -0
- package/rispecs/borrowed_from_opencode/079-worktree-branch-naming.rispec.md +122 -0
- package/rispecs/borrowed_from_opencode/080-sqlite-storage.rispec.md +134 -0
- package/rispecs/borrowed_from_opencode/081-database-migrations.rispec.md +148 -0
- package/rispecs/borrowed_from_opencode/082-database-transactions.rispec.md +138 -0
- package/rispecs/borrowed_from_opencode/083-deferred-effects.rispec.md +148 -0
- package/rispecs/borrowed_from_opencode/084-permission-rules.rispec.md +123 -0
- package/rispecs/borrowed_from_opencode/085-permission-glob-patterns.rispec.md +113 -0
- package/rispecs/borrowed_from_opencode/086-permission-merging.rispec.md +134 -0
- package/rispecs/borrowed_from_opencode/087-permission-modes.rispec.md +145 -0
- package/rispecs/borrowed_from_opencode/088-http-api-server.rispec.md +165 -0
- package/rispecs/borrowed_from_opencode/089-openapi-spec-generation.rispec.md +164 -0
- package/rispecs/borrowed_from_opencode/090-websocket-support.rispec.md +136 -0
- package/rispecs/borrowed_from_opencode/091-sse-streaming.rispec.md +168 -0
- package/rispecs/borrowed_from_opencode/092-mdns-discovery.rispec.md +145 -0
- package/rispecs/borrowed_from_opencode/093-javascript-sdk.rispec.md +200 -0
- package/rispecs/borrowed_from_opencode/094-skill-system.rispec.md +187 -0
- package/rispecs/borrowed_from_opencode/095-skill-discovery.rispec.md +182 -0
- package/rispecs/borrowed_from_opencode/096-desktop-remote-driving.rispec.md +175 -0
- package/rispecs/borrowed_from_opencode/INDEX.md +255 -0
- package/rispecs/core.rispecs.md +261 -0
- package/rispecs/engines.rispecs.md +241 -0
- package/rispecs/formatting.rispecs.md +252 -0
- package/rispecs/living-specifications.rispecs.md +361 -0
- package/rispecs/mcp.rispecs.md +197 -0
- package/rispecs/pde.rispecs.md +399 -0
- package/rispecs/pi-mono-envisionning/ENVISIONING.md +366 -0
- package/rispecs/pi-mono-envisionning/storytelling-horizon.rispecs.md +76 -0
- package/rispecs/pi-mono-envisionning/widget.rispecs.md +2 -0
- package/rispecs/relation-to-mcp-structural-thinking.kin.md +72 -0
- package/rispecs/research-for-better-framework/CLAUDE.md +7 -0
- package/rispecs/research-for-better-framework/survey-pi-openclaw-opencode-openhands.md +210 -0
- package/rispecs/session.rispecs.md +277 -0
- package/rispecs/stc.rispecs.md +138 -0
- package/rispecs/unifier.rispecs.md +317 -0
- package/scripts/LAUNCH--mcp-mia-code--testing--2603141315--ac705a66-2c15-4a1c-a26d-9491018c5ba8.sh +2 -0
- package/scripts/RESUME--mia-code--mcps--260313--ac705a66-2c15-4a1c-a26d-9491018c5ba8.sh +1 -0
- package/scripts/install-widget-in-home-pi-agent-extensions.sh +4 -0
- package/scripts/sample-decompose--2604011535-prompt.sh +1 -0
- package/skills/deep-search/AGENTS.md +17 -0
- package/skills/deep-search/SKILL.md +281 -0
- package/skills/deep-search/agent-templates.md +224 -0
- package/skills/deep-search/orchestration-patterns.md +95 -0
- package/skills/miaco-pde-inquiry-routing-deep-search/AGENTS.md +13 -0
- package/skills/miaco-pde-inquiry-routing-deep-search/SKILL.md +136 -0
- package/skills/miaco-pde-inquiry-routing-internal-external-relationship/AGENTS.md +4 -0
- package/skills/miaco-pde-inquiry-routing-internal-external-relationship/SKILL.md +157 -0
- package/skills/miaco-pde-inquiry-routing-local-qmd/AGENTS.md +42 -0
- package/skills/miaco-pde-inquiry-routing-local-qmd/SKILL.md +135 -0
- package/skills/qmd/AGENTS.md +3 -0
- package/skills/qmd/SKILL.md +144 -0
- package/skills/qmd/references/mcp-setup.md +102 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/SKILL.md +234 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/agent-templates.md +436 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/orchestration-patterns.md +197 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/references/ceremonial-technology.md +102 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/references/creative-orientation.md +99 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/references/prompt-decomposition.md +73 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/references/rise-framework.md +74 -0
- package/skills/rise-pde-inquiry-session-multi-agents-v3/references/structural-tension.md +82 -0
- package/src/cli.ts +35 -11
- package/src/geminiHeadless.ts +7 -2
- package/src/index.ts +2 -1
- package/src/mcp/miaco-server.ts +13 -1
- package/src/mcp/miatel-server.ts +13 -1
- package/src/mcp/miawa-server.ts +13 -1
- package/src/mcp/utils.ts +41 -8
- package/src/sessionStore.ts +44 -4
- package/src/types.ts +2 -1
- package/widget/mia-ceremony/README.md +36 -0
- package/widget/mia-ceremony/index.ts +143 -0
- package/widget/mia-interceptor/README.md +39 -0
- package/widget/mia-interceptor/index.ts +221 -0
- package/widget/mia-tools/README.md +37 -0
- package/widget/mia-tools/index.ts +569 -0
- package/widget/miette-echo/README.md +44 -0
- package/widget/miette-echo/index.ts +164 -0
- package/.claude/settings.local.json +0 -9
- package/.hch/issue_.env +0 -4
- package/.hch/issue_add__2601211715.json +0 -77
- package/.hch/issue_add__2601211715.md +0 -4
- package/.hch/issue_add__2602242020.json +0 -78
- package/.hch/issue_add__2602242020.md +0 -7
- package/.hch/issues.json +0 -2312
- package/.hch/issues.md +0 -30
- package/WS__mia-code__260214__IAIP_PDE.code-workspace +0 -29
- package/WS__mia-code__src332__260122.code-workspace +0 -23
- package/samples/copilot/session-state/be76abaa-a27f-4725-b2a9-22fb45f7e0f7/checkpoints/index.md +0 -6
- package/samples/copilot/session-state/be76abaa-a27f-4725-b2a9-22fb45f7e0f7/events.jsonl +0 -213
- package/samples/copilot/session-state/be76abaa-a27f-4725-b2a9-22fb45f7e0f7/plan.md +0 -243
- package/samples/copilot/session-state/be76abaa-a27f-4725-b2a9-22fb45f7e0f7/workspace.yaml +0 -5
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
# RISE-033: Provider SDK Abstraction
|
|
2
|
+
|
|
3
|
+
> RISE Framework Specification — Borrowed from OpenCode for mia-code
|
|
4
|
+
> Document: rispecs/borrowed_from_opencode/033-provider-sdk-abstraction.rispec.md
|
|
5
|
+
|
|
6
|
+
## Creative Intent
|
|
7
|
+
|
|
8
|
+
mia-code wraps each LLM provider's low-level API communication in an SDK abstraction layer that handles the unglamorous but critical mechanics: connection pooling, rate limiting, retry with exponential backoff, timeout management, and response parsing. Each provider's SDK module is loaded lazily — only when the provider is actually used — and provides a unified streaming interface regardless of whether the provider natively uses SSE, WebSockets, or HTTP chunked transfer. Errors are classified into actionable categories (retry, re-authenticate, suggest alternatives) so that upper layers never need to interpret raw HTTP status codes or provider-specific error payloads.
|
|
9
|
+
|
|
10
|
+
## Structural Tension Analysis
|
|
11
|
+
|
|
12
|
+
**Current Structural Reality:**
|
|
13
|
+
- mia-code communicates with providers by invoking CLI binaries — the binary handles all HTTP concerns
|
|
14
|
+
- There is no connection management, retry logic, or rate limit handling within mia-code itself
|
|
15
|
+
- When a CLI binary fails, the error is an opaque exit code with stderr text — no structured error classification
|
|
16
|
+
- Each CLI binary has its own timeout behavior that mia-code cannot control or configure
|
|
17
|
+
- Streaming is delegated to the binary's stdout — mia-code cannot manage backpressure or reconnection
|
|
18
|
+
- Adding a new provider requires finding and learning a new CLI tool, not implementing a known interface
|
|
19
|
+
- All providers are initialized at startup regardless of whether they're used in the session
|
|
20
|
+
|
|
21
|
+
**Desired State:**
|
|
22
|
+
- Each provider has a dedicated SDK module handling HTTP communication and error management
|
|
23
|
+
- SDK modules are loaded lazily — only the active provider's SDK is initialized
|
|
24
|
+
- Retry logic with exponential backoff handles transient failures automatically
|
|
25
|
+
- Rate limits are detected and respected with intelligent backoff using provider-supplied `retry-after` hints
|
|
26
|
+
- Connection pooling reduces latency for repeated requests to the same provider
|
|
27
|
+
- A unified streaming interface normalizes SSE, JSON lines, and chunked responses
|
|
28
|
+
- Errors are classified into categories that drive automatic recovery behavior
|
|
29
|
+
|
|
30
|
+
## Desired Outcome Definition
|
|
31
|
+
|
|
32
|
+
A developer starts a session using Claude. mia-code lazily initializes only the Anthropic SDK module — OpenAI, Groq, and other SDKs remain unloaded. The SDK establishes a connection pool to `api.anthropic.com`. When a request hits a rate limit, the SDK reads the `retry-after` header, waits the specified duration, and retries — the developer sees a brief "⏳ rate limited, retrying in 12s" message but the session continues seamlessly. A transient 502 error triggers automatic retry with exponential backoff. A persistent auth failure is classified as non-retryable and escalates to the auth system (RISE-029) for re-authentication.
|
|
33
|
+
|
|
34
|
+
## Natural Language Functional Description
|
|
35
|
+
|
|
36
|
+
### SDK Module Interface
|
|
37
|
+
|
|
38
|
+
Each provider's SDK implements:
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
interface ProviderSDK {
|
|
42
|
+
providerId: string;
|
|
43
|
+
initialized: boolean;
|
|
44
|
+
|
|
45
|
+
initialize(config: ProviderConfig): Promise<void>;
|
|
46
|
+
dispose(): Promise<void>;
|
|
47
|
+
|
|
48
|
+
// Core communication
|
|
49
|
+
send(request: ProviderRequest): Promise<ProviderResponse>;
|
|
50
|
+
stream(request: ProviderRequest): AsyncIterable<ProviderStreamChunk>;
|
|
51
|
+
|
|
52
|
+
// Model discovery
|
|
53
|
+
listModels(): Promise<ProviderModelInfo[]>;
|
|
54
|
+
|
|
55
|
+
// Health and status
|
|
56
|
+
healthCheck(): Promise<SDKHealthStatus>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
interface SDKHealthStatus {
|
|
60
|
+
connected: boolean;
|
|
61
|
+
latencyMs: number;
|
|
62
|
+
rateLimitRemaining?: number;
|
|
63
|
+
rateLimitResetAt?: number;
|
|
64
|
+
}
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Lazy Initialization
|
|
68
|
+
|
|
69
|
+
SDK modules are loaded on first use, not at application startup:
|
|
70
|
+
|
|
71
|
+
```typescript
|
|
72
|
+
class SDKManager {
|
|
73
|
+
private sdks = new Map<string, ProviderSDK>();
|
|
74
|
+
private loading = new Map<string, Promise<ProviderSDK>>();
|
|
75
|
+
|
|
76
|
+
async getSDK(providerId: string): Promise<ProviderSDK> {
|
|
77
|
+
// Return if already initialized
|
|
78
|
+
if (this.sdks.has(providerId)) return this.sdks.get(providerId)!;
|
|
79
|
+
// Deduplicate concurrent initialization requests
|
|
80
|
+
if (this.loading.has(providerId)) return this.loading.get(providerId)!;
|
|
81
|
+
|
|
82
|
+
const loadPromise = this.initializeSDK(providerId);
|
|
83
|
+
this.loading.set(providerId, loadPromise);
|
|
84
|
+
const sdk = await loadPromise;
|
|
85
|
+
this.sdks.set(providerId, sdk);
|
|
86
|
+
this.loading.delete(providerId);
|
|
87
|
+
return sdk;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
private async initializeSDK(providerId: string): Promise<ProviderSDK> {
|
|
91
|
+
const module = await import(`./providers/${providerId}/sdk.js`);
|
|
92
|
+
const sdk = new module.default();
|
|
93
|
+
const config = this.getProviderConfig(providerId);
|
|
94
|
+
await sdk.initialize(config);
|
|
95
|
+
return sdk;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
Benefits of lazy loading:
|
|
101
|
+
- Application starts faster — no waiting for unused provider connections
|
|
102
|
+
- Memory footprint is proportional to active providers only
|
|
103
|
+
- Errors in unused provider SDKs don't affect the application
|
|
104
|
+
- Hot-adding a provider mid-session is natural — just initialize on first request
|
|
105
|
+
|
|
106
|
+
### Retry with Exponential Backoff
|
|
107
|
+
|
|
108
|
+
Transient failures trigger automatic retry:
|
|
109
|
+
|
|
110
|
+
```typescript
|
|
111
|
+
interface RetryConfig {
|
|
112
|
+
maxRetries: number; // default: 3
|
|
113
|
+
initialDelayMs: number; // default: 1000
|
|
114
|
+
maxDelayMs: number; // default: 60000
|
|
115
|
+
backoffMultiplier: number; // default: 2
|
|
116
|
+
jitterFraction: number; // default: 0.1 (10% jitter)
|
|
117
|
+
retryableErrors: ErrorClass[]; // which error classes to retry
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async function withRetry<T>(
|
|
121
|
+
operation: () => Promise<T>,
|
|
122
|
+
config: RetryConfig
|
|
123
|
+
): Promise<T> {
|
|
124
|
+
let lastError: Error;
|
|
125
|
+
for (let attempt = 0; attempt <= config.maxRetries; attempt++) {
|
|
126
|
+
try {
|
|
127
|
+
return await operation();
|
|
128
|
+
} catch (error) {
|
|
129
|
+
lastError = error;
|
|
130
|
+
if (!isRetryable(error, config.retryableErrors)) throw error;
|
|
131
|
+
if (attempt === config.maxRetries) throw error;
|
|
132
|
+
|
|
133
|
+
const delay = calculateBackoff(attempt, config);
|
|
134
|
+
emitRetryNotification(attempt + 1, config.maxRetries, delay);
|
|
135
|
+
await sleep(delay);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
throw lastError!;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
function calculateBackoff(attempt: number, config: RetryConfig): number {
|
|
142
|
+
const baseDelay = config.initialDelayMs * Math.pow(config.backoffMultiplier, attempt);
|
|
143
|
+
const capped = Math.min(baseDelay, config.maxDelayMs);
|
|
144
|
+
const jitter = capped * config.jitterFraction * (Math.random() * 2 - 1);
|
|
145
|
+
return Math.max(0, capped + jitter);
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
### Rate Limit Management
|
|
150
|
+
|
|
151
|
+
Rate limits are detected and handled proactively:
|
|
152
|
+
|
|
153
|
+
```typescript
|
|
154
|
+
interface RateLimitState {
|
|
155
|
+
remaining: number; // requests remaining in current window
|
|
156
|
+
resetAt: number; // Unix timestamp when window resets
|
|
157
|
+
retryAfter?: number; // seconds to wait (from 429 response)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
class RateLimitManager {
|
|
161
|
+
private state = new Map<string, RateLimitState>();
|
|
162
|
+
|
|
163
|
+
async beforeRequest(providerId: string): Promise<void> {
|
|
164
|
+
const limit = this.state.get(providerId);
|
|
165
|
+
if (!limit) return;
|
|
166
|
+
|
|
167
|
+
if (limit.remaining <= 0 && Date.now() < limit.resetAt) {
|
|
168
|
+
const waitMs = limit.resetAt - Date.now();
|
|
169
|
+
emitRateLimitNotification(providerId, waitMs);
|
|
170
|
+
await sleep(waitMs);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
updateFromHeaders(providerId: string, headers: Headers): void {
|
|
175
|
+
this.state.set(providerId, {
|
|
176
|
+
remaining: parseInt(headers.get("x-ratelimit-remaining") ?? "100"),
|
|
177
|
+
resetAt: parseInt(headers.get("x-ratelimit-reset") ?? "0") * 1000,
|
|
178
|
+
retryAfter: headers.has("retry-after")
|
|
179
|
+
? parseInt(headers.get("retry-after")!) * 1000
|
|
180
|
+
: undefined,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### Connection Pooling
|
|
187
|
+
|
|
188
|
+
Persistent HTTP connections reduce latency for repeated requests:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
interface ConnectionPool {
|
|
192
|
+
baseURL: string;
|
|
193
|
+
maxConnections: number; // default: 6
|
|
194
|
+
idleTimeoutMs: number; // default: 30000
|
|
195
|
+
keepAlive: boolean; // default: true
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
The SDK uses Node.js `http.Agent` (or `undici` pool) to maintain persistent connections. Benefits:
|
|
200
|
+
- TCP handshake cost is paid once, not per request
|
|
201
|
+
- TLS session resumption reduces SSL overhead
|
|
202
|
+
- Connection reuse is transparent to the caller
|
|
203
|
+
|
|
204
|
+
### Unified Streaming Interface
|
|
205
|
+
|
|
206
|
+
Regardless of provider-native streaming format, the SDK exposes a consistent `AsyncIterable`:
|
|
207
|
+
|
|
208
|
+
```typescript
|
|
209
|
+
async function* unifiedStream(
|
|
210
|
+
response: IncomingMessage
|
|
211
|
+
): AsyncIterable<ProviderStreamChunk> {
|
|
212
|
+
const contentType = response.headers["content-type"];
|
|
213
|
+
|
|
214
|
+
if (contentType?.includes("text/event-stream")) {
|
|
215
|
+
yield* parseSSE(response); // Anthropic, OpenAI
|
|
216
|
+
} else if (contentType?.includes("application/x-ndjson")) {
|
|
217
|
+
yield* parseNDJSON(response); // some custom providers
|
|
218
|
+
} else if (contentType?.includes("application/json")) {
|
|
219
|
+
yield* parseChunkedJSON(response); // Gemini
|
|
220
|
+
} else {
|
|
221
|
+
throw new UnsupportedStreamFormatError(contentType);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Each parser handles:
|
|
227
|
+
- Incomplete chunks (buffering partial JSON across network packets)
|
|
228
|
+
- Keep-alive pings (empty SSE events or heartbeat messages)
|
|
229
|
+
- End-of-stream signals (SSE `[DONE]`, JSON `done: true`, connection close)
|
|
230
|
+
|
|
231
|
+
### Error Classification
|
|
232
|
+
|
|
233
|
+
Raw provider errors are classified into actionable categories:
|
|
234
|
+
|
|
235
|
+
```typescript
|
|
236
|
+
enum ErrorClass {
|
|
237
|
+
RATE_LIMIT = "rate_limit", // retry after delay
|
|
238
|
+
AUTH_FAILURE = "auth_failure", // re-authenticate (RISE-029)
|
|
239
|
+
MODEL_NOT_FOUND = "model_not_found", // suggest alternatives
|
|
240
|
+
SERVER_ERROR = "server_error", // retry with backoff
|
|
241
|
+
CONTEXT_OVERFLOW = "context_overflow", // trigger compaction (RISE-019)
|
|
242
|
+
CONTENT_FILTER = "content_filter", // modify request content
|
|
243
|
+
INVALID_REQUEST = "invalid_request", // fix request, don't retry
|
|
244
|
+
NETWORK_ERROR = "network_error", // retry with backoff
|
|
245
|
+
TIMEOUT = "timeout", // retry or increase timeout
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function classifyError(error: unknown, providerId: string): ClassifiedError {
|
|
249
|
+
if (error instanceof HTTPError) {
|
|
250
|
+
switch (error.status) {
|
|
251
|
+
case 401: case 403: return { class: ErrorClass.AUTH_FAILURE, retryable: false };
|
|
252
|
+
case 429: return { class: ErrorClass.RATE_LIMIT, retryable: true };
|
|
253
|
+
case 404: return { class: ErrorClass.MODEL_NOT_FOUND, retryable: false };
|
|
254
|
+
case 500: case 502: case 503: return { class: ErrorClass.SERVER_ERROR, retryable: true };
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
if (error instanceof TimeoutError) {
|
|
258
|
+
return { class: ErrorClass.TIMEOUT, retryable: true };
|
|
259
|
+
}
|
|
260
|
+
// Provider-specific classification
|
|
261
|
+
return classifyProviderSpecific(error, providerId);
|
|
262
|
+
}
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**Recovery actions per class:**
|
|
266
|
+
|
|
267
|
+
| Error Class | Automatic Action | User Notification |
|
|
268
|
+
|---|---|---|
|
|
269
|
+
| `rate_limit` | Wait `retry-after`, then retry | "⏳ Rate limited, retrying in Ns" |
|
|
270
|
+
| `auth_failure` | Trigger re-authentication flow | "🔑 Auth expired — re-authenticating" |
|
|
271
|
+
| `model_not_found` | Suggest alternative models | "Model X not found. Try: Y, Z" |
|
|
272
|
+
| `server_error` | Retry with exponential backoff | "⚠ Server error, retry N/3" |
|
|
273
|
+
| `context_overflow` | Trigger compaction (RISE-019) | "📝 Context too long — compacting" |
|
|
274
|
+
| `timeout` | Retry with increased timeout | "⏱ Request timed out, retrying" |
|
|
275
|
+
| `invalid_request` | Surface error to developer | "❌ Invalid request: {details}" |
|
|
276
|
+
|
|
277
|
+
### Timeout Management
|
|
278
|
+
|
|
279
|
+
Configurable timeouts prevent requests from hanging indefinitely:
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
interface TimeoutConfig {
|
|
283
|
+
connectTimeoutMs: number; // TCP connection timeout (default: 10000)
|
|
284
|
+
requestTimeoutMs: number; // total request timeout (default: 120000)
|
|
285
|
+
streamIdleTimeoutMs: number; // max gap between stream chunks (default: 30000)
|
|
286
|
+
}
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
- **Connect timeout:** how long to wait for TCP connection establishment
|
|
290
|
+
- **Request timeout:** total time for a non-streaming request (connect + send + receive)
|
|
291
|
+
- **Stream idle timeout:** maximum silence between streaming chunks before assuming connection loss
|
|
292
|
+
|
|
293
|
+
### Custom Provider SDK Extension
|
|
294
|
+
|
|
295
|
+
Custom providers extend the base OpenAI-compatible SDK:
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
class CustomProviderSDK extends OpenAICompatibleSDK {
|
|
299
|
+
constructor(config: CustomProviderConfig) {
|
|
300
|
+
super({
|
|
301
|
+
...config,
|
|
302
|
+
baseURL: config.baseURL, // custom endpoint
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Override only what differs from OpenAI-compatible behavior
|
|
307
|
+
override parseStreamChunk(chunk: string): ProviderStreamChunk {
|
|
308
|
+
// Custom parsing if needed
|
|
309
|
+
return super.parseStreamChunk(chunk);
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
This inheritance model means most custom providers need zero custom code — the base class handles everything for OpenAI-compatible APIs.
|
|
315
|
+
|
|
316
|
+
## Supporting Structures
|
|
317
|
+
|
|
318
|
+
- **Multi-Provider Architecture (RISE-028)** selects which SDK to activate based on provider configuration
|
|
319
|
+
- **Provider Authentication (RISE-029)** supplies credentials that the SDK attaches to requests
|
|
320
|
+
- **Provider Transform Pipeline (RISE-032)** transforms requests before the SDK sends them and responses after
|
|
321
|
+
- **Streaming Message Deltas (RISE-027)** consumes the unified stream output from the SDK
|
|
322
|
+
- **Session Compaction (RISE-019)** is triggered by `context_overflow` error classification
|
|
323
|
+
- **Lazy Initialization (RISE-008)** aligns with the SDK's lazy loading pattern
|
|
324
|
+
- **Named Error System (RISE-006)** provides RateLimitError, AuthenticationError, ContextOverflowError, ProviderServerError, ConnectionTimeoutError
|
|
325
|
+
|
|
326
|
+
## Creative Advancement Scenarios
|
|
327
|
+
|
|
328
|
+
**Scenario 1 — Invisible Retry:**
|
|
329
|
+
A developer sends a complex prompt. The Anthropic API returns a 502 (bad gateway). The SDK classifies it as `server_error`, waits 1 second, and retries. The second attempt succeeds. The developer sees "⚠ Server error, retried successfully" in a subtle status message — their workflow is uninterrupted. Without the SDK abstraction, this would have been a cryptic shell error requiring manual retry.
|
|
330
|
+
|
|
331
|
+
**Scenario 2 — Rate Limit Surfing:**
|
|
332
|
+
During a heavy coding session, the developer hits Anthropic's rate limit. The SDK reads `retry-after: 12` from the 429 response, displays "⏳ Rate limited, retrying in 12s", waits, and retries. The next request's response headers show `x-ratelimit-remaining: 3` — the SDK preemptively slows request pacing to avoid another 429. The developer experiences brief pauses, not failures.
|
|
333
|
+
|
|
334
|
+
**Scenario 3 — Lazy Provider Loading:**
|
|
335
|
+
A developer has 5 providers configured but only uses Anthropic today. Only the Anthropic SDK initializes — OpenAI, Groq, Gemini, and the custom provider remain unloaded. Application startup takes 200ms instead of 2 seconds. When the developer later tries a Groq model, its SDK initializes on-demand in 150ms — imperceptible in the context of an API call.
|
|
336
|
+
|
|
337
|
+
**Scenario 4 — Context Overflow Recovery:**
|
|
338
|
+
During a long session, the context window fills up. The SDK receives a `context_length_exceeded` error from the API. It classifies this as `context_overflow` and triggers session compaction (RISE-019). The compaction agent summarizes the conversation, the context shrinks by 70%, and the original request is automatically retried with the compacted context. The developer sees "📝 Context compacted — continuing" and the response arrives normally.
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
# RISE-034: Tool Registry Pattern
|
|
2
|
+
|
|
3
|
+
> RISE Framework Specification — Borrowed from OpenCode for mia-code
|
|
4
|
+
> Document: rispecs/borrowed_from_opencode/034-tool-registry.rispec.md
|
|
5
|
+
|
|
6
|
+
## Creative Intent
|
|
7
|
+
|
|
8
|
+
mia-code provides a central registry where all tools — built-in, plugin-contributed, and user-defined — register themselves at startup. Each tool declares its identity, parameters, and execution function through a uniform initialization protocol. The registry becomes the single source of truth for what the agent can do: it filters tools by agent permissions, generates tool descriptions for LLM system prompts, and resolves tool invocations at runtime. Without a registry, tools are invisible capabilities scattered across code; with one, they become a discoverable, governable catalog.
|
|
9
|
+
|
|
10
|
+
## Structural Tension Analysis
|
|
11
|
+
|
|
12
|
+
**Current Reality:**
|
|
13
|
+
- mia-code has no formal tool system — it relies entirely on the underlying Gemini/Claude CLI's built-in tools
|
|
14
|
+
- There is no way to add custom tools, restrict tool access per agent, or discover available tools programmatically
|
|
15
|
+
- Tool descriptions are whatever the CLI provider decides — mia-code cannot customize or extend them
|
|
16
|
+
- Adding a new capability means changing the CLI binary or hoping the provider adds it upstream
|
|
17
|
+
- No lifecycle management — tools cannot initialize resources at startup or clean up on shutdown
|
|
18
|
+
- Tool availability is opaque: neither the user nor the agent knows exactly which tools are available
|
|
19
|
+
|
|
20
|
+
**Desired State:**
|
|
21
|
+
- A centralized `ToolRegistry` manages all tools through a consistent interface
|
|
22
|
+
- Tools register with: `id` (unique string), an `init` function returning `{description, parameters, execute}`
|
|
23
|
+
- The registry provides: `list()` for all tools, `get(id)` for a single tool, `available(agent)` filtered by permissions
|
|
24
|
+
- Tools are loaded from three sources at startup: built-in tools, plugin tools, and user custom tools from `.mia-code/tools/`
|
|
25
|
+
- Tool descriptions are automatically injected into agent system prompts for LLM awareness
|
|
26
|
+
- The registry emits events on tool registration and deregistration for UI and logging
|
|
27
|
+
|
|
28
|
+
## Desired Outcome Definition
|
|
29
|
+
|
|
30
|
+
A developer starts mia-code. The registry loads 15 built-in tools, 2 plugin tools, and 1 custom tool from `.mia-code/tools/read-schema.ts`. When the agent processes a prompt, its system prompt includes descriptions and parameter schemas for only the tools that agent is permitted to use. The developer types `/tools` and sees a formatted list of all 18 registered tools with their descriptions.
|
|
31
|
+
|
|
32
|
+
## Natural Language Functional Description
|
|
33
|
+
|
|
34
|
+
### Tool Registration Protocol
|
|
35
|
+
|
|
36
|
+
Each tool is a module that exports an `init` function. When called, `init` returns an object describing the tool:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
interface ToolDefinition {
|
|
40
|
+
description: string;
|
|
41
|
+
parameters: ZodSchema;
|
|
42
|
+
execute: (input: unknown, context: ToolContext) => Promise<ToolResult>;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
type ToolInit = () => ToolDefinition;
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The registry calls `init()` during startup for each tool module. The returned `parameters` field is a Zod schema that validates input before `execute` is called. The `description` field is injected into LLM system prompts verbatim.
|
|
49
|
+
|
|
50
|
+
### Registry API
|
|
51
|
+
|
|
52
|
+
The registry exposes three core methods:
|
|
53
|
+
|
|
54
|
+
- `list()` — returns all registered tools with their metadata (id, description, parameter schema summary)
|
|
55
|
+
- `get(id)` — returns a single tool by its unique identifier, or throws `ToolNotFoundError`
|
|
56
|
+
- `available(agent)` — returns tools filtered by the agent's permission ruleset (RISE-011), excluding any tools the agent is denied access to
|
|
57
|
+
|
|
58
|
+
### Tool Source Loading Order
|
|
59
|
+
|
|
60
|
+
At startup, the registry loads tools in priority order:
|
|
61
|
+
|
|
62
|
+
1. **Built-in tools** — shipped with mia-code (file read/write, batch, search, etc.)
|
|
63
|
+
2. **Plugin tools** — contributed by installed plugins (RISE-071)
|
|
64
|
+
3. **User custom tools** — `.mia-code/tools/*.ts` files in the project directory
|
|
65
|
+
|
|
66
|
+
Later registrations with the same `id` override earlier ones — a user custom tool can replace a built-in tool.
|
|
67
|
+
|
|
68
|
+
### System Prompt Injection
|
|
69
|
+
|
|
70
|
+
When an agent's system prompt is constructed, the registry generates a tools section:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
Available tools:
|
|
74
|
+
- file_read: Read file content with line numbers. Parameters: {path: string}
|
|
75
|
+
- file_write: Write content to a file. Parameters: {path: string, content: string}
|
|
76
|
+
- batch: Execute multiple file operations atomically. Parameters: {operations: [...]}
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Only tools passing the agent's permission filter appear in the prompt. This prevents the LLM from attempting to invoke tools it cannot access.
|
|
80
|
+
|
|
81
|
+
### Event Emission
|
|
82
|
+
|
|
83
|
+
The registry emits events on the event bus (RISE-002):
|
|
84
|
+
|
|
85
|
+
- `tool.registered` — when a tool is added (includes tool id and source)
|
|
86
|
+
- `tool.deregistered` — when a tool is removed (plugin unload, hot reload)
|
|
87
|
+
- `tool.invoked` — when a tool's `execute` function is called (includes tool id, agent, timing)
|
|
88
|
+
|
|
89
|
+
## Supporting Structures
|
|
90
|
+
|
|
91
|
+
- **Zod Schema Validation (RISE-005)** validates tool parameters before execution
|
|
92
|
+
- **Agent Permission Rulesets (RISE-011)** determine which tools are available to each agent
|
|
93
|
+
- **Agent Prompt Templates (RISE-012)** consume tool descriptions for system prompt generation
|
|
94
|
+
- **Event Bus (RISE-002)** carries tool lifecycle events to UI and logging subscribers
|
|
95
|
+
- **Plugin Architecture (RISE-071)** contributes plugin-sourced tools to the registry
|
|
96
|
+
- **Named Error System (RISE-006)** provides ToolNotFoundError, ToolValidationError, ToolExecutionError
|
|
97
|
+
|
|
98
|
+
## Creative Advancement Scenarios
|
|
99
|
+
|
|
100
|
+
**Scenario 1 — Custom Project Tool:**
|
|
101
|
+
A developer creates `.mia-code/tools/deploy.ts` that wraps their project's deployment script. It registers as `deploy` with parameters `{environment: "staging" | "production"}`. The agent can now deploy on request — "deploy to staging" invokes the tool directly. The developer didn't modify mia-code's source code at all.
|
|
102
|
+
|
|
103
|
+
**Scenario 2 — Permission-Filtered Discovery:**
|
|
104
|
+
The plan agent asks what tools are available. The registry returns 12 of 18 tools — the 6 write-oriented tools are filtered out by the plan agent's read-only permission ruleset. The agent's system prompt never mentions file_write or bash_execute, so the LLM never attempts to use them.
|
|
105
|
+
|
|
106
|
+
**Scenario 3 — Plugin Tool Override:**
|
|
107
|
+
A team installs a plugin that provides an enhanced `file_write` tool with automatic formatting. Because plugin tools load after built-in tools, the enhanced version replaces the default. All agents now get formatted writes without any configuration change.
|
|
108
|
+
|
|
109
|
+
**Scenario 4 — Runtime Tool Inspection:**
|
|
110
|
+
The developer types `/tools` during a session. mia-code lists all registered tools grouped by source (built-in, plugin, custom), showing each tool's description and parameter summary. They spot that a custom tool has a typo in its description and fix it — on next session start, the corrected description appears in agent prompts.
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# RISE-035: Tool Context Injection
|
|
2
|
+
|
|
3
|
+
> RISE Framework Specification — Borrowed from OpenCode for mia-code
|
|
4
|
+
> Document: rispecs/borrowed_from_opencode/035-tool-context-injection.rispec.md
|
|
5
|
+
|
|
6
|
+
## Creative Intent
|
|
7
|
+
|
|
8
|
+
Every tool execution in mia-code receives a rich context object that provides session information, cancellation signals, conversation history, and interaction capabilities — without requiring tools to access global state. The context is the tool's window into the world: it knows which session invoked it, can cancel gracefully when the user interrupts, can read conversation history for context-aware behavior, and can ask the user for permission before sensitive operations. Tools remain pure functions of their input and context, making them testable, composable, and safe.
|
|
9
|
+
|
|
10
|
+
## Structural Tension Analysis
|
|
11
|
+
|
|
12
|
+
**Current Reality:**
|
|
13
|
+
- mia-code tools (provided by the underlying CLI) have no concept of session context — they execute in isolation
|
|
14
|
+
- There is no cancellation mechanism — once a tool starts, it runs to completion or the process is killed
|
|
15
|
+
- Tools cannot access conversation history to inform their behavior
|
|
16
|
+
- There is no way for a tool to ask the user a question mid-execution
|
|
17
|
+
- Tools that need metadata (session ID, project root) would need to read global state or environment variables
|
|
18
|
+
- No tracking of which session or message triggered a tool invocation
|
|
19
|
+
|
|
20
|
+
**Desired State:**
|
|
21
|
+
- Every tool's `execute` function receives a `ToolContext` as its second argument
|
|
22
|
+
- The context includes: sessionID, messageID, agent info, AbortSignal, conversation messages, `ask()` and `metadata()` functions
|
|
23
|
+
- Tools use the AbortSignal to cancel long-running operations when the user presses Ctrl+C
|
|
24
|
+
- The `ask()` function pauses execution and prompts the user for permission or input
|
|
25
|
+
- The `metadata()` function attaches result metadata (timing, file paths, byte counts) to the tool output
|
|
26
|
+
- Context is created fresh per invocation and cleaned up after — no state leaks between calls
|
|
27
|
+
|
|
28
|
+
## Desired Outcome Definition
|
|
29
|
+
|
|
30
|
+
A tool executes with full awareness of its environment. It checks `context.abort.signal` in loops, calls `context.ask("Delete 47 files?")` before destructive operations, and attaches `context.metadata({filesModified: 3})` to its result. When the user presses Ctrl+C, the AbortSignal fires and the tool exits cleanly mid-operation.
|
|
31
|
+
|
|
32
|
+
## Natural Language Functional Description
|
|
33
|
+
|
|
34
|
+
### Context Shape
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
interface ToolContext {
|
|
38
|
+
sessionID: string;
|
|
39
|
+
messageID: string;
|
|
40
|
+
agent: { name: string; mode: string; permissions: PermissionRuleset };
|
|
41
|
+
abort: AbortSignal;
|
|
42
|
+
messages: ConversationMessage[];
|
|
43
|
+
ask: (question: string, options?: AskOptions) => Promise<string>;
|
|
44
|
+
metadata: (data: Record<string, unknown>) => void;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
interface AskOptions {
|
|
48
|
+
choices?: string[];
|
|
49
|
+
allowFreeform?: boolean;
|
|
50
|
+
timeout?: number;
|
|
51
|
+
default?: string;
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Context Lifecycle
|
|
56
|
+
|
|
57
|
+
The context is created when the tool registry dispatches a tool invocation:
|
|
58
|
+
|
|
59
|
+
1. **Creation** — A new `ToolContext` is constructed with the current session ID, a fresh message ID, the invoking agent's info, and a new `AbortController`
|
|
60
|
+
2. **Injection** — The context is passed as the second argument to `tool.execute(input, context)`
|
|
61
|
+
3. **Active** — During execution, the tool reads context properties and calls context functions
|
|
62
|
+
4. **Cleanup** — After execution completes (success or failure), the context's abort controller is disposed and references are released
|
|
63
|
+
|
|
64
|
+
### Cancellation via AbortSignal
|
|
65
|
+
|
|
66
|
+
Tools check `context.abort` to support graceful cancellation:
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
async function execute(input: SearchInput, context: ToolContext) {
|
|
70
|
+
for (const file of filesToSearch) {
|
|
71
|
+
if (context.abort.aborted) {
|
|
72
|
+
return { partial: true, results: resultsSoFar };
|
|
73
|
+
}
|
|
74
|
+
const matches = await searchFile(file, input.pattern);
|
|
75
|
+
resultsSoFar.push(...matches);
|
|
76
|
+
}
|
|
77
|
+
return { partial: false, results: resultsSoFar };
|
|
78
|
+
}
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
When the user presses Ctrl+C, the session's abort controller fires. All active tool contexts receive the signal. Tools that respect it exit cleanly with partial results; tools that ignore it are force-terminated after a grace period.
|
|
82
|
+
|
|
83
|
+
### Permission Requests via ask()
|
|
84
|
+
|
|
85
|
+
Tools can pause and ask the user for confirmation:
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
async function execute(input: DeleteInput, context: ToolContext) {
|
|
89
|
+
const files = await glob(input.pattern);
|
|
90
|
+
const answer = await context.ask(
|
|
91
|
+
`Delete ${files.length} files matching "${input.pattern}"?`,
|
|
92
|
+
{ choices: ["yes", "no"], default: "no" }
|
|
93
|
+
);
|
|
94
|
+
if (answer !== "yes") return { cancelled: true };
|
|
95
|
+
// proceed with deletion
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The `ask()` function renders a prompt in the TUI and blocks until the user responds. If `timeout` is specified and the user doesn't respond, the default value is used.
|
|
100
|
+
|
|
101
|
+
### Result Metadata
|
|
102
|
+
|
|
103
|
+
Tools attach metadata to enrich the output displayed to the user:
|
|
104
|
+
|
|
105
|
+
```typescript
|
|
106
|
+
async function execute(input: ReadInput, context: ToolContext) {
|
|
107
|
+
const content = await readFile(input.path);
|
|
108
|
+
context.metadata({
|
|
109
|
+
fileSize: content.length,
|
|
110
|
+
encoding: "utf-8",
|
|
111
|
+
lineCount: content.split("\n").length,
|
|
112
|
+
});
|
|
113
|
+
return { content };
|
|
114
|
+
}
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Metadata appears in the tool result event (RISE-002) and can be rendered by the UI alongside the tool output.
|
|
118
|
+
|
|
119
|
+
### Conversation Access
|
|
120
|
+
|
|
121
|
+
Tools that need conversation context read `context.messages`:
|
|
122
|
+
|
|
123
|
+
```typescript
|
|
124
|
+
async function execute(input: SuggestInput, context: ToolContext) {
|
|
125
|
+
const recentFiles = context.messages
|
|
126
|
+
.flatMap(m => m.toolResults ?? [])
|
|
127
|
+
.filter(r => r.toolId === "file_read")
|
|
128
|
+
.map(r => r.input.path);
|
|
129
|
+
// use recently-read files to inform suggestions
|
|
130
|
+
}
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Messages are read-only snapshots — tools cannot modify conversation history.
|
|
134
|
+
|
|
135
|
+
## Supporting Structures
|
|
136
|
+
|
|
137
|
+
- **Tool Registry (RISE-034)** creates and injects context during tool dispatch
|
|
138
|
+
- **Agent Permission Rulesets (RISE-011)** populate `context.agent.permissions` for tool-side checks
|
|
139
|
+
- **Event Bus (RISE-002)** receives `tool.invoked` events with context metadata
|
|
140
|
+
- **Permission System (RISE-074)** enforces permission checks that `ask()` may trigger
|
|
141
|
+
- **Message Parts Model (RISE-026)** defines the `ConversationMessage` type in `context.messages`
|
|
142
|
+
|
|
143
|
+
## Creative Advancement Scenarios
|
|
144
|
+
|
|
145
|
+
**Scenario 1 — Graceful Cancellation:**
|
|
146
|
+
The developer asks the agent to search a massive monorepo. The code search tool iterates through thousands of files, checking `context.abort` between each batch. After 10 seconds, the developer presses Ctrl+C. The tool stops immediately, returns 847 partial results found so far, and the agent presents them with a note: "Search cancelled — showing 847 of ~3000 estimated results."
|
|
147
|
+
|
|
148
|
+
**Scenario 2 — Permission Dialogue:**
|
|
149
|
+
The agent decides to delete old build artifacts. The cleanup tool calls `context.ask("Remove 23 files from dist/?", {choices: ["yes", "no"]})`. The user sees a clear prompt, reviews the count, and confirms. The tool proceeds. Without `ask()`, this would either require blanket permission or fail silently.
|
|
150
|
+
|
|
151
|
+
**Scenario 3 — Context-Aware Tool:**
|
|
152
|
+
A documentation generation tool reads `context.messages` to find which files were recently edited. It generates docs only for those files, not the entire project. The developer gets focused, relevant documentation without specifying file paths manually.
|
|
153
|
+
|
|
154
|
+
**Scenario 4 — Metadata Enrichment:**
|
|
155
|
+
The file write tool attaches `{bytesWritten: 4096, path: "src/auth.ts"}` via `context.metadata()`. The UI renders: "✏ Wrote 4KB to src/auth.ts" — a richer experience than just "file_write completed."
|