mirror of
https://github.com/Alishahryar1/free-claude-code.git
synced 2026-04-28 03:20:01 +00:00
Support use ollama method like LM stuio --------- Co-authored-by: Alishahryar1 <alishahryar2@gmail.com> Co-authored-by: u011436427 <u011436427@noreply.gitcode.com>
425 lines
15 KiB
Python
425 lines
15 KiB
Python
"""Hierarchical public capability map.
|
|
|
|
This module is the architectural companion to ``smoke.features``. The feature
|
|
inventory says which public features must be covered; this map records the
|
|
subfeature contracts, owning module boundary, and coverage owners that protect
|
|
them while the internals are refactored.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass
|
|
|
|
|
|
@dataclass(frozen=True, slots=True)
|
|
class CapabilityContract:
|
|
capability: str
|
|
subfeature: str
|
|
feature_id: str
|
|
owner: str
|
|
inputs: str
|
|
outputs: str
|
|
failure: str
|
|
pytest_tests: tuple[str, ...]
|
|
smoke_tests: tuple[str, ...] = ()
|
|
|
|
|
|
CAPABILITY_CONTRACTS: tuple[CapabilityContract, ...] = (
|
|
CapabilityContract(
|
|
"api_compatibility",
|
|
"routes_and_probes",
|
|
"anthropic_api_routes",
|
|
"api.services.ClaudeProxyService",
|
|
"Anthropic-compatible HTTP requests",
|
|
"JSON or Anthropic SSE responses",
|
|
"HTTPException or Anthropic error payload",
|
|
("tests/api/test_api.py",),
|
|
("test_probe_and_models_routes", "test_stop_endpoint_reports_no_messaging"),
|
|
),
|
|
CapabilityContract(
|
|
"api_compatibility",
|
|
"head_options_probes",
|
|
"probe_routes",
|
|
"api.routes",
|
|
"HEAD/OPTIONS probe requests",
|
|
"204 with Allow header",
|
|
"auth failure when configured",
|
|
("tests/api/test_api.py::test_probe_endpoints_return_204_with_allow_headers",),
|
|
("test_probe_and_models_routes",),
|
|
),
|
|
CapabilityContract(
|
|
"api_compatibility",
|
|
"client_request_shapes",
|
|
"drop_in_claude_code_replacement",
|
|
"api.services.ClaudeProxyService",
|
|
"Claude Code, VS Code, and JetBrains shaped requests",
|
|
"compatible streaming response",
|
|
"provider or validation error in Anthropic shape",
|
|
("tests/api/test_api.py", "tests/cli/test_cli.py"),
|
|
("test_vscode_and_jetbrains_shaped_requests",),
|
|
),
|
|
CapabilityContract(
|
|
"api_compatibility",
|
|
"client_extensions",
|
|
"vscode_extension",
|
|
"api.services.ClaudeProxyService",
|
|
"VS Code beta query/header variants",
|
|
"accepted Anthropic-compatible response",
|
|
"HTTP error only for auth/provider failures",
|
|
(),
|
|
("test_vscode_and_jetbrains_shaped_requests",),
|
|
),
|
|
CapabilityContract(
|
|
"api_compatibility",
|
|
"client_extensions",
|
|
"intellij_extension",
|
|
"api.services.ClaudeProxyService",
|
|
"JetBrains/ACP request variants",
|
|
"accepted Anthropic-compatible response",
|
|
"HTTP error only for auth/provider failures",
|
|
(),
|
|
("test_vscode_and_jetbrains_shaped_requests",),
|
|
),
|
|
CapabilityContract(
|
|
"auth",
|
|
"anthropic_headers",
|
|
"optional_authentication",
|
|
"api.dependencies.require_api_key",
|
|
"x-api-key, authorization, anthropic-auth-token",
|
|
"request accepted or 401",
|
|
"401 missing/invalid API key",
|
|
("tests/api/test_auth.py",),
|
|
("test_auth_token_is_enforced_for_all_supported_header_shapes",),
|
|
),
|
|
CapabilityContract(
|
|
"provider_routing",
|
|
"provider_registry",
|
|
"provider_matrix",
|
|
"providers.registry.ProviderRegistry",
|
|
"provider id and Settings",
|
|
"configured BaseProvider instance",
|
|
"503 for missing credentials; ValueError for unknown provider",
|
|
("tests/api/test_dependencies.py", "tests/providers/test_registry.py"),
|
|
("test_configured_provider_models_stream_successfully",),
|
|
),
|
|
CapabilityContract(
|
|
"provider_routing",
|
|
"claude_model_resolution",
|
|
"per_model_mapping",
|
|
"api.model_router.ModelRouter",
|
|
"Claude model name and configured MODEL_* values",
|
|
"provider id plus provider model name",
|
|
"settings validation rejects invalid provider prefixes",
|
|
("tests/api/test_model_router.py", "tests/config/test_config.py"),
|
|
("test_model_mapping_configuration_is_consistent",),
|
|
),
|
|
CapabilityContract(
|
|
"provider_routing",
|
|
"mixed_provider_resolution",
|
|
"mixed_provider_mapping",
|
|
"api.model_router.ModelRouter",
|
|
"Opus/Sonnet/Haiku/fallback model config",
|
|
"distinct provider selections per request",
|
|
"skip live execution when providers are not configured",
|
|
("tests/api/test_model_router.py", "tests/config/test_config.py"),
|
|
("test_mixed_provider_model_mapping_when_configured",),
|
|
),
|
|
CapabilityContract(
|
|
"provider_routing",
|
|
"provider_runtime_config",
|
|
"provider_proxy_timeout_config",
|
|
"providers.registry.ProviderRegistry",
|
|
"provider proxy, timeout, and rate-limit settings",
|
|
"provider client and scoped limiter config",
|
|
"provider construction failure",
|
|
("tests/api/test_dependencies.py", "tests/providers/test_registry.py"),
|
|
),
|
|
CapabilityContract(
|
|
"provider_routing",
|
|
"zero_cost_backends",
|
|
"zero_cost_provider_access",
|
|
"providers.registry.ProviderRegistry",
|
|
"configured free/local provider",
|
|
"streaming response from selected backend",
|
|
"missing env or upstream unavailable skip in smoke",
|
|
("tests/api/test_dependencies.py", "tests/providers/"),
|
|
("test_configured_provider_models_stream_successfully",),
|
|
),
|
|
CapabilityContract(
|
|
"streaming_conversion",
|
|
"anthropic_sse_lifecycle",
|
|
"streaming_error_mapping",
|
|
"core.anthropic.SSEBuilder",
|
|
"provider stream chunks or native SSE events",
|
|
"Anthropic message/content/error SSE lifecycle",
|
|
"Anthropic-compatible error event",
|
|
(
|
|
"tests/contracts/test_stream_contracts.py",
|
|
"tests/providers/test_streaming_errors.py",
|
|
),
|
|
),
|
|
CapabilityContract(
|
|
"streaming_conversion",
|
|
"thinking_blocks",
|
|
"thinking_token_support",
|
|
"core.anthropic.thinking",
|
|
"reasoning_content, reasoning_details, <think> text, native thinking",
|
|
"Claude thinking blocks or suppression",
|
|
"thinking hidden when disabled",
|
|
(
|
|
"tests/contracts/test_stream_contracts.py",
|
|
"tests/providers/test_open_router.py",
|
|
),
|
|
("test_per_model_thinking_config_e2e",),
|
|
),
|
|
CapabilityContract(
|
|
"streaming_conversion",
|
|
"heuristic_tools",
|
|
"heuristic_tool_parser",
|
|
"core.anthropic.tools",
|
|
"textual tool-call output",
|
|
"structured Anthropic tool_use blocks",
|
|
"text fallback when malformed",
|
|
("tests/providers/test_parsers.py", "tests/contracts/test_stream_contracts.py"),
|
|
("test_live_tool_use_when_configured_model_supports_tools",),
|
|
),
|
|
CapabilityContract(
|
|
"streaming_conversion",
|
|
"subagent_task_control",
|
|
"subagent_control",
|
|
"core.anthropic.SSEBuilder",
|
|
"Task tool call arguments",
|
|
"run_in_background=false",
|
|
"invalid JSON flushed as safe object",
|
|
("tests/providers/test_subagent_interception.py",),
|
|
),
|
|
CapabilityContract(
|
|
"request_behavior",
|
|
"local_optimizations",
|
|
"request_optimization",
|
|
"api.optimization_handlers",
|
|
"Claude Code probe/title/suggestion/filepath requests",
|
|
"local MessagesResponse without provider call",
|
|
"falls through to provider when unmatched/disabled",
|
|
(
|
|
"tests/api/test_optimization_handlers.py",
|
|
"tests/api/test_routes_optimizations.py",
|
|
),
|
|
("test_optimization_fast_paths_do_not_need_provider",),
|
|
),
|
|
CapabilityContract(
|
|
"request_behavior",
|
|
"token_counting",
|
|
"count_tokens_contract",
|
|
"core.anthropic.get_token_count",
|
|
"messages, system blocks, tools, images, thinking, tool results",
|
|
"positive input token estimate",
|
|
"500 with readable detail on unexpected failure",
|
|
("tests/api/test_request_utils.py",),
|
|
("test_count_tokens_accepts_thinking_tools_and_results",),
|
|
),
|
|
CapabilityContract(
|
|
"config",
|
|
"env_precedence",
|
|
"config_env_precedence",
|
|
"config.settings.Settings",
|
|
"process env, user env file, repo env file, FCC_ENV_FILE",
|
|
"deterministic settings values",
|
|
"validation error for invalid settings",
|
|
("tests/config/test_config.py",),
|
|
),
|
|
CapabilityContract(
|
|
"config",
|
|
"removed_env_migration",
|
|
"removed_env_migration",
|
|
"config.settings.Settings",
|
|
"NIM_ENABLE_THINKING or ENABLE_THINKING in env or dotenv",
|
|
"startup validation error with rename guidance",
|
|
"application fails fast",
|
|
("tests/config/test_config.py",),
|
|
),
|
|
CapabilityContract(
|
|
"provider_runtime",
|
|
"rate_limit_and_disconnect",
|
|
"smart_rate_limiting",
|
|
"providers.rate_limit.GlobalRateLimiter",
|
|
"concurrent provider requests and 429/disconnect failures",
|
|
"proactive throttle, retry, cleanup",
|
|
"mapped provider error or smoke skip for upstream disconnect",
|
|
("tests/providers/test_provider_rate_limit.py",),
|
|
("test_client_disconnect_mid_stream_does_not_crash_server",),
|
|
),
|
|
CapabilityContract(
|
|
"local_providers",
|
|
"lmstudio_native_messages",
|
|
"lmstudio_endpoint",
|
|
"providers.anthropic_messages.AnthropicMessagesTransport",
|
|
"Anthropic request body and local LM Studio URL",
|
|
"native /messages stream pass-through",
|
|
"SSE error event for local upstream failure",
|
|
(
|
|
"tests/providers/test_lmstudio.py",
|
|
"tests/providers/test_anthropic_messages.py",
|
|
),
|
|
("test_lmstudio_models_endpoint_when_available",),
|
|
),
|
|
CapabilityContract(
|
|
"local_providers",
|
|
"llamacpp_native_messages",
|
|
"llamacpp_endpoint",
|
|
"providers.anthropic_messages.AnthropicMessagesTransport",
|
|
"Anthropic request body and llama.cpp URL",
|
|
"native /messages stream pass-through",
|
|
"SSE error event for local upstream failure",
|
|
(
|
|
"tests/providers/test_llamacpp.py",
|
|
"tests/providers/test_anthropic_messages.py",
|
|
),
|
|
("test_llamacpp_models_endpoint_when_available",),
|
|
),
|
|
CapabilityContract(
|
|
"local_providers",
|
|
"ollama_native_messages",
|
|
"ollama_endpoint",
|
|
"providers.ollama.OllamaProvider",
|
|
"Anthropic request body and local Ollama root URL",
|
|
"Anthropic SSE stream through the proxy",
|
|
"SSE error event for local upstream failure",
|
|
("tests/providers/test_ollama.py",),
|
|
("test_ollama_models_endpoint_when_available",),
|
|
),
|
|
CapabilityContract(
|
|
"openrouter",
|
|
"native_anthropic_messages",
|
|
"provider_matrix",
|
|
"providers.open_router.OpenRouterProvider",
|
|
"Anthropic Messages request for OpenRouter",
|
|
"native OpenRouter Anthropic SSE",
|
|
"Anthropic SSE error shape",
|
|
(
|
|
"tests/providers/test_open_router.py",
|
|
"tests/providers/test_anthropic_messages.py",
|
|
),
|
|
("test_configured_provider_models_stream_successfully",),
|
|
),
|
|
CapabilityContract(
|
|
"messaging",
|
|
"discord_telegram_platforms",
|
|
"discord_telegram_bot",
|
|
"messaging.handler.ClaudeMessageHandler",
|
|
"Discord/Telegram incoming messages and API callbacks",
|
|
"live progress edits and final transcript",
|
|
"platform retry/fallback or user-facing error",
|
|
(
|
|
"tests/messaging/test_discord_platform.py",
|
|
"tests/messaging/test_telegram.py",
|
|
),
|
|
("test_telegram_bot_api_permissions", "test_discord_bot_api_permissions"),
|
|
),
|
|
CapabilityContract(
|
|
"messaging",
|
|
"commands",
|
|
"messaging_commands",
|
|
"messaging.commands",
|
|
"/stop, /clear, /stats command messages",
|
|
"task cancellation, cleanup, or stats response",
|
|
"best-effort platform cleanup",
|
|
(
|
|
"tests/messaging/test_handler.py",
|
|
"tests/messaging/test_handler_integration.py",
|
|
),
|
|
),
|
|
CapabilityContract(
|
|
"messaging",
|
|
"tree_threading",
|
|
"tree_threading",
|
|
"messaging.trees.TreeQueueManager",
|
|
"reply-based message graph",
|
|
"queued branches and scoped cancellation",
|
|
"node error propagation",
|
|
(
|
|
"tests/messaging/test_tree_queue.py",
|
|
"tests/messaging/test_tree_concurrency.py",
|
|
),
|
|
),
|
|
CapabilityContract(
|
|
"persistence",
|
|
"restart_restore",
|
|
"restart_restore",
|
|
"messaging.session.SessionStore",
|
|
"stored tree JSON",
|
|
"restored node-to-tree mapping",
|
|
"stale pending work marked lost",
|
|
("tests/messaging/test_restart_reply_restore.py",),
|
|
),
|
|
CapabilityContract(
|
|
"persistence",
|
|
"session_store",
|
|
"session_persistence",
|
|
"messaging.session.SessionStore",
|
|
"tree data, node mapping, and message log",
|
|
"JSON persistence compatible with existing files",
|
|
"best-effort flush error logging",
|
|
("tests/messaging/test_session_store_edge_cases.py",),
|
|
),
|
|
CapabilityContract(
|
|
"voice",
|
|
"voice_transcription",
|
|
"voice_notes",
|
|
"messaging.voice.VoiceTranscriptionService",
|
|
"Discord/Telegram audio file and voice backend settings",
|
|
"transcribed prompt routed to handler",
|
|
"missing optional extra or backend error shown to user",
|
|
(
|
|
"tests/messaging/test_voice_handlers.py",
|
|
"tests/messaging/test_transcription.py",
|
|
),
|
|
("test_voice_transcription_backend_when_explicitly_enabled",),
|
|
),
|
|
CapabilityContract(
|
|
"cli",
|
|
"package_entrypoints",
|
|
"package_cli_entrypoints",
|
|
"cli.entrypoints",
|
|
"installed console scripts",
|
|
"config scaffold or uvicorn server startup",
|
|
"process cleanup in finally",
|
|
("tests/cli/test_entrypoints.py",),
|
|
(
|
|
"test_fcc_init_scaffolds_user_config",
|
|
"test_free_claude_code_entrypoint_starts_server",
|
|
),
|
|
),
|
|
CapabilityContract(
|
|
"cli",
|
|
"claude_cli_drop_in",
|
|
"claude_cli_drop_in",
|
|
"cli.session.CLISession",
|
|
"Claude CLI binary and proxy env",
|
|
"stream-json events and session id mapping",
|
|
"stderr/error event and process cleanup",
|
|
("tests/cli/test_cli.py",),
|
|
("test_claude_cli_prompt_when_available",),
|
|
),
|
|
CapabilityContract(
|
|
"extensibility",
|
|
"provider_platform_abcs",
|
|
"extensible_provider_platform_abcs",
|
|
"providers.registry and messaging.platforms.factory",
|
|
"new provider/platform implementations",
|
|
"registered BaseProvider or MessagingPlatform",
|
|
"unknown platform returns None; unknown provider errors",
|
|
(
|
|
"tests/contracts/test_feature_manifest.py",
|
|
"tests/providers/test_registry.py",
|
|
),
|
|
),
|
|
)
|
|
|
|
|
|
def capability_names() -> set[str]:
|
|
return {contract.capability for contract in CAPABILITY_CONTRACTS}
|
|
|
|
|
|
def contracted_feature_ids() -> set[str]:
|
|
return {contract.feature_id for contract in CAPABILITY_CONTRACTS}
|