compound-engineering-pi 0.2.3
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/LICENSE +21 -0
- package/README.md +124 -0
- package/bin/compound-engineering-pi +12 -0
- package/bin/compound-plugin +12 -0
- package/compound-engineering-pi +12 -0
- package/compound-plugin +5 -0
- package/docs/pi.md +152 -0
- package/extensions/compound-engineering-compat.ts +452 -0
- package/package.json +84 -0
- package/pi-resources/compound-engineering/mcporter.json +7 -0
- package/plugins/coding-tutor/.claude-plugin/plugin.json +9 -0
- package/plugins/coding-tutor/README.md +37 -0
- package/plugins/coding-tutor/commands/quiz-me.md +1 -0
- package/plugins/coding-tutor/commands/sync-tutorials.md +25 -0
- package/plugins/coding-tutor/commands/teach-me.md +1 -0
- package/plugins/coding-tutor/skills/coding-tutor/SKILL.md +214 -0
- package/plugins/coding-tutor/skills/coding-tutor/scripts/create_tutorial.py +207 -0
- package/plugins/coding-tutor/skills/coding-tutor/scripts/index_tutorials.py +193 -0
- package/plugins/coding-tutor/skills/coding-tutor/scripts/quiz_priority.py +190 -0
- package/plugins/coding-tutor/skills/coding-tutor/scripts/setup_tutorials.py +118 -0
- package/plugins/compound-engineering/.claude-plugin/plugin.json +33 -0
- package/plugins/compound-engineering/CHANGELOG.md +457 -0
- package/plugins/compound-engineering/CLAUDE.md +89 -0
- package/plugins/compound-engineering/LICENSE +21 -0
- package/plugins/compound-engineering/README.md +232 -0
- package/plugins/compound-engineering/agents/design/design-implementation-reviewer.md +109 -0
- package/plugins/compound-engineering/agents/design/design-iterator.md +224 -0
- package/plugins/compound-engineering/agents/design/figma-design-sync.md +190 -0
- package/plugins/compound-engineering/agents/docs/ankane-readme-writer.md +65 -0
- package/plugins/compound-engineering/agents/research/best-practices-researcher.md +126 -0
- package/plugins/compound-engineering/agents/research/framework-docs-researcher.md +106 -0
- package/plugins/compound-engineering/agents/research/git-history-analyzer.md +59 -0
- package/plugins/compound-engineering/agents/research/learnings-researcher.md +264 -0
- package/plugins/compound-engineering/agents/research/repo-research-analyst.md +135 -0
- package/plugins/compound-engineering/agents/review/agent-native-reviewer.md +261 -0
- package/plugins/compound-engineering/agents/review/architecture-strategist.md +67 -0
- package/plugins/compound-engineering/agents/review/code-simplicity-reviewer.md +101 -0
- package/plugins/compound-engineering/agents/review/data-integrity-guardian.md +85 -0
- package/plugins/compound-engineering/agents/review/data-migration-expert.md +112 -0
- package/plugins/compound-engineering/agents/review/deployment-verification-agent.md +174 -0
- package/plugins/compound-engineering/agents/review/dhh-rails-reviewer.md +66 -0
- package/plugins/compound-engineering/agents/review/julik-frontend-races-reviewer.md +221 -0
- package/plugins/compound-engineering/agents/review/kieran-python-reviewer.md +133 -0
- package/plugins/compound-engineering/agents/review/kieran-rails-reviewer.md +115 -0
- package/plugins/compound-engineering/agents/review/kieran-typescript-reviewer.md +124 -0
- package/plugins/compound-engineering/agents/review/pattern-recognition-specialist.md +72 -0
- package/plugins/compound-engineering/agents/review/performance-oracle.md +137 -0
- package/plugins/compound-engineering/agents/review/schema-drift-detector.md +154 -0
- package/plugins/compound-engineering/agents/review/security-sentinel.md +114 -0
- package/plugins/compound-engineering/agents/workflow/bug-reproduction-validator.md +82 -0
- package/plugins/compound-engineering/agents/workflow/every-style-editor.md +64 -0
- package/plugins/compound-engineering/agents/workflow/lint.md +16 -0
- package/plugins/compound-engineering/agents/workflow/pr-comment-resolver.md +84 -0
- package/plugins/compound-engineering/agents/workflow/spec-flow-analyzer.md +134 -0
- package/plugins/compound-engineering/commands/agent-native-audit.md +278 -0
- package/plugins/compound-engineering/commands/changelog.md +138 -0
- package/plugins/compound-engineering/commands/create-agent-skill.md +9 -0
- package/plugins/compound-engineering/commands/deepen-plan.md +546 -0
- package/plugins/compound-engineering/commands/deploy-docs.md +113 -0
- package/plugins/compound-engineering/commands/feature-video.md +342 -0
- package/plugins/compound-engineering/commands/generate_command.md +163 -0
- package/plugins/compound-engineering/commands/heal-skill.md +143 -0
- package/plugins/compound-engineering/commands/lfg.md +20 -0
- package/plugins/compound-engineering/commands/release-docs.md +212 -0
- package/plugins/compound-engineering/commands/report-bug.md +151 -0
- package/plugins/compound-engineering/commands/reproduce-bug.md +100 -0
- package/plugins/compound-engineering/commands/resolve_parallel.md +35 -0
- package/plugins/compound-engineering/commands/resolve_todo_parallel.md +37 -0
- package/plugins/compound-engineering/commands/slfg.md +32 -0
- package/plugins/compound-engineering/commands/technical_review.md +8 -0
- package/plugins/compound-engineering/commands/test-browser.md +339 -0
- package/plugins/compound-engineering/commands/test-xcode.md +332 -0
- package/plugins/compound-engineering/commands/triage.md +311 -0
- package/plugins/compound-engineering/commands/workflows/brainstorm.md +124 -0
- package/plugins/compound-engineering/commands/workflows/compound.md +239 -0
- package/plugins/compound-engineering/commands/workflows/plan.md +551 -0
- package/plugins/compound-engineering/commands/workflows/review.md +526 -0
- package/plugins/compound-engineering/commands/workflows/work.md +433 -0
- package/plugins/compound-engineering/skills/agent-browser/SKILL.md +223 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/SKILL.md +435 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/action-parity-discipline.md +409 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/agent-execution-patterns.md +467 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/agent-native-testing.md +582 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/architecture-patterns.md +478 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/dynamic-context-injection.md +338 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/files-universal-interface.md +301 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +359 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/mcp-tool-design.md +506 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/mobile-patterns.md +871 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/product-implications.md +443 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +317 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/self-modification.md +269 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/shared-workspace-architecture.md +680 -0
- package/plugins/compound-engineering/skills/agent-native-architecture/references/system-prompt-design.md +250 -0
- package/plugins/compound-engineering/skills/andrew-kane-gem-writer/SKILL.md +184 -0
- package/plugins/compound-engineering/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
- package/plugins/compound-engineering/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
- package/plugins/compound-engineering/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
- package/plugins/compound-engineering/skills/andrew-kane-gem-writer/references/resources.md +119 -0
- package/plugins/compound-engineering/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
- package/plugins/compound-engineering/skills/brainstorming/SKILL.md +190 -0
- package/plugins/compound-engineering/skills/compound-docs/SKILL.md +511 -0
- package/plugins/compound-engineering/skills/compound-docs/assets/critical-pattern-template.md +34 -0
- package/plugins/compound-engineering/skills/compound-docs/assets/resolution-template.md +93 -0
- package/plugins/compound-engineering/skills/compound-docs/references/yaml-schema.md +65 -0
- package/plugins/compound-engineering/skills/compound-docs/schema.yaml +176 -0
- package/plugins/compound-engineering/skills/create-agent-skills/SKILL.md +275 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/api-security.md +226 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/be-clear-and-direct.md +531 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/best-practices.md +404 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/common-patterns.md +595 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/core-principles.md +437 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/executable-code.md +175 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/iteration-and-testing.md +474 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/official-spec.md +134 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/recommended-structure.md +168 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/skill-structure.md +152 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/using-scripts.md +113 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/using-templates.md +112 -0
- package/plugins/compound-engineering/skills/create-agent-skills/references/workflows-and-validation.md +510 -0
- package/plugins/compound-engineering/skills/create-agent-skills/templates/router-skill.md +73 -0
- package/plugins/compound-engineering/skills/create-agent-skills/templates/simple-skill.md +33 -0
- package/plugins/compound-engineering/skills/create-agent-skills/workflows/add-reference.md +96 -0
- package/plugins/compound-engineering/skills/create-agent-skills/workflows/add-script.md +93 -0
- package/plugins/compound-engineering/skills/create-agent-skills/workflows/add-template.md +74 -0
- package/plugins/compound-engineering/skills/create-agent-skills/workflows/add-workflow.md +120 -0
- package/plugins/compound-engineering/skills/create-agent-skills/workflows/audit-skill.md +138 -0
- package/plugins/compound-engineering/skills/create-agent-skills/workflows/create-domain-expertise-skill.md +605 -0
- package/plugins/compound-engineering/skills/create-agent-skills/workflows/create-new-skill.md +191 -0
- package/plugins/compound-engineering/skills/create-agent-skills/workflows/get-guidance.md +121 -0
- package/plugins/compound-engineering/skills/create-agent-skills/workflows/upgrade-to-router.md +161 -0
- package/plugins/compound-engineering/skills/create-agent-skills/workflows/verify-skill.md +204 -0
- package/plugins/compound-engineering/skills/dhh-rails-style/SKILL.md +185 -0
- package/plugins/compound-engineering/skills/dhh-rails-style/references/architecture.md +653 -0
- package/plugins/compound-engineering/skills/dhh-rails-style/references/controllers.md +303 -0
- package/plugins/compound-engineering/skills/dhh-rails-style/references/frontend.md +510 -0
- package/plugins/compound-engineering/skills/dhh-rails-style/references/gems.md +266 -0
- package/plugins/compound-engineering/skills/dhh-rails-style/references/models.md +359 -0
- package/plugins/compound-engineering/skills/dhh-rails-style/references/testing.md +338 -0
- package/plugins/compound-engineering/skills/document-review/SKILL.md +87 -0
- package/plugins/compound-engineering/skills/dspy-ruby/SKILL.md +737 -0
- package/plugins/compound-engineering/skills/dspy-ruby/assets/config-template.rb +187 -0
- package/plugins/compound-engineering/skills/dspy-ruby/assets/module-template.rb +300 -0
- package/plugins/compound-engineering/skills/dspy-ruby/assets/signature-template.rb +221 -0
- package/plugins/compound-engineering/skills/dspy-ruby/references/core-concepts.md +674 -0
- package/plugins/compound-engineering/skills/dspy-ruby/references/observability.md +366 -0
- package/plugins/compound-engineering/skills/dspy-ruby/references/optimization.md +603 -0
- package/plugins/compound-engineering/skills/dspy-ruby/references/providers.md +418 -0
- package/plugins/compound-engineering/skills/dspy-ruby/references/toolsets.md +502 -0
- package/plugins/compound-engineering/skills/every-style-editor/SKILL.md +134 -0
- package/plugins/compound-engineering/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
- package/plugins/compound-engineering/skills/file-todos/SKILL.md +252 -0
- package/plugins/compound-engineering/skills/file-todos/assets/todo-template.md +155 -0
- package/plugins/compound-engineering/skills/frontend-design/SKILL.md +42 -0
- package/plugins/compound-engineering/skills/gemini-imagegen/SKILL.md +237 -0
- package/plugins/compound-engineering/skills/gemini-imagegen/requirements.txt +2 -0
- package/plugins/compound-engineering/skills/gemini-imagegen/scripts/compose_images.py +157 -0
- package/plugins/compound-engineering/skills/gemini-imagegen/scripts/edit_image.py +144 -0
- package/plugins/compound-engineering/skills/gemini-imagegen/scripts/gemini_images.py +263 -0
- package/plugins/compound-engineering/skills/gemini-imagegen/scripts/generate_image.py +133 -0
- package/plugins/compound-engineering/skills/gemini-imagegen/scripts/multi_turn_chat.py +216 -0
- package/plugins/compound-engineering/skills/git-worktree/SKILL.md +302 -0
- package/plugins/compound-engineering/skills/git-worktree/scripts/worktree-manager.sh +337 -0
- package/plugins/compound-engineering/skills/orchestrating-swarms/SKILL.md +1718 -0
- package/plugins/compound-engineering/skills/rclone/SKILL.md +150 -0
- package/plugins/compound-engineering/skills/rclone/scripts/check_setup.sh +60 -0
- package/plugins/compound-engineering/skills/resolve-pr-parallel/SKILL.md +89 -0
- package/plugins/compound-engineering/skills/resolve-pr-parallel/scripts/get-pr-comments +68 -0
- package/plugins/compound-engineering/skills/resolve-pr-parallel/scripts/resolve-pr-thread +23 -0
- package/plugins/compound-engineering/skills/skill-creator/SKILL.md +210 -0
- package/plugins/compound-engineering/skills/skill-creator/scripts/init_skill.py +303 -0
- package/plugins/compound-engineering/skills/skill-creator/scripts/package_skill.py +110 -0
- package/plugins/compound-engineering/skills/skill-creator/scripts/quick_validate.py +65 -0
- package/prompts/deepen-plan.md +549 -0
- package/prompts/feature-video.md +341 -0
- package/prompts/resolve_todo_parallel.md +36 -0
- package/prompts/test-browser.md +342 -0
- package/prompts/workflows-brainstorm.md +123 -0
- package/prompts/workflows-compound.md +238 -0
- package/prompts/workflows-plan.md +550 -0
- package/prompts/workflows-review.md +529 -0
- package/prompts/workflows-work.md +432 -0
- package/skills/agent-browser/SKILL.md +223 -0
- package/skills/agent-native-architecture/SKILL.md +435 -0
- package/skills/agent-native-architecture/references/action-parity-discipline.md +409 -0
- package/skills/agent-native-architecture/references/agent-execution-patterns.md +467 -0
- package/skills/agent-native-architecture/references/agent-native-testing.md +582 -0
- package/skills/agent-native-architecture/references/architecture-patterns.md +478 -0
- package/skills/agent-native-architecture/references/dynamic-context-injection.md +338 -0
- package/skills/agent-native-architecture/references/files-universal-interface.md +301 -0
- package/skills/agent-native-architecture/references/from-primitives-to-domain-tools.md +359 -0
- package/skills/agent-native-architecture/references/mcp-tool-design.md +506 -0
- package/skills/agent-native-architecture/references/mobile-patterns.md +871 -0
- package/skills/agent-native-architecture/references/product-implications.md +443 -0
- package/skills/agent-native-architecture/references/refactoring-to-prompt-native.md +317 -0
- package/skills/agent-native-architecture/references/self-modification.md +269 -0
- package/skills/agent-native-architecture/references/shared-workspace-architecture.md +680 -0
- package/skills/agent-native-architecture/references/system-prompt-design.md +250 -0
- package/skills/agent-native-reviewer/SKILL.md +260 -0
- package/skills/andrew-kane-gem-writer/SKILL.md +184 -0
- package/skills/andrew-kane-gem-writer/references/database-adapters.md +231 -0
- package/skills/andrew-kane-gem-writer/references/module-organization.md +121 -0
- package/skills/andrew-kane-gem-writer/references/rails-integration.md +183 -0
- package/skills/andrew-kane-gem-writer/references/resources.md +119 -0
- package/skills/andrew-kane-gem-writer/references/testing-patterns.md +261 -0
- package/skills/ankane-readme-writer/SKILL.md +63 -0
- package/skills/architecture-strategist/SKILL.md +66 -0
- package/skills/best-practices-researcher/SKILL.md +125 -0
- package/skills/brainstorming/SKILL.md +190 -0
- package/skills/bug-reproduction-validator/SKILL.md +81 -0
- package/skills/code-simplicity-reviewer/SKILL.md +100 -0
- package/skills/compound-docs/SKILL.md +511 -0
- package/skills/compound-docs/assets/critical-pattern-template.md +34 -0
- package/skills/compound-docs/assets/resolution-template.md +93 -0
- package/skills/compound-docs/references/yaml-schema.md +65 -0
- package/skills/compound-docs/schema.yaml +176 -0
- package/skills/create-agent-skills/SKILL.md +275 -0
- package/skills/create-agent-skills/references/api-security.md +226 -0
- package/skills/create-agent-skills/references/be-clear-and-direct.md +531 -0
- package/skills/create-agent-skills/references/best-practices.md +404 -0
- package/skills/create-agent-skills/references/common-patterns.md +595 -0
- package/skills/create-agent-skills/references/core-principles.md +437 -0
- package/skills/create-agent-skills/references/executable-code.md +175 -0
- package/skills/create-agent-skills/references/iteration-and-testing.md +474 -0
- package/skills/create-agent-skills/references/official-spec.md +134 -0
- package/skills/create-agent-skills/references/recommended-structure.md +168 -0
- package/skills/create-agent-skills/references/skill-structure.md +152 -0
- package/skills/create-agent-skills/references/using-scripts.md +113 -0
- package/skills/create-agent-skills/references/using-templates.md +112 -0
- package/skills/create-agent-skills/references/workflows-and-validation.md +510 -0
- package/skills/create-agent-skills/templates/router-skill.md +73 -0
- package/skills/create-agent-skills/templates/simple-skill.md +33 -0
- package/skills/create-agent-skills/workflows/add-reference.md +96 -0
- package/skills/create-agent-skills/workflows/add-script.md +93 -0
- package/skills/create-agent-skills/workflows/add-template.md +74 -0
- package/skills/create-agent-skills/workflows/add-workflow.md +120 -0
- package/skills/create-agent-skills/workflows/audit-skill.md +138 -0
- package/skills/create-agent-skills/workflows/create-domain-expertise-skill.md +605 -0
- package/skills/create-agent-skills/workflows/create-new-skill.md +191 -0
- package/skills/create-agent-skills/workflows/get-guidance.md +121 -0
- package/skills/create-agent-skills/workflows/upgrade-to-router.md +161 -0
- package/skills/create-agent-skills/workflows/verify-skill.md +204 -0
- package/skills/data-integrity-guardian/SKILL.md +84 -0
- package/skills/data-migration-expert/SKILL.md +111 -0
- package/skills/deployment-verification-agent/SKILL.md +173 -0
- package/skills/design-implementation-reviewer/SKILL.md +107 -0
- package/skills/design-iterator/SKILL.md +222 -0
- package/skills/dhh-rails-reviewer/SKILL.md +65 -0
- package/skills/dhh-rails-style/SKILL.md +185 -0
- package/skills/dhh-rails-style/references/architecture.md +653 -0
- package/skills/dhh-rails-style/references/controllers.md +303 -0
- package/skills/dhh-rails-style/references/frontend.md +510 -0
- package/skills/dhh-rails-style/references/gems.md +266 -0
- package/skills/dhh-rails-style/references/models.md +359 -0
- package/skills/dhh-rails-style/references/testing.md +338 -0
- package/skills/document-review/SKILL.md +87 -0
- package/skills/dspy-ruby/SKILL.md +737 -0
- package/skills/dspy-ruby/assets/config-template.rb +187 -0
- package/skills/dspy-ruby/assets/module-template.rb +300 -0
- package/skills/dspy-ruby/assets/signature-template.rb +221 -0
- package/skills/dspy-ruby/references/core-concepts.md +674 -0
- package/skills/dspy-ruby/references/observability.md +366 -0
- package/skills/dspy-ruby/references/optimization.md +603 -0
- package/skills/dspy-ruby/references/providers.md +418 -0
- package/skills/dspy-ruby/references/toolsets.md +502 -0
- package/skills/every-style-editor/SKILL.md +134 -0
- package/skills/every-style-editor/references/EVERY_WRITE_STYLE.md +529 -0
- package/skills/every-style-editor-2/SKILL.md +62 -0
- package/skills/figma-design-sync/SKILL.md +188 -0
- package/skills/file-todos/SKILL.md +252 -0
- package/skills/file-todos/assets/todo-template.md +155 -0
- package/skills/framework-docs-researcher/SKILL.md +105 -0
- package/skills/frontend-design/SKILL.md +42 -0
- package/skills/gemini-imagegen/SKILL.md +237 -0
- package/skills/gemini-imagegen/requirements.txt +2 -0
- package/skills/gemini-imagegen/scripts/compose_images.py +157 -0
- package/skills/gemini-imagegen/scripts/edit_image.py +144 -0
- package/skills/gemini-imagegen/scripts/gemini_images.py +263 -0
- package/skills/gemini-imagegen/scripts/generate_image.py +133 -0
- package/skills/gemini-imagegen/scripts/multi_turn_chat.py +216 -0
- package/skills/git-history-analyzer/SKILL.md +58 -0
- package/skills/git-worktree/SKILL.md +302 -0
- package/skills/git-worktree/scripts/worktree-manager.sh +337 -0
- package/skills/julik-frontend-races-reviewer/SKILL.md +220 -0
- package/skills/kieran-python-reviewer/SKILL.md +132 -0
- package/skills/kieran-rails-reviewer/SKILL.md +114 -0
- package/skills/kieran-typescript-reviewer/SKILL.md +123 -0
- package/skills/learnings-researcher/SKILL.md +263 -0
- package/skills/lint/SKILL.md +14 -0
- package/skills/orchestrating-swarms/SKILL.md +1718 -0
- package/skills/pattern-recognition-specialist/SKILL.md +71 -0
- package/skills/performance-oracle/SKILL.md +136 -0
- package/skills/pr-comment-resolver/SKILL.md +82 -0
- package/skills/rclone/SKILL.md +150 -0
- package/skills/rclone/scripts/check_setup.sh +60 -0
- package/skills/repo-research-analyst/SKILL.md +134 -0
- package/skills/resolve_pr_parallel/SKILL.md +89 -0
- package/skills/resolve_pr_parallel/scripts/get-pr-comments +68 -0
- package/skills/resolve_pr_parallel/scripts/resolve-pr-thread +23 -0
- package/skills/schema-drift-detector/SKILL.md +153 -0
- package/skills/security-sentinel/SKILL.md +113 -0
- package/skills/skill-creator/SKILL.md +210 -0
- package/skills/skill-creator/scripts/init_skill.py +303 -0
- package/skills/skill-creator/scripts/package_skill.py +110 -0
- package/skills/skill-creator/scripts/quick_validate.py +65 -0
- package/skills/spec-flow-analyzer/SKILL.md +133 -0
- package/src/commands/convert.ts +183 -0
- package/src/commands/install.ts +273 -0
- package/src/commands/list.ts +37 -0
- package/src/commands/sync.ts +89 -0
- package/src/converters/claude-to-codex.ts +182 -0
- package/src/converters/claude-to-opencode.ts +395 -0
- package/src/converters/claude-to-pi.ts +205 -0
- package/src/index.ts +22 -0
- package/src/parsers/claude-home.ts +65 -0
- package/src/parsers/claude.ts +252 -0
- package/src/sync/codex.ts +92 -0
- package/src/sync/opencode.ts +75 -0
- package/src/sync/pi.ts +88 -0
- package/src/targets/codex.ts +96 -0
- package/src/targets/index.ts +38 -0
- package/src/targets/opencode.ts +57 -0
- package/src/targets/pi.ts +131 -0
- package/src/templates/pi/compat-extension.ts +452 -0
- package/src/types/claude.ts +90 -0
- package/src/types/codex.ts +23 -0
- package/src/types/opencode.ts +54 -0
- package/src/types/pi.ts +40 -0
- package/src/utils/codex-agents.ts +64 -0
- package/src/utils/files.ts +77 -0
- package/src/utils/frontmatter.ts +65 -0
- package/src/utils/symlink.ts +43 -0
|
@@ -0,0 +1,674 @@
|
|
|
1
|
+
# DSPy.rb Core Concepts
|
|
2
|
+
|
|
3
|
+
## Signatures
|
|
4
|
+
|
|
5
|
+
Signatures define the interface between application code and language models. They specify inputs, outputs, and a task description using Sorbet types for compile-time and runtime type safety.
|
|
6
|
+
|
|
7
|
+
### Structure
|
|
8
|
+
|
|
9
|
+
```ruby
|
|
10
|
+
class ClassifyEmail < DSPy::Signature
|
|
11
|
+
description "Classify customer support emails by urgency and category"
|
|
12
|
+
|
|
13
|
+
input do
|
|
14
|
+
const :subject, String
|
|
15
|
+
const :body, String
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
output do
|
|
19
|
+
const :category, String
|
|
20
|
+
const :urgency, String
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Supported Types
|
|
26
|
+
|
|
27
|
+
| Type | JSON Schema | Notes |
|
|
28
|
+
|------|-------------|-------|
|
|
29
|
+
| `String` | `string` | Required string |
|
|
30
|
+
| `Integer` | `integer` | Whole numbers |
|
|
31
|
+
| `Float` | `number` | Decimal numbers |
|
|
32
|
+
| `T::Boolean` | `boolean` | true/false |
|
|
33
|
+
| `T::Array[X]` | `array` | Typed arrays |
|
|
34
|
+
| `T::Hash[K, V]` | `object` | Typed key-value maps |
|
|
35
|
+
| `T.nilable(X)` | nullable | Optional fields |
|
|
36
|
+
| `Date` | `string` (ISO 8601) | Auto-converted |
|
|
37
|
+
| `DateTime` | `string` (ISO 8601) | Preserves timezone |
|
|
38
|
+
| `Time` | `string` (ISO 8601) | Converted to UTC |
|
|
39
|
+
|
|
40
|
+
### Date and Time Types
|
|
41
|
+
|
|
42
|
+
Date, DateTime, and Time fields serialize to ISO 8601 strings and auto-convert back to Ruby objects on output.
|
|
43
|
+
|
|
44
|
+
```ruby
|
|
45
|
+
class EventScheduler < DSPy::Signature
|
|
46
|
+
description "Schedule events based on requirements"
|
|
47
|
+
|
|
48
|
+
input do
|
|
49
|
+
const :start_date, Date # ISO 8601: YYYY-MM-DD
|
|
50
|
+
const :preferred_time, DateTime # ISO 8601 with timezone
|
|
51
|
+
const :deadline, Time # Converted to UTC
|
|
52
|
+
const :end_date, T.nilable(Date) # Optional date
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
output do
|
|
56
|
+
const :scheduled_date, Date # String from LLM, auto-converted to Date
|
|
57
|
+
const :event_datetime, DateTime # Preserves timezone info
|
|
58
|
+
const :created_at, Time # Converted to UTC
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
predictor = DSPy::Predict.new(EventScheduler)
|
|
63
|
+
result = predictor.call(
|
|
64
|
+
start_date: "2024-01-15",
|
|
65
|
+
preferred_time: "2024-01-15T10:30:45Z",
|
|
66
|
+
deadline: Time.now,
|
|
67
|
+
end_date: nil
|
|
68
|
+
)
|
|
69
|
+
|
|
70
|
+
result.scheduled_date.class # => Date
|
|
71
|
+
result.event_datetime.class # => DateTime
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Timezone conventions follow ActiveRecord: Time objects convert to UTC, DateTime objects preserve timezone, Date objects are timezone-agnostic.
|
|
75
|
+
|
|
76
|
+
### Enums with T::Enum
|
|
77
|
+
|
|
78
|
+
Define constrained output values using `T::Enum` classes. Do not use inline `T.enum([...])` syntax.
|
|
79
|
+
|
|
80
|
+
```ruby
|
|
81
|
+
class SentimentAnalysis < DSPy::Signature
|
|
82
|
+
description "Analyze sentiment of text"
|
|
83
|
+
|
|
84
|
+
class Sentiment < T::Enum
|
|
85
|
+
enums do
|
|
86
|
+
Positive = new('positive')
|
|
87
|
+
Negative = new('negative')
|
|
88
|
+
Neutral = new('neutral')
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
input do
|
|
93
|
+
const :text, String
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
output do
|
|
97
|
+
const :sentiment, Sentiment
|
|
98
|
+
const :confidence, Float
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
predictor = DSPy::Predict.new(SentimentAnalysis)
|
|
103
|
+
result = predictor.call(text: "This product is amazing!")
|
|
104
|
+
|
|
105
|
+
result.sentiment # => #<Sentiment::Positive>
|
|
106
|
+
result.sentiment.serialize # => "positive"
|
|
107
|
+
result.confidence # => 0.92
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Enum matching is case-insensitive. The LLM returning `"POSITIVE"` matches `new('positive')`.
|
|
111
|
+
|
|
112
|
+
### Default Values
|
|
113
|
+
|
|
114
|
+
Default values work on both inputs and outputs. Input defaults reduce caller boilerplate. Output defaults provide fallbacks when the LLM omits optional fields.
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
class SmartSearch < DSPy::Signature
|
|
118
|
+
description "Search with intelligent defaults"
|
|
119
|
+
|
|
120
|
+
input do
|
|
121
|
+
const :query, String
|
|
122
|
+
const :max_results, Integer, default: 10
|
|
123
|
+
const :language, String, default: "English"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
output do
|
|
127
|
+
const :results, T::Array[String]
|
|
128
|
+
const :total_found, Integer
|
|
129
|
+
const :cached, T::Boolean, default: false
|
|
130
|
+
end
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
search = DSPy::Predict.new(SmartSearch)
|
|
134
|
+
result = search.call(query: "Ruby programming")
|
|
135
|
+
# max_results defaults to 10, language defaults to "English"
|
|
136
|
+
# If LLM omits `cached`, it defaults to false
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Field Descriptions
|
|
140
|
+
|
|
141
|
+
Add `description:` to any field to guide the LLM on expected content. These descriptions appear in the generated JSON schema sent to the model.
|
|
142
|
+
|
|
143
|
+
```ruby
|
|
144
|
+
class ASTNode < T::Struct
|
|
145
|
+
const :node_type, String, description: "The type of AST node (heading, paragraph, code_block)"
|
|
146
|
+
const :text, String, default: "", description: "Text content of the node"
|
|
147
|
+
const :level, Integer, default: 0, description: "Heading level 1-6, only for heading nodes"
|
|
148
|
+
const :children, T::Array[ASTNode], default: []
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
ASTNode.field_descriptions[:node_type] # => "The type of AST node ..."
|
|
152
|
+
ASTNode.field_descriptions[:children] # => nil (no description set)
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
Field descriptions also work inside signature `input` and `output` blocks:
|
|
156
|
+
|
|
157
|
+
```ruby
|
|
158
|
+
class ExtractEntities < DSPy::Signature
|
|
159
|
+
description "Extract named entities from text"
|
|
160
|
+
|
|
161
|
+
input do
|
|
162
|
+
const :text, String, description: "Raw text to analyze"
|
|
163
|
+
const :language, String, default: "en", description: "ISO 639-1 language code"
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
output do
|
|
167
|
+
const :entities, T::Array[String], description: "List of extracted entity names"
|
|
168
|
+
const :count, Integer, description: "Total number of unique entities found"
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### Schema Formats
|
|
174
|
+
|
|
175
|
+
DSPy.rb supports three schema formats for communicating type structure to LLMs.
|
|
176
|
+
|
|
177
|
+
#### JSON Schema (default)
|
|
178
|
+
|
|
179
|
+
Verbose but universally supported. Access via `YourSignature.output_json_schema`.
|
|
180
|
+
|
|
181
|
+
#### BAML Schema
|
|
182
|
+
|
|
183
|
+
Compact format that reduces schema tokens by 80-85%. Requires the `sorbet-baml` gem.
|
|
184
|
+
|
|
185
|
+
```ruby
|
|
186
|
+
DSPy.configure do |c|
|
|
187
|
+
c.lm = DSPy::LM.new('openai/gpt-4o-mini',
|
|
188
|
+
api_key: ENV['OPENAI_API_KEY'],
|
|
189
|
+
schema_format: :baml
|
|
190
|
+
)
|
|
191
|
+
end
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
BAML applies only in Enhanced Prompting mode (`structured_outputs: false`). When `structured_outputs: true`, the provider receives JSON Schema directly.
|
|
195
|
+
|
|
196
|
+
#### TOON Schema + Data Format
|
|
197
|
+
|
|
198
|
+
Table-oriented text format that shrinks both schema definitions and prompt values.
|
|
199
|
+
|
|
200
|
+
```ruby
|
|
201
|
+
DSPy.configure do |c|
|
|
202
|
+
c.lm = DSPy::LM.new('openai/gpt-4o-mini',
|
|
203
|
+
api_key: ENV['OPENAI_API_KEY'],
|
|
204
|
+
schema_format: :toon,
|
|
205
|
+
data_format: :toon
|
|
206
|
+
)
|
|
207
|
+
end
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
`schema_format: :toon` replaces the schema block in the system prompt. `data_format: :toon` renders input values and output templates inside `toon` fences. Only works with Enhanced Prompting mode. The `sorbet-toon` gem is included automatically as a dependency.
|
|
211
|
+
|
|
212
|
+
### Recursive Types
|
|
213
|
+
|
|
214
|
+
Structs that reference themselves produce `$defs` entries in the generated JSON schema, using `$ref` pointers to avoid infinite recursion.
|
|
215
|
+
|
|
216
|
+
```ruby
|
|
217
|
+
class ASTNode < T::Struct
|
|
218
|
+
const :node_type, String
|
|
219
|
+
const :text, String, default: ""
|
|
220
|
+
const :children, T::Array[ASTNode], default: []
|
|
221
|
+
end
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
The schema generator detects the self-reference in `T::Array[ASTNode]` and emits:
|
|
225
|
+
|
|
226
|
+
```json
|
|
227
|
+
{
|
|
228
|
+
"$defs": {
|
|
229
|
+
"ASTNode": { "type": "object", "properties": { ... } }
|
|
230
|
+
},
|
|
231
|
+
"properties": {
|
|
232
|
+
"children": {
|
|
233
|
+
"type": "array",
|
|
234
|
+
"items": { "$ref": "#/$defs/ASTNode" }
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Access the schema with accumulated definitions via `YourSignature.output_json_schema_with_defs`.
|
|
241
|
+
|
|
242
|
+
### Union Types with T.any()
|
|
243
|
+
|
|
244
|
+
Specify fields that accept multiple types:
|
|
245
|
+
|
|
246
|
+
```ruby
|
|
247
|
+
output do
|
|
248
|
+
const :result, T.any(Float, String)
|
|
249
|
+
end
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
For struct unions, DSPy.rb automatically adds a `_type` discriminator field to each struct's JSON schema. The LLM returns `_type` in its response, and DSPy converts the hash to the correct struct instance.
|
|
253
|
+
|
|
254
|
+
```ruby
|
|
255
|
+
class CreateTask < T::Struct
|
|
256
|
+
const :title, String
|
|
257
|
+
const :priority, String
|
|
258
|
+
end
|
|
259
|
+
|
|
260
|
+
class DeleteTask < T::Struct
|
|
261
|
+
const :task_id, String
|
|
262
|
+
const :reason, T.nilable(String)
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
class TaskRouter < DSPy::Signature
|
|
266
|
+
description "Route user request to the appropriate task action"
|
|
267
|
+
|
|
268
|
+
input do
|
|
269
|
+
const :request, String
|
|
270
|
+
end
|
|
271
|
+
|
|
272
|
+
output do
|
|
273
|
+
const :action, T.any(CreateTask, DeleteTask)
|
|
274
|
+
end
|
|
275
|
+
end
|
|
276
|
+
|
|
277
|
+
result = DSPy::Predict.new(TaskRouter).call(request: "Create a task for Q4 review")
|
|
278
|
+
result.action.class # => CreateTask
|
|
279
|
+
result.action.title # => "Q4 Review"
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Pattern matching works on the result:
|
|
283
|
+
|
|
284
|
+
```ruby
|
|
285
|
+
case result.action
|
|
286
|
+
when CreateTask then puts "Creating: #{result.action.title}"
|
|
287
|
+
when DeleteTask then puts "Deleting: #{result.action.task_id}"
|
|
288
|
+
end
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Union types also work inside arrays for heterogeneous collections:
|
|
292
|
+
|
|
293
|
+
```ruby
|
|
294
|
+
output do
|
|
295
|
+
const :events, T::Array[T.any(LoginEvent, PurchaseEvent)]
|
|
296
|
+
end
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Limit unions to 2-4 types for reliable LLM comprehension. Use clear struct names since they become the `_type` discriminator values.
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Modules
|
|
304
|
+
|
|
305
|
+
Modules are composable building blocks that wrap predictors. Define a `forward` method; invoke the module with `.call()`.
|
|
306
|
+
|
|
307
|
+
### Basic Structure
|
|
308
|
+
|
|
309
|
+
```ruby
|
|
310
|
+
class SentimentAnalyzer < DSPy::Module
|
|
311
|
+
def initialize
|
|
312
|
+
super
|
|
313
|
+
@predictor = DSPy::Predict.new(SentimentSignature)
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
def forward(text:)
|
|
317
|
+
@predictor.call(text: text)
|
|
318
|
+
end
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
analyzer = SentimentAnalyzer.new
|
|
322
|
+
result = analyzer.call(text: "I love this product!")
|
|
323
|
+
|
|
324
|
+
result.sentiment # => "positive"
|
|
325
|
+
result.confidence # => 0.9
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
**API rules:**
|
|
329
|
+
- Invoke modules and predictors with `.call()`, not `.forward()`.
|
|
330
|
+
- Access result fields with `result.field`, not `result[:field]`.
|
|
331
|
+
|
|
332
|
+
### Module Composition
|
|
333
|
+
|
|
334
|
+
Combine multiple modules through explicit method calls in `forward`:
|
|
335
|
+
|
|
336
|
+
```ruby
|
|
337
|
+
class DocumentProcessor < DSPy::Module
|
|
338
|
+
def initialize
|
|
339
|
+
super
|
|
340
|
+
@classifier = DocumentClassifier.new
|
|
341
|
+
@summarizer = DocumentSummarizer.new
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def forward(document:)
|
|
345
|
+
classification = @classifier.call(content: document)
|
|
346
|
+
summary = @summarizer.call(content: document)
|
|
347
|
+
|
|
348
|
+
{
|
|
349
|
+
document_type: classification.document_type,
|
|
350
|
+
summary: summary.summary
|
|
351
|
+
}
|
|
352
|
+
end
|
|
353
|
+
end
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Lifecycle Callbacks
|
|
357
|
+
|
|
358
|
+
Modules support `before`, `after`, and `around` callbacks on `forward`. Declare them as class-level macros referencing private methods.
|
|
359
|
+
|
|
360
|
+
#### Execution order
|
|
361
|
+
|
|
362
|
+
1. `before` callbacks (in registration order)
|
|
363
|
+
2. `around` callbacks (before `yield`)
|
|
364
|
+
3. `forward` method
|
|
365
|
+
4. `around` callbacks (after `yield`)
|
|
366
|
+
5. `after` callbacks (in registration order)
|
|
367
|
+
|
|
368
|
+
```ruby
|
|
369
|
+
class InstrumentedModule < DSPy::Module
|
|
370
|
+
before :setup_metrics
|
|
371
|
+
after :log_metrics
|
|
372
|
+
around :manage_context
|
|
373
|
+
|
|
374
|
+
def initialize
|
|
375
|
+
super
|
|
376
|
+
@predictor = DSPy::Predict.new(MySignature)
|
|
377
|
+
@metrics = {}
|
|
378
|
+
end
|
|
379
|
+
|
|
380
|
+
def forward(question:)
|
|
381
|
+
@predictor.call(question: question)
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
private
|
|
385
|
+
|
|
386
|
+
def setup_metrics
|
|
387
|
+
@metrics[:start_time] = Time.now
|
|
388
|
+
end
|
|
389
|
+
|
|
390
|
+
def manage_context
|
|
391
|
+
load_context
|
|
392
|
+
result = yield
|
|
393
|
+
save_context
|
|
394
|
+
result
|
|
395
|
+
end
|
|
396
|
+
|
|
397
|
+
def log_metrics
|
|
398
|
+
@metrics[:duration] = Time.now - @metrics[:start_time]
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
```
|
|
402
|
+
|
|
403
|
+
Multiple callbacks of the same type execute in registration order. Callbacks inherit from parent classes; parent callbacks run first.
|
|
404
|
+
|
|
405
|
+
#### Around callbacks
|
|
406
|
+
|
|
407
|
+
Around callbacks must call `yield` to execute the wrapped method and return the result:
|
|
408
|
+
|
|
409
|
+
```ruby
|
|
410
|
+
def with_retry
|
|
411
|
+
retries = 0
|
|
412
|
+
begin
|
|
413
|
+
yield
|
|
414
|
+
rescue StandardError => e
|
|
415
|
+
retries += 1
|
|
416
|
+
retry if retries < 3
|
|
417
|
+
raise e
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
### Instruction Update Contract
|
|
423
|
+
|
|
424
|
+
Teleprompters (GEPA, MIPROv2) require modules to expose immutable update hooks. Include `DSPy::Mixins::InstructionUpdatable` and implement `with_instruction` and `with_examples`, each returning a new instance:
|
|
425
|
+
|
|
426
|
+
```ruby
|
|
427
|
+
class SentimentPredictor < DSPy::Module
|
|
428
|
+
include DSPy::Mixins::InstructionUpdatable
|
|
429
|
+
|
|
430
|
+
def initialize
|
|
431
|
+
super
|
|
432
|
+
@predictor = DSPy::Predict.new(SentimentSignature)
|
|
433
|
+
end
|
|
434
|
+
|
|
435
|
+
def with_instruction(instruction)
|
|
436
|
+
clone = self.class.new
|
|
437
|
+
clone.instance_variable_set(:@predictor, @predictor.with_instruction(instruction))
|
|
438
|
+
clone
|
|
439
|
+
end
|
|
440
|
+
|
|
441
|
+
def with_examples(examples)
|
|
442
|
+
clone = self.class.new
|
|
443
|
+
clone.instance_variable_set(:@predictor, @predictor.with_examples(examples))
|
|
444
|
+
clone
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
If a module omits these hooks, teleprompters raise `DSPy::InstructionUpdateError` instead of silently mutating state.
|
|
450
|
+
|
|
451
|
+
---
|
|
452
|
+
|
|
453
|
+
## Predictors
|
|
454
|
+
|
|
455
|
+
Predictors are execution engines that take a signature and produce structured results from a language model. DSPy.rb provides four predictor types.
|
|
456
|
+
|
|
457
|
+
### Predict
|
|
458
|
+
|
|
459
|
+
Direct LLM call with typed input/output. Fastest option, lowest token usage.
|
|
460
|
+
|
|
461
|
+
```ruby
|
|
462
|
+
classifier = DSPy::Predict.new(ClassifyText)
|
|
463
|
+
result = classifier.call(text: "Technical document about APIs")
|
|
464
|
+
|
|
465
|
+
result.sentiment # => #<Sentiment::Positive>
|
|
466
|
+
result.topics # => ["APIs", "technical"]
|
|
467
|
+
result.confidence # => 0.92
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
### ChainOfThought
|
|
471
|
+
|
|
472
|
+
Adds a `reasoning` field to the output automatically. The model generates step-by-step reasoning before the final answer. Do not define a `:reasoning` field in the signature output when using ChainOfThought.
|
|
473
|
+
|
|
474
|
+
```ruby
|
|
475
|
+
class SolveMathProblem < DSPy::Signature
|
|
476
|
+
description "Solve mathematical word problems step by step"
|
|
477
|
+
|
|
478
|
+
input do
|
|
479
|
+
const :problem, String
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
output do
|
|
483
|
+
const :answer, String
|
|
484
|
+
# :reasoning is added automatically by ChainOfThought
|
|
485
|
+
end
|
|
486
|
+
end
|
|
487
|
+
|
|
488
|
+
solver = DSPy::ChainOfThought.new(SolveMathProblem)
|
|
489
|
+
result = solver.call(problem: "Sarah has 15 apples. She gives 7 away and buys 12 more.")
|
|
490
|
+
|
|
491
|
+
result.reasoning # => "Step by step: 15 - 7 = 8, then 8 + 12 = 20"
|
|
492
|
+
result.answer # => "20 apples"
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
Use ChainOfThought for complex analysis, multi-step reasoning, or when explainability matters.
|
|
496
|
+
|
|
497
|
+
### ReAct
|
|
498
|
+
|
|
499
|
+
Reasoning + Action agent that uses tools in an iterative loop. Define tools by subclassing `DSPy::Tools::Base`. Group related tools with `DSPy::Tools::Toolset`.
|
|
500
|
+
|
|
501
|
+
```ruby
|
|
502
|
+
class WeatherTool < DSPy::Tools::Base
|
|
503
|
+
extend T::Sig
|
|
504
|
+
|
|
505
|
+
tool_name "weather"
|
|
506
|
+
tool_description "Get weather information for a location"
|
|
507
|
+
|
|
508
|
+
sig { params(location: String).returns(String) }
|
|
509
|
+
def call(location:)
|
|
510
|
+
{ location: location, temperature: 72, condition: "sunny" }.to_json
|
|
511
|
+
end
|
|
512
|
+
end
|
|
513
|
+
|
|
514
|
+
class TravelSignature < DSPy::Signature
|
|
515
|
+
description "Help users plan travel"
|
|
516
|
+
|
|
517
|
+
input do
|
|
518
|
+
const :destination, String
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
output do
|
|
522
|
+
const :recommendations, String
|
|
523
|
+
end
|
|
524
|
+
end
|
|
525
|
+
|
|
526
|
+
agent = DSPy::ReAct.new(
|
|
527
|
+
TravelSignature,
|
|
528
|
+
tools: [WeatherTool.new],
|
|
529
|
+
max_iterations: 5
|
|
530
|
+
)
|
|
531
|
+
|
|
532
|
+
result = agent.call(destination: "Tokyo, Japan")
|
|
533
|
+
result.recommendations # => "Visit Senso-ji Temple early morning..."
|
|
534
|
+
result.history # => Array of reasoning steps, actions, observations
|
|
535
|
+
result.iterations # => 3
|
|
536
|
+
result.tools_used # => ["weather"]
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
Use toolsets to expose multiple tool methods from a single class:
|
|
540
|
+
|
|
541
|
+
```ruby
|
|
542
|
+
text_tools = DSPy::Tools::TextProcessingToolset.to_tools
|
|
543
|
+
agent = DSPy::ReAct.new(MySignature, tools: text_tools)
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
### CodeAct
|
|
547
|
+
|
|
548
|
+
Think-Code-Observe agent that synthesizes and executes Ruby code. Ships as a separate gem.
|
|
549
|
+
|
|
550
|
+
```ruby
|
|
551
|
+
# Gemfile
|
|
552
|
+
gem 'dspy-code_act', '~> 0.29'
|
|
553
|
+
```
|
|
554
|
+
|
|
555
|
+
```ruby
|
|
556
|
+
programmer = DSPy::CodeAct.new(ProgrammingSignature, max_iterations: 10)
|
|
557
|
+
result = programmer.call(task: "Calculate the factorial of 20")
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
### Predictor Comparison
|
|
561
|
+
|
|
562
|
+
| Predictor | Speed | Token Usage | Best For |
|
|
563
|
+
|-----------|-------|-------------|----------|
|
|
564
|
+
| Predict | Fastest | Low | Classification, extraction |
|
|
565
|
+
| ChainOfThought | Moderate | Medium-High | Complex reasoning, analysis |
|
|
566
|
+
| ReAct | Slower | High | Multi-step tasks with tools |
|
|
567
|
+
| CodeAct | Slowest | Very High | Dynamic programming, calculations |
|
|
568
|
+
|
|
569
|
+
### Concurrent Predictions
|
|
570
|
+
|
|
571
|
+
Process multiple independent predictions simultaneously using `Async::Barrier`:
|
|
572
|
+
|
|
573
|
+
```ruby
|
|
574
|
+
require 'async'
|
|
575
|
+
require 'async/barrier'
|
|
576
|
+
|
|
577
|
+
analyzer = DSPy::Predict.new(ContentAnalyzer)
|
|
578
|
+
documents = ["Text one", "Text two", "Text three"]
|
|
579
|
+
|
|
580
|
+
Async do
|
|
581
|
+
barrier = Async::Barrier.new
|
|
582
|
+
|
|
583
|
+
tasks = documents.map do |doc|
|
|
584
|
+
barrier.async { analyzer.call(content: doc) }
|
|
585
|
+
end
|
|
586
|
+
|
|
587
|
+
barrier.wait
|
|
588
|
+
predictions = tasks.map(&:wait)
|
|
589
|
+
|
|
590
|
+
predictions.each { |p| puts p.sentiment }
|
|
591
|
+
end
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
Add `gem 'async', '~> 2.29'` to the Gemfile. Handle errors within each `barrier.async` block to prevent one failure from cancelling others:
|
|
595
|
+
|
|
596
|
+
```ruby
|
|
597
|
+
barrier.async do
|
|
598
|
+
begin
|
|
599
|
+
analyzer.call(content: doc)
|
|
600
|
+
rescue StandardError => e
|
|
601
|
+
nil
|
|
602
|
+
end
|
|
603
|
+
end
|
|
604
|
+
```
|
|
605
|
+
|
|
606
|
+
### Few-Shot Examples and Instruction Tuning
|
|
607
|
+
|
|
608
|
+
```ruby
|
|
609
|
+
classifier = DSPy::Predict.new(SentimentAnalysis)
|
|
610
|
+
|
|
611
|
+
examples = [
|
|
612
|
+
DSPy::FewShotExample.new(
|
|
613
|
+
input: { text: "Love it!" },
|
|
614
|
+
output: { sentiment: "positive", confidence: 0.95 }
|
|
615
|
+
)
|
|
616
|
+
]
|
|
617
|
+
|
|
618
|
+
optimized = classifier.with_examples(examples)
|
|
619
|
+
tuned = classifier.with_instruction("Be precise and confident.")
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
---
|
|
623
|
+
|
|
624
|
+
## Type System
|
|
625
|
+
|
|
626
|
+
### Automatic Type Conversion
|
|
627
|
+
|
|
628
|
+
DSPy.rb v0.9.0+ automatically converts LLM JSON responses to typed Ruby objects:
|
|
629
|
+
|
|
630
|
+
- **Enums**: String values become `T::Enum` instances (case-insensitive)
|
|
631
|
+
- **Structs**: Nested hashes become `T::Struct` objects
|
|
632
|
+
- **Arrays**: Elements convert recursively
|
|
633
|
+
- **Defaults**: Missing fields use declared defaults
|
|
634
|
+
|
|
635
|
+
### Discriminators for Union Types
|
|
636
|
+
|
|
637
|
+
When a field uses `T.any()` with struct types, DSPy adds a `_type` field to each struct's schema. On deserialization, `_type` selects the correct struct class:
|
|
638
|
+
|
|
639
|
+
```json
|
|
640
|
+
{
|
|
641
|
+
"action": {
|
|
642
|
+
"_type": "CreateTask",
|
|
643
|
+
"title": "Review Q4 Report"
|
|
644
|
+
}
|
|
645
|
+
}
|
|
646
|
+
```
|
|
647
|
+
|
|
648
|
+
DSPy matches `"CreateTask"` against the union members and instantiates the correct struct. No manual discriminator field is needed.
|
|
649
|
+
|
|
650
|
+
### Recursive Types
|
|
651
|
+
|
|
652
|
+
Structs referencing themselves are supported. The schema generator tracks visited types and produces `$ref` pointers under `$defs`:
|
|
653
|
+
|
|
654
|
+
```ruby
|
|
655
|
+
class TreeNode < T::Struct
|
|
656
|
+
const :label, String
|
|
657
|
+
const :children, T::Array[TreeNode], default: []
|
|
658
|
+
end
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
The generated schema uses `"$ref": "#/$defs/TreeNode"` for the children array items, preventing infinite schema expansion.
|
|
662
|
+
|
|
663
|
+
### Nesting Depth
|
|
664
|
+
|
|
665
|
+
- 1-2 levels: reliable across all providers.
|
|
666
|
+
- 3-4 levels: works but increases schema complexity.
|
|
667
|
+
- 5+ levels: may trigger OpenAI depth validation warnings and reduce LLM accuracy. Flatten deeply nested structures or split into multiple signatures.
|
|
668
|
+
|
|
669
|
+
### Tips
|
|
670
|
+
|
|
671
|
+
- Prefer `T::Array[X], default: []` over `T.nilable(T::Array[X])` -- the nilable form causes schema issues with OpenAI structured outputs.
|
|
672
|
+
- Use clear struct names for union types since they become `_type` discriminator values.
|
|
673
|
+
- Limit union types to 2-4 members for reliable model comprehension.
|
|
674
|
+
- Check schema compatibility with `DSPy::OpenAI::LM::SchemaConverter.validate_compatibility(schema)`.
|