multi-forge 0.4.0__tar.gz → 0.5.0__tar.gz
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.
- {multi_forge-0.4.0 → multi_forge-0.5.0}/PKG-INFO +1 -1
- {multi_forge-0.4.0 → multi_forge-0.5.0}/pyproject.toml +1 -1
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/__init__.py +1 -1
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/activity.py +14 -3
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/gc.py +4 -4
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/hooks/direct_commands.py +3 -3
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/memory.py +6 -6
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/policy.py +1 -1
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/runtime.py +77 -2
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/session_manage.py +5 -5
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/status_line.py +5 -1
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/transfer.py +12 -4
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/anthropic-passthrough.yaml +3 -2
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/litellm-anthropic-local.yaml +5 -1
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/litellm-anthropic.yaml +6 -3
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/openrouter-anthropic.yaml +5 -3
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/auth/capabilities.py +17 -2
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/data/model_catalog.yaml +41 -3
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/invoker/__init__.py +3 -0
- multi_forge-0.4.0/src/forge/core/invoker/claude.py → multi_forge-0.5.0/src/forge/core/invoker/_lifecycle.py +150 -174
- multi_forge-0.5.0/src/forge/core/invoker/claude.py +154 -0
- multi_forge-0.5.0/src/forge/core/invoker/codex.py +218 -0
- multi_forge-0.5.0/src/forge/core/invoker/codex_stream.py +141 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/invoker/types.py +6 -0
- multi_forge-0.5.0/src/forge/core/ops/codex_bridge.py +244 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/ops/gc.py +9 -9
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/ops/resolution.py +7 -7
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/ops/session.py +7 -7
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/ops/transfer.py +18 -4
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/ops/usage_summary.py +135 -33
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/reactive/env.py +92 -17
- multi_forge-0.5.0/src/forge/core/run_id.py +44 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/runtime/__init__.py +18 -0
- multi_forge-0.5.0/src/forge/core/runtime/codex_preflight.py +509 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/runtime/registry.py +45 -25
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/usage/__init__.py +2 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/usage/emit.py +65 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/usage/ledger.py +5 -1
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/queries.py +2 -2
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/cost_logger.py +83 -1
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/data_models.py +4 -2
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/server.py +45 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/models.py +7 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/direct_model.py +4 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/manager.py +11 -6
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/transfer.py +152 -20
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/panel/SKILL.md +3 -3
- {multi_forge-0.4.0 → multi_forge-0.5.0}/.gitignore +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/LICENSE +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/NOTICE +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/README.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/agents/.gitkeep +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/commands/.gitkeep +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/backend/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/backend/adapters/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/backend/adapters/litellm.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/backend/creation.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/backend/registry.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/auth.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/backend.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/claude.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/config_cmd.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/editor.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/extensions.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/guards.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/hooks/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/hooks/_group.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/hooks/_helpers.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/hooks/commands.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/hooks/install.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/hooks/policy.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/hooks/protocols.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/hooks/read_hygiene.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/hooks/verification.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/launch_confirmation.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/logs.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/main.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/memory_report.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/memory_writer.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/output.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/proxy.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/proxy_audit.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/proxy_costs.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/search.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/session.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/session_addendum.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/session_fork.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/session_lifecycle.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/statusline/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/statusline/context.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/statusline/names.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/statusline/palette.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/statusline/registry.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/statusline/throttle.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/cli/workflow.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/dataclass_utils.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/backends/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/backends/litellm.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/litellm-gemini-flash-local.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/litellm-gemini-local.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/litellm-gemini-test.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/litellm-gemini.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/litellm-openai-codex-local.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/litellm-openai-local.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/litellm-openai.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/openrouter-deepseek.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/openrouter-gemini-flash.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/openrouter-gemini.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/openrouter-glm.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/openrouter-kimi.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/openrouter-minimax.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/openrouter-openai-codex.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/openrouter-openai.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/openrouter-qwen.yaml +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/loader.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/schema.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/auth/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/auth/credentials_file.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/auth/protocols.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/auth/secrets.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/auth/template_secrets.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/data/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/data/system_prompt_addendums/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/data/system_prompt_addendums/gemini.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/data/system_prompt_addendums/openai.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/llm/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/llm/clients/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/llm/clients/base.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/llm/clients/litellm.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/llm/clients/openai_compat.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/llm/clients/openrouter.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/llm/credentials.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/llm/detection.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/llm/errors.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/llm/protocols.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/llm/types.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/logging.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/models/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/models/catalog.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/models/types.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/naming.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/ops/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/ops/context.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/ops/proxy.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/ops/session_context.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/paths.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/process.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/reactive/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/reactive/cost_tracking.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/reactive/headless_json.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/reactive/proxy.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/reactive/routing.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/reactive/session_runner.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/reactive/structured_output.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/reactive/tagger.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/reactive/throttle.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/state/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/state/exceptions.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/state/io.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/state/lock.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/state/timestamps.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/transcript.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/typing_helpers.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/usage/billing.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/usage/correlation.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/usage/vocabulary.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/workqueue/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/workqueue/queue.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/core/workqueue/types.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/install/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/install/cli.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/install/exceptions.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/install/hooks.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/install/installer.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/install/models.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/install/preset.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/install/settings_merge.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/install/tracking.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/install/version.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/deterministic/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/deterministic/base.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/deterministic/coding_standards.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/deterministic/registry.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/deterministic/tdd.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/engine.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/protocols.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/semantic/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/semantic/promotion.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/semantic/supervisor.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/semantic/verdict.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/store.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/team/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/team/config.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/team/handlers.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/team/prompts.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/types.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/workflow/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/workflow/branches.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/workflow/config.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/workflow/divergence.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/workflow/policy.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/policy/workflow/stages.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/audit_logger.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/base_client.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/client_adapter.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/client_factory.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/converters.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/cost_tracker.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/error_hints.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/intercept.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/metrics.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/model_spec.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/passthrough.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/proxies.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/proxy_identity.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/proxy_orchestrator.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/proxy_startup.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/proxy/utils.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/adversarial.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/consensus.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/engine.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/resources/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/resources/codereview-performance.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/resources/codereview-quick.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/resources/codereview-security.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/resources/codereview.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/resources/docreview-quick.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/resources/docreview.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/resources/thinkdeep.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/routing.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/review/synthesis.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/runtime_config.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/search/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/search/bm25_store.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/search/content_store.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/search/engine.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/search/exceptions.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/search/extractor.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/search/index_state.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/search/store.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/search/tokenizer.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/active.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/artifacts.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/claude/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/claude/cleanup.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/claude/invoke.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/claude/paths.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/claude/relocate.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/cleanup.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/config.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/effective.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/exceptions.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/hooks/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/hooks/models.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/hooks/session_start.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/identity.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/index.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/memory_inheritance.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/memory_writer.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/models.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/overrides.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/passport.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/plan_resolution.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/prev_sessions.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/project_memory.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/shadow_curation.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/store.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/validation.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/worktree/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/worktree/cleanup.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/worktree/config_copy.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/session/worktree/create.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/sidecar/__init__.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/sidecar/container.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/sidecar/docker.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/sidecar/secrets.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/analyze/SKILL.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/challenge/SKILL.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/consensus/SKILL.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/consensus/resources/code_consensus_evaluation.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/consensus/resources/consensus_evaluation.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/consensus/resources/synthesis.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/debate/SKILL.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/debate/resources/code_debate_evaluation.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/debate/resources/debate_evaluation.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/panel/resources/synthesis.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/SKILL.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/0-enable.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/1-preflight.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/10-resume.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/11-config.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/12-search.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/13-policy.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/14-workflow.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/15-skills.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/16-memory.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/17-info.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/18-disable.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/19-uninstall.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/2-extension.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/20-cleanup.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/3-authentication.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/4-proxy.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/5-session.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/6-hook.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/7-costs.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/8-status-line.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist/9-direct-commands.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/checklist.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/resources/report-template.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/scripts/start-container.sh +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/qa/scripts/walkthrough-state.py +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review/SKILL.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review/references/claude-4.6.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review/references/claude-4.8.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review/references/gemini-3.1.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review/references/gpt-5.5.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review/references/skills-writing-guide.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review/resources/code-anthropic.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review/resources/code-gemini.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review/resources/code-openai.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review/resources/code.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review-docs/SKILL.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review-docs/resources/docs-anthropic.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review-docs/resources/docs-gemini.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review-docs/resources/docs-openai.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/review-docs/resources/docs.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/smoke-test/SKILL.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/smoke-test/scripts/smoke-test.sh +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/understand/SKILL.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/understand/resources/code-anthropic.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/understand/resources/code-gemini.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/understand/resources/code-openai.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/understand/resources/code.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/understand/resources/docs-anthropic.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/understand/resources/docs-gemini.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/understand/resources/docs-openai.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/understand/resources/docs.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/walkthrough/SKILL.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/walkthrough/resources/checklist.md +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/walkthrough/scripts/run-in-repo.sh +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/walkthrough/scripts/setup-test-repo.sh +0 -0
- {multi_forge-0.4.0 → multi_forge-0.5.0}/src/skills/walkthrough/scripts/walkthrough-state.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: multi-forge
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.5.0
|
|
4
4
|
Summary: Multi-runtime agent toolkit: proxy routing, cost control, session management, policy enforcement, and workflow orchestration
|
|
5
5
|
Project-URL: Homepage, https://github.com/hapa1i/multi-forge
|
|
6
6
|
Project-URL: Repository, https://github.com/hapa1i/multi-forge
|
|
@@ -100,7 +100,10 @@ def _render(summary: SessionActivitySummary, *, days: int | None) -> None:
|
|
|
100
100
|
for c in summary.commands:
|
|
101
101
|
errors = f"[red]{c.errors}[/red]" if c.errors else "0"
|
|
102
102
|
tokens = f"{c.input_tokens}/{c.output_tokens}" if (c.input_tokens or c.output_tokens) else "-"
|
|
103
|
-
|
|
103
|
+
if c.cost_micro_usd is None:
|
|
104
|
+
cost = "-"
|
|
105
|
+
else:
|
|
106
|
+
cost = f"{'~' if c.cost_estimated else ''}{_fmt_usd(c.cost_micro_usd)}"
|
|
104
107
|
row = [c.command, str(c.calls)]
|
|
105
108
|
if show_workers:
|
|
106
109
|
row.append(str(c.workers) if c.workers else "-")
|
|
@@ -120,7 +123,10 @@ def _render(summary: SessionActivitySummary, *, days: int | None) -> None:
|
|
|
120
123
|
if summary.subagents:
|
|
121
124
|
console.print(f"\n[bold]Subagents[/bold]: {summary.subagents}")
|
|
122
125
|
|
|
123
|
-
|
|
126
|
+
if summary.total_cost_micro_usd is None:
|
|
127
|
+
total_cost = "n/a"
|
|
128
|
+
else:
|
|
129
|
+
total_cost = f"{'~' if summary.cost_estimated else ''}{_fmt_usd(summary.total_cost_micro_usd)}"
|
|
124
130
|
console.print(
|
|
125
131
|
f"\n[dim]Total:[/dim] {summary.total_events} events · "
|
|
126
132
|
f"{summary.total_input_tokens}/{summary.total_output_tokens} tok · {total_cost}"
|
|
@@ -138,7 +144,12 @@ def _footnotes(summary: SessionActivitySummary) -> list[str]:
|
|
|
138
144
|
notes.append("policy decision log is at capacity — older decisions may not be shown")
|
|
139
145
|
if summary.session_tagging_partial:
|
|
140
146
|
notes.append("some calls (e.g. the action tagger) are not session-attributed")
|
|
141
|
-
|
|
147
|
+
# "no snapshot estimates" covers both exact sources: the 4g cost-plane root-join
|
|
148
|
+
# and runtime-reported (runtime_native) self-reports. A cost-less summary keeps
|
|
149
|
+
# the generic caveat -- there is no figure to call exact.
|
|
150
|
+
exact = summary.total_cost_micro_usd is not None and not summary.cost_estimated
|
|
151
|
+
evidence = "reported (no snapshot estimates mixed in)" if exact else "reported-or-estimated"
|
|
152
|
+
notes.append(f"cost is {evidence}, best-effort; 'forge proxy costs show' is the authoritative spend view")
|
|
142
153
|
return notes
|
|
143
154
|
|
|
144
155
|
|
|
@@ -16,9 +16,9 @@ from forge.core.ops.gc import CleanError, CleanReport, collect_clean_report, run
|
|
|
16
16
|
@click.command("clean")
|
|
17
17
|
@click.option(
|
|
18
18
|
"--scope",
|
|
19
|
-
type=click.Choice(["
|
|
20
|
-
default="
|
|
21
|
-
help="Scope:
|
|
19
|
+
type=click.Choice(["workspace", "project", "all"]),
|
|
20
|
+
default="workspace",
|
|
21
|
+
help="Scope: workspace (default), project, or all",
|
|
22
22
|
)
|
|
23
23
|
@click.option("--yes", "-y", is_flag=True, help="Actually delete (default is dry-run)")
|
|
24
24
|
@click.option("--verbose", "-v", is_flag=True, help="Show individual items")
|
|
@@ -31,7 +31,7 @@ def clean_cmd(scope: str, yes: bool, verbose: bool, as_json: bool) -> None:
|
|
|
31
31
|
Examples:
|
|
32
32
|
|
|
33
33
|
\b
|
|
34
|
-
forge clean # Dry-run (scope:
|
|
34
|
+
forge clean # Dry-run (scope: workspace)
|
|
35
35
|
forge clean --yes # Actually clean
|
|
36
36
|
forge clean --scope all --yes # Clean globally
|
|
37
37
|
forge clean --scope project # Current Forge project only
|
|
@@ -68,7 +68,7 @@ def _handle_cmd_help() -> None:
|
|
|
68
68
|
"reason": "Direct commands:\n"
|
|
69
69
|
"- %session show [name] | list\n"
|
|
70
70
|
"- %proxy list | show <id> | audit show|diff [id]\n"
|
|
71
|
-
"- %clean [--scope
|
|
71
|
+
"- %clean [--scope workspace|project|all]\n"
|
|
72
72
|
"- %plan\n"
|
|
73
73
|
"- %config (show runtime config)\n"
|
|
74
74
|
"- %policy status | enable | disable | check\n"
|
|
@@ -108,8 +108,8 @@ def _handle_cmd_session(data: dict[str, Any], argv: list[str]) -> None:
|
|
|
108
108
|
if "--no-incognito" in argv:
|
|
109
109
|
include_incognito = False
|
|
110
110
|
|
|
111
|
-
# Parse --scope VALUE or --scope=VALUE (default:
|
|
112
|
-
scope = "
|
|
111
|
+
# Parse --scope VALUE or --scope=VALUE (default: workspace)
|
|
112
|
+
scope = "workspace"
|
|
113
113
|
for i, arg in enumerate(argv):
|
|
114
114
|
if arg.startswith("--scope="):
|
|
115
115
|
scope = arg.split("=", 1)[1].lower()
|
|
@@ -85,7 +85,7 @@ def memory() -> None:
|
|
|
85
85
|
forge memory track docs/changelog.md --strategy changelog # author a passport (sessionless)
|
|
86
86
|
forge memory enable --session planner # enable memory for a session
|
|
87
87
|
forge memory list # show passported docs
|
|
88
|
-
forge memory status --scope
|
|
88
|
+
forge memory status --scope workspace # show activation across sessions
|
|
89
89
|
"""
|
|
90
90
|
|
|
91
91
|
|
|
@@ -590,7 +590,7 @@ def list_cmd(as_json: bool) -> None:
|
|
|
590
590
|
@memory.command("status")
|
|
591
591
|
@click.option(
|
|
592
592
|
"--scope",
|
|
593
|
-
type=click.Choice(["project", "
|
|
593
|
+
type=click.Choice(["project", "workspace", "all"]),
|
|
594
594
|
default="project",
|
|
595
595
|
show_default=True,
|
|
596
596
|
help="Scope for discovery.",
|
|
@@ -689,7 +689,7 @@ def _collect_shadow_entries(
|
|
|
689
689
|
@shadows_group.command("list")
|
|
690
690
|
@click.option(
|
|
691
691
|
"--scope",
|
|
692
|
-
type=click.Choice(["project", "
|
|
692
|
+
type=click.Choice(["project", "workspace", "all"]),
|
|
693
693
|
default="project",
|
|
694
694
|
show_default=True,
|
|
695
695
|
help="Scope for discovery.",
|
|
@@ -754,7 +754,7 @@ def shadows_list_cmd(scope: str, as_json: bool) -> None:
|
|
|
754
754
|
@click.option("--for", "for_doc", required=True, help="Official doc to show shadow content for.")
|
|
755
755
|
@click.option(
|
|
756
756
|
"--scope",
|
|
757
|
-
type=click.Choice(["project", "
|
|
757
|
+
type=click.Choice(["project", "workspace", "all"]),
|
|
758
758
|
default="project",
|
|
759
759
|
show_default=True,
|
|
760
760
|
help="Scope for discovery.",
|
|
@@ -820,7 +820,7 @@ def shadows_show_cmd(for_doc: str, scope: str) -> None:
|
|
|
820
820
|
@click.option("--session", "-s", "session_name", default=None, help="Session name.")
|
|
821
821
|
@click.option(
|
|
822
822
|
"--scope",
|
|
823
|
-
type=click.Choice(["project", "
|
|
823
|
+
type=click.Choice(["project", "workspace", "all"]),
|
|
824
824
|
default="project",
|
|
825
825
|
show_default=True,
|
|
826
826
|
help="Scope for shadow discovery.",
|
|
@@ -923,7 +923,7 @@ def _review_curate(
|
|
|
923
923
|
)
|
|
924
924
|
|
|
925
925
|
if scope == "all":
|
|
926
|
-
raise click.ClickException("Cross-project curation deferred; use --scope project or --scope
|
|
926
|
+
raise click.ClickException("Cross-project curation deferred; use --scope project or --scope workspace.")
|
|
927
927
|
|
|
928
928
|
ctx = ExecutionContext.from_cwd()
|
|
929
929
|
try:
|
|
@@ -59,7 +59,7 @@ def _resolve_session_for_display(
|
|
|
59
59
|
name: str,
|
|
60
60
|
cwd: Path,
|
|
61
61
|
) -> tuple[SessionStore, SessionState]:
|
|
62
|
-
"""Resolve a named session,
|
|
62
|
+
"""Resolve a named session, workspace-scoped with current-project preference.
|
|
63
63
|
|
|
64
64
|
Delegates to the shared two-tier resolver in core.ops.resolution.
|
|
65
65
|
"""
|
|
@@ -7,12 +7,19 @@ headless, hooks, usage source, native resume, install scopes).
|
|
|
7
7
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
|
+
import sys
|
|
11
|
+
|
|
10
12
|
import click
|
|
11
13
|
from rich.console import Console
|
|
12
14
|
from rich.markup import escape
|
|
13
15
|
from rich.table import Table
|
|
14
16
|
|
|
15
|
-
from forge.core.runtime import
|
|
17
|
+
from forge.core.runtime import (
|
|
18
|
+
CodexPreflight,
|
|
19
|
+
RuntimeSpec,
|
|
20
|
+
list_runtimes,
|
|
21
|
+
preflight_codex,
|
|
22
|
+
)
|
|
16
23
|
|
|
17
24
|
|
|
18
25
|
@click.group(context_settings={"help_option_names": ["-h", "--help"]})
|
|
@@ -99,7 +106,75 @@ def list_cmd(as_json: bool) -> None:
|
|
|
99
106
|
|
|
100
107
|
console.print(table)
|
|
101
108
|
# Escape note text: a free-text note may contain bracketed tokens (e.g.
|
|
102
|
-
# `[features]
|
|
109
|
+
# `[features] hooks`) that Rich would otherwise eat as markup.
|
|
103
110
|
for s in specs:
|
|
104
111
|
if s.note:
|
|
105
112
|
console.print(f"[dim]{s.id}: {escape(s.note)}[/dim]")
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def _render_preflight(console: Console, result: CodexPreflight) -> None:
|
|
116
|
+
"""Render a CodexPreflight as a labeled report (escapes free-text; carries no secret)."""
|
|
117
|
+
version = result.version or "-"
|
|
118
|
+
floor_met = "yes" if result.version_ok else "no"
|
|
119
|
+
ready = "[green]YES[/green]" if result.ready else "[red]NO[/red]"
|
|
120
|
+
|
|
121
|
+
console.print("[bold]Codex preflight[/bold]")
|
|
122
|
+
console.print(f" Installed: {'yes' if result.installed else 'no'}")
|
|
123
|
+
console.print(f" Version: {escape(version)} (hook floor met: {floor_met})")
|
|
124
|
+
console.print(
|
|
125
|
+
f" Auth: {escape(result.auth_method)} "
|
|
126
|
+
f"(source: {escape(result.auth_source)}, billing: {escape(result.billing_mode)})"
|
|
127
|
+
)
|
|
128
|
+
console.print(f" Hook seam: {escape(result.hook_seam)}")
|
|
129
|
+
console.print(f" Responses: {escape(result.proxy_responses)}")
|
|
130
|
+
if result.doctor_status:
|
|
131
|
+
console.print(f" Doctor: {escape(result.doctor_status)} [dim](informational)[/dim]")
|
|
132
|
+
console.print(f" Ready: {ready}")
|
|
133
|
+
if not result.ready and result.blocking_reason:
|
|
134
|
+
console.print()
|
|
135
|
+
console.print(escape(result.blocking_reason))
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
@runtime.command("preflight")
|
|
139
|
+
@click.argument("runtime_name", metavar="RUNTIME")
|
|
140
|
+
@click.option(
|
|
141
|
+
"--proxy",
|
|
142
|
+
"proxy_id",
|
|
143
|
+
default=None,
|
|
144
|
+
metavar="PROXY_ID",
|
|
145
|
+
help="Check Responses support against an existing proxy id (reads proxy.yaml; starts nothing).",
|
|
146
|
+
)
|
|
147
|
+
@click.option("--json", "as_json", is_flag=True, help="Output as JSON")
|
|
148
|
+
def preflight_cmd(runtime_name: str, proxy_id: str | None, as_json: bool) -> None:
|
|
149
|
+
"""Preflight a runtime for headless runs: auth, hooks, and Responses readiness.
|
|
150
|
+
|
|
151
|
+
Runs the dynamic, per-machine checks the static `forge runtime list` matrix cannot:
|
|
152
|
+
resolves a non-interactive credential, reads `codex doctor`, checks hook state, and
|
|
153
|
+
-- with --proxy -- whether that proxy can serve Codex its Responses API. Exits
|
|
154
|
+
non-zero when the runtime is not ready.
|
|
155
|
+
|
|
156
|
+
\b
|
|
157
|
+
Examples:
|
|
158
|
+
forge runtime preflight codex
|
|
159
|
+
forge runtime preflight codex --json
|
|
160
|
+
forge runtime preflight codex --proxy my-openai-proxy
|
|
161
|
+
"""
|
|
162
|
+
if runtime_name != "codex":
|
|
163
|
+
# Codex is the only runtime with a preflight today; this is the dispatch seam.
|
|
164
|
+
raise click.BadParameter(
|
|
165
|
+
f"No preflight available for '{runtime_name}' (supported: codex).",
|
|
166
|
+
param_hint="RUNTIME",
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
result = preflight_codex(proxy_id=proxy_id)
|
|
170
|
+
|
|
171
|
+
if as_json:
|
|
172
|
+
import json
|
|
173
|
+
from dataclasses import asdict
|
|
174
|
+
|
|
175
|
+
click.echo(json.dumps(asdict(result), indent=2))
|
|
176
|
+
else:
|
|
177
|
+
_render_preflight(Console(), result)
|
|
178
|
+
|
|
179
|
+
if not result.ready:
|
|
180
|
+
sys.exit(1)
|
|
@@ -415,9 +415,9 @@ def _delete_single_session(
|
|
|
415
415
|
)
|
|
416
416
|
@click.option(
|
|
417
417
|
"--scope",
|
|
418
|
-
type=click.Choice(["
|
|
419
|
-
default="
|
|
420
|
-
help="Scope:
|
|
418
|
+
type=click.Choice(["workspace", "project", "all"], case_sensitive=False),
|
|
419
|
+
default="workspace",
|
|
420
|
+
help="Scope: workspace (default, all worktrees of the same repo), project (same forge_root), all (global)",
|
|
421
421
|
)
|
|
422
422
|
@click.option("--json", "as_json", is_flag=True, help="Output as JSON")
|
|
423
423
|
def list_sessions(include_incognito: bool, older_than: int | None, scope: str, as_json: bool) -> None:
|
|
@@ -788,7 +788,7 @@ def show(session_id: str | None, as_json: bool, field_path: str | None) -> None:
|
|
|
788
788
|
|
|
789
789
|
# Resolve the forge_root once -- either from get_session_context's prior
|
|
790
790
|
# UUID/name lookup (preserves exact scope for UUIDs) or via the two-tier
|
|
791
|
-
#
|
|
791
|
+
# workspace-wide resolver as fallback.
|
|
792
792
|
from forge.core.ops.resolution import resolve_session_repo_wide
|
|
793
793
|
from forge.core.ops.session_context import resolve_session_identifier
|
|
794
794
|
|
|
@@ -815,7 +815,7 @@ def show(session_id: str | None, as_json: bool, field_path: str | None) -> None:
|
|
|
815
815
|
return st, ent, is_cross
|
|
816
816
|
except ForgeSessionError:
|
|
817
817
|
pass
|
|
818
|
-
# Fallback: two-tier
|
|
818
|
+
# Fallback: two-tier workspace-wide resolution
|
|
819
819
|
try:
|
|
820
820
|
res = resolve_session_repo_wide(ctx.session_name, _fr, manager=manager)
|
|
821
821
|
return res.state, res.entry, res.is_cross_project
|
|
@@ -338,7 +338,8 @@ def get_tier_display(runtime: ProxyRuntimeTruth | None) -> str | None:
|
|
|
338
338
|
def get_tier_from_display_name(display_name: str) -> str:
|
|
339
339
|
"""Map Claude Code's display name to tier."""
|
|
340
340
|
display_lower = display_name.lower()
|
|
341
|
-
|
|
341
|
+
# Fable carries no tier word of its own; it rides the opus tier.
|
|
342
|
+
if "opus" in display_lower or "fable" in display_lower:
|
|
342
343
|
return "opus"
|
|
343
344
|
elif "sonnet" in display_lower:
|
|
344
345
|
return "sonnet"
|
|
@@ -360,6 +361,9 @@ def explicit_tier_from_model(model_id: str) -> str | None:
|
|
|
360
361
|
for tier in ("haiku", "sonnet", "opus"):
|
|
361
362
|
if tier in name:
|
|
362
363
|
return tier
|
|
364
|
+
# Fable carries no tier word of its own; it rides the opus tier.
|
|
365
|
+
if "fable" in name:
|
|
366
|
+
return "opus"
|
|
363
367
|
return None
|
|
364
368
|
|
|
365
369
|
|
|
@@ -31,7 +31,7 @@ from forge.core.ops.transfer import (
|
|
|
31
31
|
show_transfer,
|
|
32
32
|
)
|
|
33
33
|
from forge.core.paths import display_path
|
|
34
|
-
from forge.session.transfer import ResumeStrategy
|
|
34
|
+
from forge.session.transfer import TRANSFER_TARGET_RUNTIMES, ResumeStrategy
|
|
35
35
|
|
|
36
36
|
_STRATEGY_CHOICES = [s.value for s in ResumeStrategy]
|
|
37
37
|
|
|
@@ -112,11 +112,19 @@ def show_cmd(parent: str, child: str | None, as_json: bool) -> None:
|
|
|
112
112
|
help="Override strategy (default: the cache's current strategy).",
|
|
113
113
|
)
|
|
114
114
|
@click.option("--depth", type=int, default=None, help="Override lineage depth (default: the cache's current depth).")
|
|
115
|
-
|
|
115
|
+
@click.option(
|
|
116
|
+
"--target-runtime",
|
|
117
|
+
type=click.Choice(list(TRANSFER_TARGET_RUNTIMES)),
|
|
118
|
+
default=None,
|
|
119
|
+
help="Which runtime will consume this context (default: the cache's current target runtime).",
|
|
120
|
+
)
|
|
121
|
+
def regenerate_cmd(parent: str, strategy: str | None, depth: int | None, target_runtime: str | None) -> None:
|
|
116
122
|
"""Rebuild the parent cache (generated.md). Never touches children or notes."""
|
|
117
123
|
ctx = ExecutionContext.from_cwd()
|
|
118
124
|
try:
|
|
119
|
-
result = regenerate_transfer(
|
|
125
|
+
result = regenerate_transfer(
|
|
126
|
+
ctx=ctx, parent=parent, strategy=strategy, depth=depth, target_runtime=target_runtime
|
|
127
|
+
)
|
|
120
128
|
except ForgeOpError as e:
|
|
121
129
|
print_error_with_tip(
|
|
122
130
|
str(e),
|
|
@@ -127,7 +135,7 @@ def regenerate_cmd(parent: str, strategy: str | None, depth: int | None) -> None
|
|
|
127
135
|
|
|
128
136
|
console.print(
|
|
129
137
|
f"Regenerated [green]{display_path(result.path)}[/green] "
|
|
130
|
-
f"[dim](strategy={result.strategy}, depth={result.depth})[/dim]"
|
|
138
|
+
f"[dim](strategy={result.strategy}, depth={result.depth}, runtime={result.target_runtime})[/dim]"
|
|
131
139
|
)
|
|
132
140
|
for warning in result.warnings:
|
|
133
141
|
console.print(f"[yellow]Warning:[/yellow] {warning}")
|
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
# `provider: litellm` is only a config slot used for credential and upstream
|
|
9
9
|
# resolution — `wire_shape: anthropic_passthrough` is the authoritative wire truth
|
|
10
10
|
# (GET / reports it). Tiers are informational here; the client's model is forwarded
|
|
11
|
-
# unchanged
|
|
11
|
+
# unchanged (so --model claude-fable-5 reaches the API as-is; no model_alternatives
|
|
12
|
+
# remap applies on this wire shape). Requires ANTHROPIC_API_KEY in .env (or environment).
|
|
12
13
|
|
|
13
14
|
proxy:
|
|
14
15
|
family: anthropic
|
|
@@ -26,5 +27,5 @@ proxy:
|
|
|
26
27
|
tiers:
|
|
27
28
|
haiku: claude-haiku-4-5
|
|
28
29
|
sonnet: claude-sonnet-4-6
|
|
29
|
-
opus: claude-
|
|
30
|
+
opus: claude-fable-5
|
|
30
31
|
base_url: "https://api.anthropic.com"
|
|
@@ -6,6 +6,9 @@
|
|
|
6
6
|
#
|
|
7
7
|
# Backend (LiteLLM on port 4000) starts automatically.
|
|
8
8
|
#
|
|
9
|
+
# Opus tier defaults to Fable 5. Use --model claude-opus-4-8 or
|
|
10
|
+
# --model claude-opus-4-6 to select an Opus alternative instead.
|
|
11
|
+
#
|
|
9
12
|
# Note: If you added ANTHROPIC_API_KEY after the backend started,
|
|
10
13
|
# restart with: forge backend stop litellm-4000
|
|
11
14
|
|
|
@@ -25,9 +28,10 @@ proxy:
|
|
|
25
28
|
tiers:
|
|
26
29
|
haiku: anthropic/claude-haiku-4-5
|
|
27
30
|
sonnet: anthropic/claude-sonnet-4-6
|
|
28
|
-
opus: anthropic/claude-
|
|
31
|
+
opus: anthropic/claude-fable-5
|
|
29
32
|
model_alternatives:
|
|
30
33
|
opus:
|
|
31
34
|
claude-opus-4-8: anthropic/claude-opus-4-8
|
|
35
|
+
claude-opus-4-6: anthropic/claude-opus-4-6
|
|
32
36
|
prompt_caching: passthrough
|
|
33
37
|
error_hints: true
|
{multi_forge-0.4.0 → multi_forge-0.5.0}/src/forge/config/defaults/templates/litellm-anthropic.yaml
RENAMED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# Template: litellm-anthropic
|
|
2
2
|
# Anthropic Claude via remote/shared LiteLLM
|
|
3
3
|
#
|
|
4
|
-
# Access to Claude Opus 4.
|
|
4
|
+
# Access to Claude Fable 5, Opus 4.8/4.6, Sonnet 4.6, and Haiku 4.5.
|
|
5
5
|
# Requires LITELLM_API_KEY and LITELLM_BASE_URL in .env (or environment).
|
|
6
|
+
# NOTE: the shared LiteLLM instance must serve anthropic/claude-fable-5.
|
|
6
7
|
#
|
|
7
|
-
# Use --model claude-opus-4-8
|
|
8
|
+
# Opus tier defaults to Fable 5. Use --model claude-opus-4-8 or
|
|
9
|
+
# --model claude-opus-4-6 to select an Opus alternative instead.
|
|
8
10
|
# prompt_caching: passthrough respects Anthropic's 4-breakpoint cache_control limit.
|
|
9
11
|
|
|
10
12
|
proxy:
|
|
@@ -16,9 +18,10 @@ proxy:
|
|
|
16
18
|
tiers:
|
|
17
19
|
haiku: anthropic/claude-haiku-4-5
|
|
18
20
|
sonnet: anthropic/claude-sonnet-4-6
|
|
19
|
-
opus: anthropic/claude-
|
|
21
|
+
opus: anthropic/claude-fable-5
|
|
20
22
|
model_alternatives:
|
|
21
23
|
opus:
|
|
22
24
|
claude-opus-4-8: anthropic/claude-opus-4-8
|
|
25
|
+
claude-opus-4-6: anthropic/claude-opus-4-6
|
|
23
26
|
prompt_caching: passthrough
|
|
24
27
|
error_hints: true
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# Template: openrouter-anthropic
|
|
2
2
|
# Anthropic Claude models via OpenRouter (direct, no LiteLLM)
|
|
3
3
|
#
|
|
4
|
-
# Access to Claude Opus 4.
|
|
4
|
+
# Access to Claude Fable 5, Opus 4.8/4.6, Sonnet 4.6, and Haiku 4.5.
|
|
5
5
|
# Requires OPENROUTER_API_KEY in .env (or environment).
|
|
6
6
|
#
|
|
7
|
-
# Use --model claude-opus-4-8
|
|
7
|
+
# Opus tier defaults to Fable 5. Use --model claude-opus-4-8 or
|
|
8
|
+
# --model claude-opus-4-6 to select an Opus alternative instead.
|
|
8
9
|
|
|
9
10
|
proxy:
|
|
10
11
|
family: anthropic
|
|
@@ -15,9 +16,10 @@ proxy:
|
|
|
15
16
|
tiers:
|
|
16
17
|
haiku: anthropic/claude-haiku-4.5
|
|
17
18
|
sonnet: anthropic/claude-sonnet-4.6
|
|
18
|
-
opus: anthropic/claude-
|
|
19
|
+
opus: anthropic/claude-fable-5
|
|
19
20
|
model_alternatives:
|
|
20
21
|
opus:
|
|
21
22
|
claude-opus-4-8: anthropic/claude-opus-4.8
|
|
23
|
+
claude-opus-4-6: anthropic/claude-opus-4.6
|
|
22
24
|
base_url: "https://openrouter.ai/api/v1"
|
|
23
25
|
error_hints: true
|
|
@@ -84,6 +84,21 @@ CREDENTIALS: dict[str, Credential] = {
|
|
|
84
84
|
signup_url="https://aistudio.google.com/apikey",
|
|
85
85
|
note="Gemini API key for local LiteLLM proxy routing",
|
|
86
86
|
),
|
|
87
|
+
"codex-api": Credential(
|
|
88
|
+
name="codex-api",
|
|
89
|
+
env_vars=(EnvVar("CODEX_API_KEY"),),
|
|
90
|
+
unlocks_features=("Native Codex headless runs (codex exec)",),
|
|
91
|
+
signup_url="https://platform.openai.com/api-keys",
|
|
92
|
+
note=(
|
|
93
|
+
"Non-interactive Codex override. Codex keeps its OWN credential store; run "
|
|
94
|
+
"'codex doctor' to see resolved auth. Not your ChatGPT login (codex login "
|
|
95
|
+
"--device-auth) and not OPENAI_API_KEY."
|
|
96
|
+
),
|
|
97
|
+
not_needed_for=(
|
|
98
|
+
"Codex already logged in via 'codex login'",
|
|
99
|
+
"Codex via ChatGPT subscription (codex login --device-auth)",
|
|
100
|
+
),
|
|
101
|
+
),
|
|
87
102
|
"litellm-remote": Credential(
|
|
88
103
|
name="litellm-remote",
|
|
89
104
|
env_vars=(
|
|
@@ -158,8 +173,8 @@ def format_missing_credential_error(
|
|
|
158
173
|
"""Build an actionable error message for missing credentials.
|
|
159
174
|
|
|
160
175
|
Includes what failed, which key(s), signup URL, and the exact
|
|
161
|
-
``forge auth login`` command. Renders ``not_needed_for``
|
|
162
|
-
anthropic-api
|
|
176
|
+
``forge auth login`` command. Renders ``not_needed_for`` when the credential
|
|
177
|
+
defines it (anthropic-api, codex-api -- where false urgency is common).
|
|
163
178
|
"""
|
|
164
179
|
key_word = "key" if len(missing_vars) == 1 else "keys"
|
|
165
180
|
var_list = ", ".join(missing_vars)
|
|
@@ -761,7 +761,7 @@ models:
|
|
|
761
761
|
# minimal/low/none/disable -> low, medium/high -> high
|
|
762
762
|
litellm_reasoning_efforts: [none, disable, minimal, low, medium, high]
|
|
763
763
|
default_reasoning_effort: high
|
|
764
|
-
intelligence_score:
|
|
764
|
+
intelligence_score: 99 # Peer of gpt-5.5 / Claude Opus 4.8
|
|
765
765
|
system_prompt_addendum: system_prompt_addendums/gemini.md
|
|
766
766
|
tags: []
|
|
767
767
|
|
|
@@ -785,7 +785,7 @@ models:
|
|
|
785
785
|
default_thinking_level: high
|
|
786
786
|
litellm_reasoning_efforts: [none, disable, minimal, low, medium, high]
|
|
787
787
|
default_reasoning_effort: high
|
|
788
|
-
intelligence_score:
|
|
788
|
+
intelligence_score: 99 # Tracks gemini-3.1-pro-preview
|
|
789
789
|
system_prompt_addendum: system_prompt_addendums/gemini.md
|
|
790
790
|
tags: [agentic, custom-tools]
|
|
791
791
|
|
|
@@ -976,9 +976,41 @@ models:
|
|
|
976
976
|
litellm_reasoning_efforts: [low, medium, high, xhigh]
|
|
977
977
|
default_reasoning_effort: high
|
|
978
978
|
token_estimate_multiplier: 1.35
|
|
979
|
-
intelligence_score:
|
|
979
|
+
intelligence_score: 99 # Below Fable 5; peer of gpt-5.5 / Gemini 3.1 Pro
|
|
980
980
|
tags: [bounded-review, opt-in]
|
|
981
981
|
|
|
982
|
+
# --- Claude Fable Series ---
|
|
983
|
+
# Fable 5 is the most capable model (a tier above Opus). Same request surface
|
|
984
|
+
# as Opus 4.8 -- adaptive thinking only, sampling overrides removed. Used as
|
|
985
|
+
# the OpenRouter opus-tier default (see templates/openrouter-anthropic.yaml);
|
|
986
|
+
# Opus 4.8/4.6 stay selectable via --model. Not a catalog default: anthropic
|
|
987
|
+
# defaults stay on 4.6 until this profile is proven for resume-heavy flows.
|
|
988
|
+
claude-fable-5:
|
|
989
|
+
friendly_name: Claude Fable 5
|
|
990
|
+
context_window_tokens: 1000000
|
|
991
|
+
max_output_tokens: 128000
|
|
992
|
+
max_thinking_tokens: 128000
|
|
993
|
+
supports_thinking: true
|
|
994
|
+
supports_images: true
|
|
995
|
+
supports_1m_context: true
|
|
996
|
+
temperature_constraint: fixed
|
|
997
|
+
temperature: 1.0
|
|
998
|
+
supports_top_p: false
|
|
999
|
+
supports_sampling_overrides: false
|
|
1000
|
+
default_timeout_seconds: 240
|
|
1001
|
+
prompt_caching:
|
|
1002
|
+
supports: true
|
|
1003
|
+
mechanism: cache_control
|
|
1004
|
+
min_tokens: 1024
|
|
1005
|
+
max_cache_blocks: 4
|
|
1006
|
+
native_thinking_param: output_config.effort
|
|
1007
|
+
thinking_modes: [adaptive]
|
|
1008
|
+
litellm_reasoning_efforts: [low, medium, high, xhigh]
|
|
1009
|
+
default_reasoning_effort: high
|
|
1010
|
+
token_estimate_multiplier: 1.35
|
|
1011
|
+
intelligence_score: 100
|
|
1012
|
+
tags: [opt-in]
|
|
1013
|
+
|
|
982
1014
|
claude-sonnet-4-6:
|
|
983
1015
|
friendly_name: Claude Sonnet 4.6
|
|
984
1016
|
context_window_tokens: 200000
|
|
@@ -1547,6 +1579,12 @@ aliases:
|
|
|
1547
1579
|
opus-4-8: claude-opus-4-8
|
|
1548
1580
|
opus-4.8: claude-opus-4-8
|
|
1549
1581
|
|
|
1582
|
+
# Fable 5 (most capable; OpenRouter opus-tier default, direct --model fable)
|
|
1583
|
+
anthropic/claude-fable-5: claude-fable-5
|
|
1584
|
+
claude-fable: claude-fable-5
|
|
1585
|
+
fable-5: claude-fable-5
|
|
1586
|
+
fable: claude-fable-5
|
|
1587
|
+
|
|
1550
1588
|
# Sonnet 4.6
|
|
1551
1589
|
anthropic/claude-sonnet-4-6: claude-sonnet-4-6
|
|
1552
1590
|
anthropic/claude-sonnet-4-6-1m: claude-sonnet-4-6-1m
|
|
@@ -7,6 +7,7 @@ ordered fan-out, timeouts) and per-job usage emission. Phase 5 adds a
|
|
|
7
7
|
"""
|
|
8
8
|
|
|
9
9
|
from .claude import ClaudeHeadlessInvoker
|
|
10
|
+
from .codex import CodexHeadlessInvoker, prepare_codex_request
|
|
10
11
|
from .types import (
|
|
11
12
|
Attribution,
|
|
12
13
|
HeadlessInvoker,
|
|
@@ -17,7 +18,9 @@ from .types import (
|
|
|
17
18
|
__all__ = [
|
|
18
19
|
"Attribution",
|
|
19
20
|
"ClaudeHeadlessInvoker",
|
|
21
|
+
"CodexHeadlessInvoker",
|
|
20
22
|
"HeadlessInvoker",
|
|
21
23
|
"HeadlessRequest",
|
|
22
24
|
"HeadlessResult",
|
|
25
|
+
"prepare_codex_request",
|
|
23
26
|
]
|