alishahryar1--free-claude-code
6455c63e1d
## Problem FCC reduced reasoning to global and route booleans, mixing client intent, configuration, provider wire capabilities, output visibility, and history replay. That discarded named client efforts, encouraged model-name checks, and made provider behavior inconsistent. ## Changes | Before | After | | --- | --- | | Admin exposed global and route thinking toggles. | Admin exposes **Off**, **From client**, **Low**, **Medium**, **High**, **X-High**, and **Max**; Fable, Opus, Sonnet, and Haiku also expose **Inherit**. | | Request intent was repeatedly reduced to a boolean across routing and providers. | The application boundary resolves one immutable `ReasoningPolicy` with independent control, named effort, and exact positive token budget. | | Provider adapters could infer reasoning behavior from upstream model names or versions. | Provider profiles translate only documented provider-wide wire capabilities; architecture and contributor rules prohibit model-specific reasoning branches. | | Gateway reasoning controls were ad hoc. | [OpenRouter](https://openrouter.ai/docs/guides/best-practices/reasoning-tokens) and [Vercel AI Gateway](https://vercel.com/docs/ai-gateway/models-and-providers) use documented reasoning objects, including exact budgets where representable. | | Named effort forwarding was inconsistent or absent. | [Gemini](https://ai.google.dev/gemini-api/docs/openai), [Ollama](https://docs.ollama.com/api/openai-compatibility), [LM Studio](https://lmstudio.ai/changelog/lmstudio-v0.4.8), [Fireworks](https://docs.fireworks.ai/guides/querying-text-models/reasoning), [Cohere](https://docs.cohere.com/docs/compatibility-api), [Wafer](https://docs.wafer.ai/serverless/api-reference), [Groq](https://console.groq.com/docs/reasoning), [Cerebras](https://inference-docs.cerebras.ai/capabilities/reasoning), [SambaNova](https://docs.sambanova.ai/docs/api-reference/chat-completions/create-chat-based-completion), and [Mistral](https://docs.mistral.ai/studio-api/conversations/reasoning) receive their documented named vocabularies with explicit provider-owned downgrades. | | Boolean thinking controls were mixed into shared conversion. | [DeepSeek](https://api-docs.deepseek.com/guides/thinking_mode/), [Kimi](https://platform.kimi.ai/docs/guide/use-kimi-k2-thinking-model), [Z.ai](https://docs.z.ai/guides/capabilities/thinking-mode), [Cloudflare Workers AI](https://developers.cloudflare.com/changelog/post/2026-04-20-kimi-k2-6-workers-ai/), and [NVIDIA NIM](https://docs.nvidia.com/nim/large-language-models/1.15.0/thinking-budget-control.html) use provider-owned thinking-object or chat-template controls. | | Effort names and output limits could become fabricated reasoning budgets. | Exact budgets remain exact and are forwarded only through documented fields for OpenRouter, Fireworks, LM Studio, NIM, and [llama.cpp](https://github.com/ggml-org/llama.cpp/blob/master/tools/server/README.md); named efforts and output limits are never converted into token budgets. | | New-turn reasoning and prior-turn replay shared one switch. | Every profile independently declares native reasoning replay, `<think>` tag replay, provider-specific replay, or no replay; **Off** suppresses new reasoning output without corrupting required history. | | Providers without a stable generic compute control received guessed controls. | [MiniMax](https://platform.minimax.io/docs/api-reference/text-openai-api) requests split output only, while [GitHub Models](https://docs.github.com/en/rest/models/inference), [Hugging Face Inference Providers](https://huggingface.co/docs/inference-providers/en/tasks/chat-completion), Codestral, and OpenCode keep provider defaults and use only their explicit replay profile. | | OpenAI Responses effort became a lossy Anthropic thinking boolean. | Responses preserves `reasoning.effort` through `output_config`, then resolves it through the same application policy as Messages without inventing a budget. | | Legacy booleans remained the persisted contract. | FCC-owned dotenv files migrate to typed `REASONING_*` values, explicit env files receive an actionable warning, documentation describes the ownership boundary, and the package advances to 4.8.0. | | Reasoning behavior was covered by scattered boolean assertions. | New policy, routing, encoder, provider, Admin, migration, Responses, and smoke contracts pass all five local CI checks: 2,368 tests passed, 40 skipped; 92 smoke tests collect and both live config migration checks pass. | <!-- greptile_comment --> <details open><summary><h3>Greptile Summary</h3></summary> This PR makes reasoning policy client-aware and independent of provider model names. The main changes are: - Adds one immutable reasoning policy resolved at the application boundary. - Adds typed root and route reasoning settings with Admin UI support. - Moves wire controls and history replay behavior into provider profiles. - Migrates owned dotenv files from legacy thinking booleans. - Expands provider, routing, migration, API, and smoke coverage. </details> <h3>Confidence Score: 5/5</h3> This looks safe to merge. No blocking issues found in the changed code. <details><summary><h3><a href="https://www.greptile.com/trex"><img alt="T-Rex" src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg" height="20" align="absmiddle"></a> T-Rex Logs</h3></summary> **What T-Rex did** - Ran the contract-validation test suite with the specified test modules, and the tests reported 78 passed in 1.53s with exit code 0. - Reviewed the complete captured output artifact reasoning-contract-02-after.log to verify the final test outcomes and successful contract validation. <a href="https://app.greptile.com/trex/runs/14792858/artifacts"><picture><source media="(prefers-color-scheme: dark)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifactsDark.svg?v=4"><source media="(prefers-color-scheme: light)" srcset="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"><img alt="View all artifacts" src="https://greptile-static-assets.s3.amazonaws.com/badges/ViewAllArtifacts.svg?v=4"></picture></a> <sub><a href="https://www.greptile.com/trex"><img alt="T-Rex" src="https://greptile-static-assets.s3.amazonaws.com/trex/trex_green.svg" height="14" align="absmiddle"></a> Ran code and verified through T-Rex</sub> </details> <details open><summary><h3>Important Files Changed</h3></summary> | Filename | Overview | |----------|----------| | src/free_claude_code/config/env_migrations.py | Migrates legacy reasoning booleans in owned dotenv files and warns for explicit environment files. | | src/free_claude_code/application/reasoning.py | Resolves client controls and configured preferences into one provider-neutral reasoning policy. | | src/free_claude_code/application/routing.py | Carries route-level reasoning preferences into request-scoped policy resolution. | | src/free_claude_code/providers/openai_chat/reasoning.py | Provides shared provider encoders for reasoning controls and replay behavior. | </details> <sub>Reviews (2): Last reviewed commit: ["chore: release reasoning controls as 4.8..."](https://github.com/alishahryar1/free-claude-code/commit/9d4be767f7dbdca5709474012f43dcdc6f4347e3) | [Re-trigger Greptile](https://app.greptile.com/api/retrigger?id=44984039)</sub> <!-- /greptile_comment -->
8.2 KiB
8.2 KiB
AGENTIC DIRECTIVE
Keep AGENTS.md and CLAUDE.md identical.
CODING ENVIRONMENT
- Install astral uv using "curl -LsSf https://astral.sh/uv/install.sh | sh" if not already installed and if already installed then update it to the latest version
- Install Python 3.14.0 stable using
uv python install 3.14.0if not already installed (requires uv >=0.9; see[tool.uv] required-versioninpyproject.toml) - Always use
uv runto run files instead of the globalpythoncommand. - Current uv ruff formatter is set to py314 which has supports multiple exception types without paranthesis (except TypeError, ValueError:)
- Read
.env.examplefor environment variables. - All CI checks must pass; failing checks block merge.
- Add tests for new changes (including edge cases).
- Before pushing, prefer
./scripts/ci.sh(macOS/Linux) or.\scripts\ci.ps1(Windows) to run the local CI sequence; requiresuvon PATH. The local scripts run Ruff in repair mode (ruff format, thenruff check --fix) before type checking and tests. - Use
--only/--skip(PowerShell:-Only/-Skip) to run a subset when iterating; use--dry-runto print commands without running them. - GitHub CI remains check-only for Ruff (
ruff format --check,ruff check) so branch protection verifies committed code. - Fall back to individual repair commands when debugging local failures:
uv run ruff format,uv run ruff check --fix,uv run ty check,uv run pytest -v --tb=short. Use GitHub-style checks only when verifying enforcement locally:uv run ruff format --check,uv run ruff check. - Do not add
# type: ignoreor# ty: ignore; fix the underlying type issue. - Do not add
from __future__ import annotations; Python 3.14 native lazy annotations are the project standard. - All 5 check IDs are represented in
scripts/ci.sh/scripts/ci.ps1and enforced intests.ymlon push/merge (parallel jobs: suppression grep, ruff-format, ruff-check, ty, pytest). - GitHub CI runs on
push,pull_request, andmerge_groupso required checks validate merge queue candidates before they land. - Repository protection should use rulesets: a non-bypassable main integrity ruleset requires pull requests, merge queue, required checks, and blocks direct/force pushes to
main; a separate review ruleset may allowAlishahryar1/admins to bypass review only. - Required status checks: set required status checks to all of those statuses (e.g. Ban suppressions and legacy annotations, ruff-format, ruff-check, ty, pytest—use the exact labels GitHub shows, which may be prefixed with CI /). Remove ci from required checks if it was previously added for the old gate job.
IDENTITY & CONTEXT
- You are an expert Software Architect and Systems Engineer.
- Goal: Zero-defect, root-cause-oriented engineering for bugs; test-driven engineering for new features. Think carefully; no need to rush.
- Code: Write the simplest code possible. Keep the codebase minimal and modular.
ARCHITECTURE PRINCIPLES
- Shared utilities: Put shared Anthropic protocol logic in neutral
src/free_claude_code/core/anthropic/modules. Do not have one provider import from another provider's utils. - Failure ownership: Keep canonical failure semantics and redaction SDK-free in
core/; providers alone classify SDK/HTTP failures and own retries; protocol/API adapters alone choose wire error types and commit-boundary serialization. - DRY: Extract shared base classes to eliminate duplication. Prefer composition over copy-paste.
- Encapsulation: Use accessor methods for internal state (e.g.
set_current_task()), not direct_attributeassignment from outside. - Provider-specific config: Keep provider-specific fields (e.g.
nim_settings) in provider constructors, not in the baseProviderConfig. - Model-independent reasoning: Resolve client reasoning intent once at the application boundary; provider adapters translate documented provider capabilities. Never branch on upstream model names or versions to choose reasoning behavior.
- Dead code: Remove unused code, legacy systems, and hardcoded values. Use settings/config instead of literals (e.g.
settings.provider_typenot"nvidia_nim"). - Performance: Use list accumulation for strings (not
+=in loops), cache env vars at init, prefer iterative over recursive when stack depth matters. - Platform-agnostic naming: Use generic names (e.g.
PLATFORM_EDIT) not platform-specific ones (e.g.TELEGRAM_EDIT) in shared code. - No type ignores: Do not add
# type: ignoreor# ty: ignore. Fix the underlying type issue. - Python 3.14 annotations: Do not use
from __future__ import annotations; rely on native lazy annotations and fix circular import boundaries instead of hiding them with annotation stringization. - Imports: Prefer top-level imports. Avoid
TYPE_CHECKINGand local imports for first-party or required dependencies; if a top-level import creates a cycle, move shared types/protocols to a neutral owner. - Complete migrations: When moving modules, update imports to the new owner and remove old compatibility shims in the same change unless preserving a published interface is explicitly required.
- Maximum Test Coverage: There should be maximum test coverage for everything, preferably live smoke test coverage to catch bugs early
COGNITIVE WORKFLOW
- ANALYZE: Read relevant files. Do not guess.
- PLAN: Map out the logic. Identify root cause or required changes. Order changes by dependency.
- EXECUTE: Fix the cause, not the symptom. Execute incrementally with clear commits.
- VERIFY: Run
./scripts/ci.shor.\scripts\ci.ps1, plus relevant smoke tests when needed. Confirm the fix via logs or output. - SPECIFICITY: Do exactly as much as asked; nothing more, nothing less.
- PROPAGATION: Changes impact multiple files; propagate updates correctly.
- VERSION: If the commit touches production files on
main, bump semver in the same commit (see Versioning).
VERSIONING (MAIN)
Every commit on main that changes a production file must include a semver bump in pyproject.toml in the same commit. Do not merge or push prod changes without updating the version.
Production files
These paths count as production (runtime, packaging, or install surface):
src/free_claude_code/api/,src/free_claude_code/cli/,src/free_claude_code/config/,src/free_claude_code/core/,src/free_claude_code/messaging/,src/free_claude_code/providers/src/free_claude_code/application/.env.examplepyproject.toml(dependencies, scripts, packaging)scripts/install.sh,scripts/install.ps1,scripts/uninstall.sh,scripts/uninstall.ps1,scripts/ci.sh,scripts/ci.ps1
These do not require a version bump on their own:
tests/,smoke/- Docs and assets:
README.md,assets/,AGENTS.md,CLAUDE.md - CI and repo config:
.github/,.gitignore
If a single commit mixes production and non-production edits, still bump the version.
Semver rules
Use [project].version as MAJOR.MINOR.PATCH:
- PATCH (
x.y.Z+1): bug fixes, refactors with no user-visible behavior change, dependency updates, packaging/install fixes. - MINOR (
x.Y+1.0): backward-compatible features—new providers, admin fields, CLI commands, config options, or behavior additions. - MAJOR (
X+1.0.0): breaking changes—removed or renamed env vars, incompatible API/CLI/default changes, or migrations users must act on.
When unsure between PATCH and MINOR, prefer PATCH for fixes and MINOR for new capability.
Required steps
- Classify the change and choose the bump level.
- Update
versioninpyproject.toml. - Run
uv locksouv.lockreflects the new package version. - Include the version and lockfile updates in the same commit as the production change.
Example commit on main after a packaging fix: bump 1.2.38 → 1.2.39, run uv lock, commit together with the fix.
SUMMARY STANDARDS
- Summaries must be technical and granular.
- Include: [Files Changed], [Logic Altered], [Verification Method], [Residual Risks] (if no residual risks then say none).
TOOLS
- Prefer built-in tools (grep, read_file, etc.) over manual workflows. Check tool availability before use.