@oneciel-ai/ciel-runtime 0.1.1 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +132 -0
- package/ciel-runtime-menu.py +56 -6
- package/ciel_runtime.py +9379 -35909
- package/ciel_runtime_support/advisor_client.py +193 -0
- package/ciel_runtime_support/advisor_policy.py +320 -0
- package/ciel_runtime_support/advisor_refinement.py +160 -0
- package/ciel_runtime_support/advisor_request_builder.py +261 -0
- package/ciel_runtime_support/agy_installer.py +169 -0
- package/ciel_runtime_support/agy_mcp_restore.py +182 -0
- package/ciel_runtime_support/anthropic_model_policy.py +186 -0
- package/ciel_runtime_support/anthropic_response_writer.py +255 -0
- package/ciel_runtime_support/anthropic_tool_turns.py +130 -0
- package/ciel_runtime_support/api_key_cooldown.py +159 -0
- package/ciel_runtime_support/architecture.py +488 -1
- package/ciel_runtime_support/architecture_budget.py +42 -0
- package/ciel_runtime_support/channel_backlog.py +90 -0
- package/ciel_runtime_support/channel_cli.py +119 -0
- package/ciel_runtime_support/channel_compact_injection.py +82 -0
- package/ciel_runtime_support/channel_compact_poll.py +67 -0
- package/ciel_runtime_support/channel_compact_request_repository.py +113 -0
- package/ciel_runtime_support/channel_config_service.py +281 -0
- package/ciel_runtime_support/channel_connection_lifecycle.py +180 -0
- package/ciel_runtime_support/channel_connection_registry.py +128 -0
- package/ciel_runtime_support/channel_connection_worker.py +284 -0
- package/ciel_runtime_support/channel_cursor_recovery.py +92 -0
- package/ciel_runtime_support/channel_cursor_repository.py +89 -0
- package/ciel_runtime_support/channel_cursor_service.py +178 -0
- package/ciel_runtime_support/channel_event_identity.py +212 -0
- package/ciel_runtime_support/channel_event_projection.py +315 -0
- package/ciel_runtime_support/channel_inflight.py +127 -0
- package/ciel_runtime_support/channel_injection.py +115 -0
- package/ciel_runtime_support/channel_launch_guard_repository.py +58 -0
- package/ciel_runtime_support/channel_launch_policy.py +180 -0
- package/ciel_runtime_support/channel_llm_context.py +156 -0
- package/ciel_runtime_support/channel_mcp_discovery.py +186 -0
- package/ciel_runtime_support/channel_mcp_http_controller.py +239 -0
- package/ciel_runtime_support/channel_mcp_ownership.py +148 -0
- package/ciel_runtime_support/channel_mcp_tools.py +240 -0
- package/ciel_runtime_support/channel_mcp_transport.py +394 -0
- package/ciel_runtime_support/channel_message_dedupe.py +65 -0
- package/ciel_runtime_support/channel_message_policy.py +256 -0
- package/ciel_runtime_support/channel_message_prompt.py +305 -0
- package/ciel_runtime_support/channel_message_repository.py +234 -0
- package/ciel_runtime_support/channel_notification_projection.py +217 -0
- package/ciel_runtime_support/channel_panel.py +162 -0
- package/ciel_runtime_support/channel_pending_injection.py +209 -0
- package/ciel_runtime_support/channel_pending_poll.py +109 -0
- package/ciel_runtime_support/channel_probe_cache.py +433 -0
- package/ciel_runtime_support/channel_probe_report.py +101 -0
- package/ciel_runtime_support/channel_runtime_environment.py +181 -0
- package/ciel_runtime_support/channel_session_lifecycle.py +114 -0
- package/ciel_runtime_support/channel_session_repository.py +90 -0
- package/ciel_runtime_support/channel_terminal_dispatch.py +115 -0
- package/ciel_runtime_support/channel_terminal_input.py +277 -0
- package/ciel_runtime_support/channel_terminal_proxy.py +447 -0
- package/ciel_runtime_support/channel_tool_context.py +166 -0
- package/ciel_runtime_support/channel_transcript.py +414 -0
- package/ciel_runtime_support/channel_transcript_repository.py +96 -0
- package/ciel_runtime_support/channel_wake_claim_repository.py +126 -0
- package/ciel_runtime_support/channel_wake_delivery_repository.py +88 -0
- package/ciel_runtime_support/chat_files.py +138 -0
- package/ciel_runtime_support/chat_http_controller.py +235 -0
- package/ciel_runtime_support/claude_environment.py +375 -0
- package/ciel_runtime_support/claude_router.py +247 -193
- package/ciel_runtime_support/cli_dispatch.py +792 -0
- package/ciel_runtime_support/cli_parser.py +165 -0
- package/ciel_runtime_support/cli_usage.py +100 -0
- package/ciel_runtime_support/codex_app_server.py +20 -5
- package/ciel_runtime_support/codex_channel_sse_launch.py +87 -0
- package/ciel_runtime_support/codex_cli.py +42 -6
- package/ciel_runtime_support/codex_config.py +323 -0
- package/ciel_runtime_support/codex_launch_configuration.py +240 -0
- package/ciel_runtime_support/codex_launch_policy.py +66 -0
- package/ciel_runtime_support/codex_mcp_integration.py +195 -0
- package/ciel_runtime_support/codex_mcp_restore.py +304 -0
- package/ciel_runtime_support/codex_model_catalog.py +133 -0
- package/ciel_runtime_support/codex_process_lifecycle.py +271 -0
- package/ciel_runtime_support/codex_router.py +147 -1
- package/ciel_runtime_support/codex_session_repository.py +115 -0
- package/ciel_runtime_support/codex_session_selection.py +114 -0
- package/ciel_runtime_support/command_asset_installer.py +103 -0
- package/ciel_runtime_support/compatibility_probe.py +295 -0
- package/ciel_runtime_support/compatibility_protocol.py +251 -0
- package/ciel_runtime_support/compatibility_runtime.py +166 -0
- package/ciel_runtime_support/compatibility_test.py +370 -0
- package/ciel_runtime_support/config_migrations.py +307 -0
- package/ciel_runtime_support/config_repository.py +175 -0
- package/ciel_runtime_support/config_value_codec.py +64 -0
- package/ciel_runtime_support/configuration_cli.py +374 -0
- package/ciel_runtime_support/context_compaction.py +280 -0
- package/ciel_runtime_support/context_setup.py +208 -0
- package/ciel_runtime_support/context_summary_policy.py +392 -0
- package/ciel_runtime_support/credential_cli.py +104 -0
- package/ciel_runtime_support/credential_management.py +261 -0
- package/ciel_runtime_support/credentials.py +269 -0
- package/ciel_runtime_support/executable_discovery.py +141 -0
- package/ciel_runtime_support/github_copilot_oauth.py +335 -0
- package/ciel_runtime_support/github_copilot_oauth_runtime.py +213 -0
- package/ciel_runtime_support/header_forwarding.py +73 -0
- package/ciel_runtime_support/headless_config.py +221 -0
- package/ciel_runtime_support/http_response.py +129 -0
- package/ciel_runtime_support/install_diagnostics.py +149 -0
- package/ciel_runtime_support/kimi_identity.py +123 -0
- package/ciel_runtime_support/launch_diagnostics.py +204 -0
- package/ciel_runtime_support/launch_state.py +127 -0
- package/ciel_runtime_support/live_api_key_controller.py +58 -0
- package/ciel_runtime_support/llm_config_http.py +148 -0
- package/ciel_runtime_support/llm_option_config.py +259 -0
- package/ciel_runtime_support/llm_presentation_data.py +447 -0
- package/ciel_runtime_support/llm_presets.py +773 -0
- package/ciel_runtime_support/lm_studio_runtime.py +401 -0
- package/ciel_runtime_support/managed_mcp_config.py +144 -0
- package/ciel_runtime_support/managed_mcp_discovery.py +151 -0
- package/ciel_runtime_support/managed_service_cleanup.py +89 -0
- package/ciel_runtime_support/mcp_config_reader.py +230 -0
- package/ciel_runtime_support/mcp_http_proxy.py +607 -0
- package/ciel_runtime_support/mcp_inventory.py +59 -0
- package/ciel_runtime_support/mcp_notification_wait_policy.py +159 -0
- package/ciel_runtime_support/mcp_probe_codec.py +136 -0
- package/ciel_runtime_support/mcp_probe_transport.py +328 -0
- package/ciel_runtime_support/mcp_proxy_codec.py +345 -0
- package/ciel_runtime_support/mcp_proxy_config.py +107 -0
- package/ciel_runtime_support/mcp_proxy_notifications.py +261 -0
- package/ciel_runtime_support/mcp_proxy_process.py +560 -0
- package/ciel_runtime_support/mcp_split_proxy_http.py +165 -0
- package/ciel_runtime_support/mcp_stdio_probe.py +240 -0
- package/ciel_runtime_support/mcp_transport.py +146 -0
- package/ciel_runtime_support/model_cache_lifecycle.py +78 -0
- package/ciel_runtime_support/model_catalog_projection.py +61 -0
- package/ciel_runtime_support/model_context_hints.py +109 -0
- package/ciel_runtime_support/model_panel.py +147 -0
- package/ciel_runtime_support/model_registry_repository.py +231 -0
- package/ciel_runtime_support/npm_runtime.py +191 -0
- package/ciel_runtime_support/ollama_catalog.py +462 -0
- package/ciel_runtime_support/ollama_catalog_cli.py +41 -0
- package/ciel_runtime_support/ollama_catalog_repository.py +75 -0
- package/ciel_runtime_support/ollama_context_sync.py +87 -0
- package/ciel_runtime_support/ollama_forwarding.py +449 -0
- package/ciel_runtime_support/openai_chat_passthrough.py +67 -0
- package/ciel_runtime_support/openai_chat_router.py +64 -0
- package/ciel_runtime_support/openai_forwarding.py +194 -0
- package/ciel_runtime_support/openai_responses_router.py +291 -0
- package/ciel_runtime_support/openai_responses_stream.py +135 -0
- package/ciel_runtime_support/output_budget.py +89 -0
- package/ciel_runtime_support/package_lifecycle.py +217 -0
- package/ciel_runtime_support/plan_artifact_controller.py +104 -0
- package/ciel_runtime_support/prelaunch.py +959 -0
- package/ciel_runtime_support/prelaunch_launch_preference.py +75 -0
- package/ciel_runtime_support/prelaunch_panel_projection.py +396 -0
- package/ciel_runtime_support/prelaunch_terminal.py +764 -0
- package/ciel_runtime_support/process_control.py +708 -0
- package/ciel_runtime_support/prompt_compaction.py +322 -0
- package/ciel_runtime_support/prompt_injection.py +176 -0
- package/ciel_runtime_support/protocols/__init__.py +24 -0
- package/ciel_runtime_support/protocols/anthropic_content.py +29 -0
- package/ciel_runtime_support/protocols/anthropic_thinking_policy.py +336 -0
- package/ciel_runtime_support/protocols/chat_projection.py +315 -0
- package/ciel_runtime_support/protocols/conversation_policy.py +217 -0
- package/ciel_runtime_support/protocols/conversation_turn_policy.py +972 -0
- package/ciel_runtime_support/protocols/ollama_chat.py +111 -0
- package/ciel_runtime_support/protocols/ollama_response.py +231 -0
- package/ciel_runtime_support/protocols/openai_reasoning.py +75 -0
- package/ciel_runtime_support/protocols/openai_responses.py +271 -0
- package/ciel_runtime_support/protocols/pseudo_tool_history.py +248 -0
- package/ciel_runtime_support/protocols/tool_result_projection.py +112 -0
- package/ciel_runtime_support/provider_adapters.py +160 -0
- package/ciel_runtime_support/provider_catalog_sources.py +316 -0
- package/ciel_runtime_support/provider_choice.py +201 -0
- package/ciel_runtime_support/provider_compatibility.py +165 -0
- package/ciel_runtime_support/provider_config_mutations.py +361 -0
- package/ciel_runtime_support/provider_configuration_service.py +162 -0
- package/ciel_runtime_support/provider_context.py +308 -0
- package/ciel_runtime_support/provider_contract_projection.py +73 -0
- package/ciel_runtime_support/provider_descriptor.py +82 -0
- package/ciel_runtime_support/provider_endpoint_policy.py +130 -0
- package/ciel_runtime_support/provider_endpoint_probe.py +165 -0
- package/ciel_runtime_support/provider_launch_endpoint.py +109 -0
- package/ciel_runtime_support/provider_limits.py +457 -0
- package/ciel_runtime_support/provider_model_identity.py +139 -0
- package/ciel_runtime_support/provider_model_selection.py +431 -0
- package/ciel_runtime_support/provider_model_specs.py +142 -0
- package/ciel_runtime_support/provider_models.py +263 -0
- package/ciel_runtime_support/provider_network.py +176 -0
- package/ciel_runtime_support/provider_option_cli.py +238 -0
- package/ciel_runtime_support/provider_option_panel.py +275 -0
- package/ciel_runtime_support/provider_option_status.py +192 -0
- package/ciel_runtime_support/provider_policy.py +101 -0
- package/ciel_runtime_support/provider_query_policy.py +67 -0
- package/ciel_runtime_support/provider_readiness.py +112 -0
- package/ciel_runtime_support/provider_request_access.py +131 -0
- package/ciel_runtime_support/provider_request_builder.py +250 -0
- package/ciel_runtime_support/provider_responses_passthrough.py +81 -0
- package/ciel_runtime_support/provider_runtime_info.py +113 -0
- package/ciel_runtime_support/provider_runtime_modes.py +150 -0
- package/ciel_runtime_support/provider_sampling_policy.py +46 -0
- package/ciel_runtime_support/provider_status.py +145 -0
- package/ciel_runtime_support/provider_timeout_policy.py +184 -0
- package/ciel_runtime_support/provider_tool_policy.py +145 -0
- package/ciel_runtime_support/providers/__init__.py +65 -0
- package/ciel_runtime_support/providers/anthropic.py +160 -0
- package/ciel_runtime_support/providers/anthropic_catalog.py +119 -0
- package/ciel_runtime_support/providers/base.py +232 -0
- package/ciel_runtime_support/providers/catalog.py +326 -0
- package/ciel_runtime_support/providers/cloud.py +194 -0
- package/ciel_runtime_support/providers/constants.py +54 -0
- package/ciel_runtime_support/providers/deepseek.py +115 -0
- package/ciel_runtime_support/providers/fireworks.py +158 -0
- package/ciel_runtime_support/providers/github_copilot_oauth.py +199 -0
- package/ciel_runtime_support/providers/kimi.py +297 -0
- package/ciel_runtime_support/providers/lm_studio.py +76 -0
- package/ciel_runtime_support/providers/meta.py +257 -0
- package/ciel_runtime_support/providers/native.py +194 -0
- package/ciel_runtime_support/providers/nim.py +69 -0
- package/ciel_runtime_support/providers/nvidia.py +158 -0
- package/ciel_runtime_support/providers/nvidia_runtime.py +285 -0
- package/ciel_runtime_support/providers/ollama.py +181 -0
- package/ciel_runtime_support/providers/ollama_context.py +195 -0
- package/ciel_runtime_support/providers/ollama_runtime.py +213 -0
- package/ciel_runtime_support/providers/opencode.py +220 -0
- package/ciel_runtime_support/providers/opencode_go.py +37 -0
- package/ciel_runtime_support/providers/openrouter.py +57 -0
- package/ciel_runtime_support/providers/vllm.py +65 -0
- package/ciel_runtime_support/providers/zai.py +119 -0
- package/ciel_runtime_support/pseudo_tool_parser.py +115 -0
- package/ciel_runtime_support/rate_limit_policy.py +117 -0
- package/ciel_runtime_support/rate_limit_repository.py +154 -0
- package/ciel_runtime_support/registry.py +46 -0
- package/ciel_runtime_support/request_shortcuts.py +253 -0
- package/ciel_runtime_support/request_trace.py +323 -0
- package/ciel_runtime_support/response_collection.py +209 -0
- package/ciel_runtime_support/router_access.py +238 -0
- package/ciel_runtime_support/router_client_lifecycle.py +366 -0
- package/ciel_runtime_support/router_health_policy.py +101 -0
- package/ciel_runtime_support/router_http.py +513 -0
- package/ciel_runtime_support/router_process_lifecycle.py +401 -0
- package/ciel_runtime_support/router_rate_limit_service.py +285 -0
- package/ciel_runtime_support/router_server_runtime.py +103 -0
- package/ciel_runtime_support/router_shortcuts.py +201 -0
- package/ciel_runtime_support/routing_fallback.py +73 -0
- package/ciel_runtime_support/runtime_activity_repository.py +143 -0
- package/ciel_runtime_support/runtime_adapters.py +104 -0
- package/ciel_runtime_support/runtime_command_factory.py +73 -0
- package/ciel_runtime_support/runtime_compatibility.py +50 -0
- package/ciel_runtime_support/runtime_constants.py +178 -0
- package/ciel_runtime_support/runtime_launch.py +1602 -0
- package/ciel_runtime_support/runtime_llm_options.py +312 -0
- package/ciel_runtime_support/runtime_logging.py +161 -0
- package/ciel_runtime_support/runtime_paths.py +157 -0
- package/ciel_runtime_support/runtime_restart.py +84 -0
- package/ciel_runtime_support/runtime_upgrade.py +149 -0
- package/ciel_runtime_support/secure_json_repository.py +55 -0
- package/ciel_runtime_support/session_import.py +356 -0
- package/ciel_runtime_support/settings_repository.py +8 -0
- package/ciel_runtime_support/slash_command_assets.py +211 -0
- package/ciel_runtime_support/sse_stream.py +57 -0
- package/ciel_runtime_support/sse_trace.py +225 -0
- package/ciel_runtime_support/statusline_script.py +593 -0
- package/ciel_runtime_support/statusline_settings.py +53 -0
- package/ciel_runtime_support/stream_chunk_policy.py +18 -0
- package/ciel_runtime_support/streaming_anthropic.py +1955 -0
- package/ciel_runtime_support/synthetic_tool_policy.py +105 -0
- package/ciel_runtime_support/terminal_platform_io.py +127 -0
- package/ciel_runtime_support/timeout_profile.py +196 -0
- package/ciel_runtime_support/tool_dialects.py +85 -0
- package/ciel_runtime_support/tool_exposure_policy.py +63 -0
- package/ciel_runtime_support/tool_guard_hooks.py +218 -0
- package/ciel_runtime_support/tool_request_projection.py +96 -0
- package/ciel_runtime_support/tool_schema.py +483 -0
- package/ciel_runtime_support/tool_side_effect_dedupe.py +95 -0
- package/ciel_runtime_support/ui_text.py +266 -0
- package/ciel_runtime_support/upstream_error_policy.py +104 -0
- package/ciel_runtime_support/upstream_retry.py +419 -0
- package/ciel_runtime_support/upstream_stream_io.py +106 -0
- package/ciel_runtime_support/usage_events.py +96 -0
- package/ciel_runtime_support/visible_stream_filters.py +130 -0
- package/ciel_runtime_support/web_endpoints.py +447 -0
- package/ciel_runtime_support/web_ui.py +915 -0
- package/ciel_runtime_support/web_ui_controller.py +189 -0
- package/ciel_runtime_support/windows_console_input.py +137 -0
- package/ciel_runtime_support/windows_console_mode.py +112 -0
- package/docs/Architecture.md +54 -0
- package/docs/Configuration.md +17 -0
- package/docs/Module-Map.md +1093 -26
- package/docs/Providers.md +46 -1
- package/docs/adr/0001-runtime-bounded-contexts.md +295 -0
- package/npm-bin/run-ciel-runtime.js +22 -2
- package/package.json +9 -2
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"""LM Studio provider adapter."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field, replace
|
|
4
|
+
|
|
5
|
+
from ..architecture import (
|
|
6
|
+
ProviderCapabilities,
|
|
7
|
+
ProviderConfig,
|
|
8
|
+
ProviderContextPolicy,
|
|
9
|
+
ProviderModelCatalogPolicy,
|
|
10
|
+
ProviderOptionPresentationPolicy,
|
|
11
|
+
ProviderStatusPolicy,
|
|
12
|
+
)
|
|
13
|
+
from .base import OpenAICompatibleProviderAdapter, provider_configuration
|
|
14
|
+
from .constants import DEFAULT_REQUEST_TIMEOUT_MS, PROVIDER_DEFAULT_BASE_URLS
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@dataclass(frozen=True)
|
|
18
|
+
class LMStudioProviderAdapter(OpenAICompatibleProviderAdapter):
|
|
19
|
+
name: str = "lm-studio"
|
|
20
|
+
base_url: str = PROVIDER_DEFAULT_BASE_URLS["lm-studio"]
|
|
21
|
+
configuration_defaults_value: dict = field(
|
|
22
|
+
default_factory=lambda: provider_configuration(
|
|
23
|
+
"local-model",
|
|
24
|
+
custom_models=("local-model",),
|
|
25
|
+
native_compat=True,
|
|
26
|
+
rate_limit_rpm=0,
|
|
27
|
+
rate_limit_status=False,
|
|
28
|
+
context_window=32768,
|
|
29
|
+
max_output_tokens=4096,
|
|
30
|
+
temperature=0.7,
|
|
31
|
+
top_p=0.8,
|
|
32
|
+
context_reserve_tokens=1024,
|
|
33
|
+
request_timeout_ms=DEFAULT_REQUEST_TIMEOUT_MS,
|
|
34
|
+
stream_enabled=True,
|
|
35
|
+
stream_word_chunking=False,
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
capabilities_value: ProviderCapabilities = field(
|
|
39
|
+
default_factory=lambda: ProviderCapabilities(
|
|
40
|
+
upstream_protocol="openai_chat", local=True
|
|
41
|
+
)
|
|
42
|
+
)
|
|
43
|
+
model_catalog_policy_value: ProviderModelCatalogPolicy = field(
|
|
44
|
+
default_factory=lambda: ProviderModelCatalogPolicy(kind="lm_studio")
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
def requires_catalog_model_selection(self, config: ProviderConfig) -> bool:
|
|
48
|
+
del config
|
|
49
|
+
return True
|
|
50
|
+
|
|
51
|
+
def placeholder_model_ids(self) -> frozenset[str]:
|
|
52
|
+
return super().placeholder_model_ids() | {"local-model"}
|
|
53
|
+
|
|
54
|
+
def context_policy(self, config: ProviderConfig) -> ProviderContextPolicy:
|
|
55
|
+
return replace(
|
|
56
|
+
super().context_policy(config), status_capacity_strategy="openai_budget"
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
def option_presentation_policy(
|
|
60
|
+
self, config: ProviderConfig
|
|
61
|
+
) -> ProviderOptionPresentationPolicy:
|
|
62
|
+
return replace(super().option_presentation_policy(config), show_rate_limit=True)
|
|
63
|
+
|
|
64
|
+
def model_paths(self, config: ProviderConfig) -> tuple[str, ...]:
|
|
65
|
+
del config
|
|
66
|
+
return ("/api/v0/models", "/api/v1/models", "/v1/models", "/models")
|
|
67
|
+
|
|
68
|
+
def status_policy(self, config: ProviderConfig) -> ProviderStatusPolicy:
|
|
69
|
+
return replace(
|
|
70
|
+
super().status_policy(config),
|
|
71
|
+
unreachable_hint="Start LM Studio's Local Server or set a reachable Anthropic-compatible Base URL before launching Claude Code.",
|
|
72
|
+
readiness_validation="lm_studio",
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
__all__ = ["LMStudioProviderAdapter"]
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"""Meta Model API / Muse Spark provider adapter."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import Any, Mapping
|
|
7
|
+
|
|
8
|
+
from ..architecture import (
|
|
9
|
+
MessageProtocol,
|
|
10
|
+
ProviderCapabilities,
|
|
11
|
+
ProviderConfig,
|
|
12
|
+
ProviderContextPolicy,
|
|
13
|
+
ProviderModelCatalogPolicy,
|
|
14
|
+
ProviderOptionPresentationPolicy,
|
|
15
|
+
ProviderRequestPolicy,
|
|
16
|
+
ProviderStatusPolicy,
|
|
17
|
+
)
|
|
18
|
+
from .base import HttpBearerProviderAdapter, provider_configuration
|
|
19
|
+
from .constants import DEFAULT_REQUEST_TIMEOUT_MS, PROVIDER_DEFAULT_BASE_URLS
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
MUSE_SPARK_MODEL = "muse-spark-1.1"
|
|
23
|
+
MUSE_SPARK_CONTEXT_WINDOW = 1_048_576
|
|
24
|
+
MUSE_SPARK_AUTO_COMPACT_LIMIT = 900_000
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass(frozen=True)
|
|
28
|
+
class MetaModelProviderAdapter(HttpBearerProviderAdapter):
|
|
29
|
+
"""Preserve Meta's native Responses and Anthropic Messages contracts."""
|
|
30
|
+
|
|
31
|
+
name: str = "meta"
|
|
32
|
+
base_url: str = PROVIDER_DEFAULT_BASE_URLS["meta"]
|
|
33
|
+
configuration_defaults_value: dict = field(
|
|
34
|
+
default_factory=lambda: provider_configuration(
|
|
35
|
+
MUSE_SPARK_MODEL,
|
|
36
|
+
custom_models=(MUSE_SPARK_MODEL,),
|
|
37
|
+
native_compat=True,
|
|
38
|
+
preserve_anthropic_thinking=True,
|
|
39
|
+
normalize_anthropic_tool_use=True,
|
|
40
|
+
supports_tool_choice=True,
|
|
41
|
+
claude_code_supported_capabilities=["effort", "thinking"],
|
|
42
|
+
context_window=MUSE_SPARK_CONTEXT_WINDOW,
|
|
43
|
+
max_model_len=MUSE_SPARK_CONTEXT_WINDOW,
|
|
44
|
+
auto_compact_window=MUSE_SPARK_AUTO_COMPACT_LIMIT,
|
|
45
|
+
codex_auto_compact_window=MUSE_SPARK_AUTO_COMPACT_LIMIT,
|
|
46
|
+
request_timeout_ms=DEFAULT_REQUEST_TIMEOUT_MS,
|
|
47
|
+
stream_enabled=True,
|
|
48
|
+
stream_word_chunking=False,
|
|
49
|
+
effort_level="high",
|
|
50
|
+
enable_tool_search=True,
|
|
51
|
+
haiku_model=MUSE_SPARK_MODEL,
|
|
52
|
+
opus_model=MUSE_SPARK_MODEL,
|
|
53
|
+
sonnet_model=MUSE_SPARK_MODEL,
|
|
54
|
+
subagent_model=MUSE_SPARK_MODEL,
|
|
55
|
+
)
|
|
56
|
+
)
|
|
57
|
+
authorization_header: str = "authorization"
|
|
58
|
+
include_x_api_key: bool = False
|
|
59
|
+
require_api_key: bool = True
|
|
60
|
+
api_key_display_name_value: str = "Meta Model API"
|
|
61
|
+
api_key_launch_error_value: str = (
|
|
62
|
+
"Launch blocked: Meta Model API requires a MODEL_API_KEY."
|
|
63
|
+
)
|
|
64
|
+
capabilities_value: ProviderCapabilities = field(
|
|
65
|
+
default_factory=lambda: ProviderCapabilities(
|
|
66
|
+
upstream_protocol="anthropic_messages",
|
|
67
|
+
supports_thinking=True,
|
|
68
|
+
preserves_anthropic_thinking=True,
|
|
69
|
+
requires_api_key=True,
|
|
70
|
+
)
|
|
71
|
+
)
|
|
72
|
+
request_policy_value: ProviderRequestPolicy = field(
|
|
73
|
+
default_factory=lambda: ProviderRequestPolicy(
|
|
74
|
+
chat_path="/v1/messages",
|
|
75
|
+
models_path="/v1/models",
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
model_catalog_policy_value: ProviderModelCatalogPolicy = field(
|
|
79
|
+
default_factory=lambda: ProviderModelCatalogPolicy(
|
|
80
|
+
kind="openai",
|
|
81
|
+
fallback_models=(MUSE_SPARK_MODEL,),
|
|
82
|
+
allow_configured_fallback=True,
|
|
83
|
+
)
|
|
84
|
+
)
|
|
85
|
+
|
|
86
|
+
def context_policy(self, config: ProviderConfig) -> ProviderContextPolicy:
|
|
87
|
+
del config
|
|
88
|
+
return ProviderContextPolicy(
|
|
89
|
+
capacity_strategy="configured_first",
|
|
90
|
+
settings_strategy="standard",
|
|
91
|
+
hosted_timeout=True,
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
def router_native_anthropic_enabled(
|
|
95
|
+
self, config: ProviderConfig, model: str | None = None
|
|
96
|
+
) -> bool:
|
|
97
|
+
del model
|
|
98
|
+
return bool(config.options.get("native_compat", True))
|
|
99
|
+
|
|
100
|
+
def supported_protocols(
|
|
101
|
+
self, config: ProviderConfig, model: str | None = None
|
|
102
|
+
) -> frozenset[MessageProtocol]:
|
|
103
|
+
del config, model
|
|
104
|
+
return frozenset({"anthropic_messages", "openai_responses"})
|
|
105
|
+
|
|
106
|
+
def select_protocol(
|
|
107
|
+
self,
|
|
108
|
+
operation: MessageProtocol,
|
|
109
|
+
config: ProviderConfig,
|
|
110
|
+
model: str | None = None,
|
|
111
|
+
) -> MessageProtocol:
|
|
112
|
+
del config, model
|
|
113
|
+
return (
|
|
114
|
+
"openai_responses"
|
|
115
|
+
if operation == "openai_responses"
|
|
116
|
+
else "anthropic_messages"
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
def model_configuration_profile(
|
|
120
|
+
self, config: ProviderConfig
|
|
121
|
+
) -> tuple[Mapping[str, Any], str | None]:
|
|
122
|
+
if self.normalize_model_id(config.model) != MUSE_SPARK_MODEL:
|
|
123
|
+
return {}, None
|
|
124
|
+
return (
|
|
125
|
+
{
|
|
126
|
+
"context_window": MUSE_SPARK_CONTEXT_WINDOW,
|
|
127
|
+
"max_model_len": MUSE_SPARK_CONTEXT_WINDOW,
|
|
128
|
+
"auto_compact_window": MUSE_SPARK_AUTO_COMPACT_LIMIT,
|
|
129
|
+
"effort_level": "high",
|
|
130
|
+
"model_profile": "muse-spark-1.1-1m",
|
|
131
|
+
},
|
|
132
|
+
"Muse Spark 1.1 profile applied: 1M context, high reasoning effort, "
|
|
133
|
+
"and 900K automatic compaction. Start a new session after changing "
|
|
134
|
+
"model, context, or reasoning effort.",
|
|
135
|
+
)
|
|
136
|
+
|
|
137
|
+
def model_selection_config_updates(
|
|
138
|
+
self, config: ProviderConfig, model_id: str
|
|
139
|
+
) -> dict[str, str]:
|
|
140
|
+
del config
|
|
141
|
+
return {
|
|
142
|
+
"haiku_model": model_id,
|
|
143
|
+
"opus_model": model_id,
|
|
144
|
+
"sonnet_model": model_id,
|
|
145
|
+
"subagent_model": model_id,
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
def option_presentation_policy(
|
|
149
|
+
self, config: ProviderConfig
|
|
150
|
+
) -> ProviderOptionPresentationPolicy:
|
|
151
|
+
del config
|
|
152
|
+
return ProviderOptionPresentationPolicy(
|
|
153
|
+
show_native=True,
|
|
154
|
+
show_tool_choice=True,
|
|
155
|
+
show_stream=True,
|
|
156
|
+
show_rate_limit_controls=True,
|
|
157
|
+
show_sampling_controls=False,
|
|
158
|
+
show_ip_family_control=True,
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
def status_policy(self, config: ProviderConfig) -> ProviderStatusPolicy:
|
|
162
|
+
del config
|
|
163
|
+
return ProviderStatusPolicy(
|
|
164
|
+
kind="catalog",
|
|
165
|
+
label="Meta Model API",
|
|
166
|
+
catalog_path="/v1/models",
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
def normalize_request_options(
|
|
170
|
+
self, config: ProviderConfig, request: Mapping[str, Any]
|
|
171
|
+
) -> Mapping[str, Any]:
|
|
172
|
+
del config
|
|
173
|
+
normalized = dict(request)
|
|
174
|
+
if "input" in normalized and "messages" not in normalized:
|
|
175
|
+
self._normalize_responses_request(normalized)
|
|
176
|
+
else:
|
|
177
|
+
self._normalize_messages_request(normalized)
|
|
178
|
+
return normalized
|
|
179
|
+
|
|
180
|
+
def normalize_tool_choice(
|
|
181
|
+
self, config: ProviderConfig, model: str, tool_choice: Any
|
|
182
|
+
) -> Any:
|
|
183
|
+
del config, model
|
|
184
|
+
if not isinstance(tool_choice, Mapping):
|
|
185
|
+
return tool_choice
|
|
186
|
+
if str(tool_choice.get("type") or "").strip().lower() == "tool":
|
|
187
|
+
return {"type": "auto"}
|
|
188
|
+
return tool_choice
|
|
189
|
+
|
|
190
|
+
def allows_sampling_overrides(self, config: ProviderConfig) -> bool:
|
|
191
|
+
del config
|
|
192
|
+
return False
|
|
193
|
+
|
|
194
|
+
@classmethod
|
|
195
|
+
def _normalize_responses_request(cls, request: dict[str, Any]) -> None:
|
|
196
|
+
include = request.get("include")
|
|
197
|
+
if request.get("previous_response_id"):
|
|
198
|
+
if isinstance(include, list):
|
|
199
|
+
values = [
|
|
200
|
+
value
|
|
201
|
+
for value in include
|
|
202
|
+
if value != "reasoning.encrypted_content"
|
|
203
|
+
]
|
|
204
|
+
if values:
|
|
205
|
+
request["include"] = values
|
|
206
|
+
else:
|
|
207
|
+
request.pop("include", None)
|
|
208
|
+
else:
|
|
209
|
+
values = list(include) if isinstance(include, list) else []
|
|
210
|
+
if "reasoning.encrypted_content" not in values:
|
|
211
|
+
values.append("reasoning.encrypted_content")
|
|
212
|
+
request["include"] = values
|
|
213
|
+
truncation = str(request.get("truncation") or "").strip().lower()
|
|
214
|
+
if truncation == "auto":
|
|
215
|
+
request["truncation"] = "disabled"
|
|
216
|
+
reasoning = request.get("reasoning")
|
|
217
|
+
if isinstance(reasoning, Mapping):
|
|
218
|
+
projected = dict(reasoning)
|
|
219
|
+
projected["effort"] = cls._effort(projected.get("effort"))
|
|
220
|
+
request["reasoning"] = projected
|
|
221
|
+
|
|
222
|
+
@classmethod
|
|
223
|
+
def _normalize_messages_request(cls, request: dict[str, Any]) -> None:
|
|
224
|
+
for key in ("stop_sequences", "top_k", "container", "inference_geo"):
|
|
225
|
+
request.pop(key, None)
|
|
226
|
+
if "temperature" in request and "top_p" in request:
|
|
227
|
+
request.pop("top_p", None)
|
|
228
|
+
thinking = request.get("thinking")
|
|
229
|
+
if isinstance(thinking, Mapping):
|
|
230
|
+
projected = dict(thinking)
|
|
231
|
+
if str(projected.get("type") or "").strip().lower() == "disabled":
|
|
232
|
+
projected = {"type": "adaptive"}
|
|
233
|
+
request["thinking"] = projected
|
|
234
|
+
output_config = request.get("output_config")
|
|
235
|
+
if isinstance(output_config, Mapping) and output_config.get("effort") is not None:
|
|
236
|
+
projected_output = dict(output_config)
|
|
237
|
+
projected_output["effort"] = cls._effort(projected_output.get("effort"))
|
|
238
|
+
request["output_config"] = projected_output
|
|
239
|
+
|
|
240
|
+
@staticmethod
|
|
241
|
+
def _effort(value: Any) -> str:
|
|
242
|
+
effort = str(value or "high").strip().lower()
|
|
243
|
+
if effort in {"none", "minimal"}:
|
|
244
|
+
return "minimal"
|
|
245
|
+
if effort in {"low", "medium", "high", "xhigh"}:
|
|
246
|
+
return effort
|
|
247
|
+
if effort in {"max", "ultra"}:
|
|
248
|
+
return "xhigh"
|
|
249
|
+
return "high"
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
__all__ = [
|
|
253
|
+
"MUSE_SPARK_AUTO_COMPACT_LIMIT",
|
|
254
|
+
"MUSE_SPARK_CONTEXT_WINDOW",
|
|
255
|
+
"MUSE_SPARK_MODEL",
|
|
256
|
+
"MetaModelProviderAdapter",
|
|
257
|
+
]
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
"""Native Codex and AGY provider-selection adapters."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from dataclasses import dataclass, field
|
|
6
|
+
from typing import Any, Mapping
|
|
7
|
+
|
|
8
|
+
from ..architecture import (
|
|
9
|
+
ProviderCapabilities,
|
|
10
|
+
ProviderConfigurationPolicy,
|
|
11
|
+
ProviderConfig,
|
|
12
|
+
ProviderModelCatalogPolicy,
|
|
13
|
+
ProviderOptionPresentationPolicy,
|
|
14
|
+
ProviderRequestPolicy,
|
|
15
|
+
ProviderStatusPolicy,
|
|
16
|
+
ProviderUiPolicy,
|
|
17
|
+
)
|
|
18
|
+
from .base import NoAuthProviderAdapter, provider_configuration
|
|
19
|
+
from .constants import DEFAULT_REQUEST_TIMEOUT_MS, PROVIDER_DEFAULT_BASE_URLS
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@dataclass(frozen=True)
|
|
23
|
+
class CodexProviderAdapter(NoAuthProviderAdapter):
|
|
24
|
+
name: str = "codex"
|
|
25
|
+
base_url: str = PROVIDER_DEFAULT_BASE_URLS["codex"]
|
|
26
|
+
configuration_defaults_value: dict = field(
|
|
27
|
+
default_factory=lambda: provider_configuration(
|
|
28
|
+
route_through_router=False,
|
|
29
|
+
request_timeout_ms=DEFAULT_REQUEST_TIMEOUT_MS,
|
|
30
|
+
)
|
|
31
|
+
)
|
|
32
|
+
capabilities_value: ProviderCapabilities = field(
|
|
33
|
+
default_factory=lambda: ProviderCapabilities(
|
|
34
|
+
upstream_protocol="openai_responses"
|
|
35
|
+
)
|
|
36
|
+
)
|
|
37
|
+
request_policy_value: ProviderRequestPolicy = field(
|
|
38
|
+
default_factory=lambda: ProviderRequestPolicy(
|
|
39
|
+
chat_path="/v1/responses", models_path="/v1/models"
|
|
40
|
+
)
|
|
41
|
+
)
|
|
42
|
+
model_catalog_policy_value: ProviderModelCatalogPolicy = field(
|
|
43
|
+
default_factory=lambda: ProviderModelCatalogPolicy(kind="configured")
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
def routing_mode_update(self, enabled: bool) -> tuple[str, ...]:
|
|
47
|
+
return (
|
|
48
|
+
"Codex routing mode updated.",
|
|
49
|
+
f"mode: {'codex-routed' if enabled else 'codex-native'}",
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
def selection_config_updates(self, config: ProviderConfig) -> Mapping[str, Any]:
|
|
53
|
+
del config
|
|
54
|
+
return {"route_through_router": False}
|
|
55
|
+
|
|
56
|
+
def selection_status_lines(self, config: ProviderConfig) -> tuple[str, ...]:
|
|
57
|
+
del config
|
|
58
|
+
return ("mode: codex-native",)
|
|
59
|
+
|
|
60
|
+
def option_presentation_policy(
|
|
61
|
+
self, config: ProviderConfig
|
|
62
|
+
) -> ProviderOptionPresentationPolicy:
|
|
63
|
+
del config
|
|
64
|
+
return ProviderOptionPresentationPolicy(show_route=True)
|
|
65
|
+
|
|
66
|
+
def ui_policy(self, config: ProviderConfig) -> ProviderUiPolicy:
|
|
67
|
+
del config
|
|
68
|
+
return ProviderUiPolicy(
|
|
69
|
+
menu_label="Codex Native",
|
|
70
|
+
routed_menu_label="Codex routed",
|
|
71
|
+
native_choice="codex:native",
|
|
72
|
+
routed_choice="codex:routed",
|
|
73
|
+
model_placeholder="Codex default",
|
|
74
|
+
advisor_placeholder="Codex native",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
def shows_claude_workflow_options(self, config: ProviderConfig) -> bool:
|
|
78
|
+
del config
|
|
79
|
+
return False
|
|
80
|
+
|
|
81
|
+
def option_timeout_default(self) -> str:
|
|
82
|
+
return "Codex default"
|
|
83
|
+
|
|
84
|
+
def api_key_status(
|
|
85
|
+
self, config: ProviderConfig, *, key_count: int, primary_detail: str
|
|
86
|
+
) -> str:
|
|
87
|
+
routed = bool(config.options.get("route_through_router"))
|
|
88
|
+
if routed:
|
|
89
|
+
if key_count > 1:
|
|
90
|
+
return (
|
|
91
|
+
f"API keys: {key_count} keys, round-robin "
|
|
92
|
+
f"(stored; Codex routed uses native login/auth headers{primary_detail})"
|
|
93
|
+
)
|
|
94
|
+
return (
|
|
95
|
+
f"API key: set (stored; Codex routed uses native login/auth headers{primary_detail})"
|
|
96
|
+
if key_count
|
|
97
|
+
else "API key: not set (uses native Codex login/auth headers)"
|
|
98
|
+
)
|
|
99
|
+
if key_count > 1:
|
|
100
|
+
return f"API keys: {key_count} keys, round-robin (Codex fallback{primary_detail})"
|
|
101
|
+
return (
|
|
102
|
+
f"API key: set (Codex fallback{primary_detail})"
|
|
103
|
+
if key_count
|
|
104
|
+
else "API key: not set (uses native Codex login/config)"
|
|
105
|
+
)
|
|
106
|
+
|
|
107
|
+
def status_policy(self, config: ProviderConfig) -> ProviderStatusPolicy:
|
|
108
|
+
del config
|
|
109
|
+
return ProviderStatusPolicy(kind="native_codex")
|
|
110
|
+
|
|
111
|
+
def configuration_policy(
|
|
112
|
+
self, config: ProviderConfig
|
|
113
|
+
) -> ProviderConfigurationPolicy:
|
|
114
|
+
del config
|
|
115
|
+
return ProviderConfigurationPolicy(
|
|
116
|
+
runtime_owns_model=True, restricts_runtime_options=True
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
@dataclass(frozen=True)
|
|
121
|
+
class AgyProviderAdapter(NoAuthProviderAdapter):
|
|
122
|
+
name: str = "agy"
|
|
123
|
+
base_url: str = PROVIDER_DEFAULT_BASE_URLS["agy"]
|
|
124
|
+
configuration_defaults_value: dict = field(
|
|
125
|
+
default_factory=lambda: provider_configuration(
|
|
126
|
+
route_through_router=False,
|
|
127
|
+
request_timeout_ms=DEFAULT_REQUEST_TIMEOUT_MS,
|
|
128
|
+
)
|
|
129
|
+
)
|
|
130
|
+
capabilities_value: ProviderCapabilities = field(
|
|
131
|
+
default_factory=lambda: ProviderCapabilities(
|
|
132
|
+
upstream_protocol="openai_responses"
|
|
133
|
+
)
|
|
134
|
+
)
|
|
135
|
+
model_catalog_policy_value: ProviderModelCatalogPolicy = field(
|
|
136
|
+
default_factory=lambda: ProviderModelCatalogPolicy(kind="configured")
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
def routing_mode_update(self, enabled: bool) -> tuple[str, ...]:
|
|
140
|
+
return (
|
|
141
|
+
"AGY routing mode updated.",
|
|
142
|
+
f"mode: {'agy-routed' if enabled else 'agy-native'}",
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
def selection_config_updates(self, config: ProviderConfig) -> Mapping[str, Any]:
|
|
146
|
+
del config
|
|
147
|
+
return {"route_through_router": False}
|
|
148
|
+
|
|
149
|
+
def selection_status_lines(self, config: ProviderConfig) -> tuple[str, ...]:
|
|
150
|
+
del config
|
|
151
|
+
return ("mode: agy-native",)
|
|
152
|
+
|
|
153
|
+
def option_presentation_policy(
|
|
154
|
+
self, config: ProviderConfig
|
|
155
|
+
) -> ProviderOptionPresentationPolicy:
|
|
156
|
+
del config
|
|
157
|
+
return ProviderOptionPresentationPolicy(show_route=True)
|
|
158
|
+
|
|
159
|
+
def ui_policy(self, config: ProviderConfig) -> ProviderUiPolicy:
|
|
160
|
+
del config
|
|
161
|
+
return ProviderUiPolicy(
|
|
162
|
+
menu_label="AGY",
|
|
163
|
+
routed_menu_label="AGY Routed",
|
|
164
|
+
native_choice="agy:native",
|
|
165
|
+
routed_choice="agy:routed",
|
|
166
|
+
model_placeholder="AGY default",
|
|
167
|
+
advisor_placeholder="AGY native",
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
def option_timeout_default(self) -> str:
|
|
171
|
+
return "AGY default"
|
|
172
|
+
|
|
173
|
+
def api_key_status(
|
|
174
|
+
self, config: ProviderConfig, *, key_count: int, primary_detail: str
|
|
175
|
+
) -> str:
|
|
176
|
+
del key_count, primary_detail
|
|
177
|
+
return (
|
|
178
|
+
"API key: not set (uses native AGY Google sign-in/keyring)"
|
|
179
|
+
if config.options.get("route_through_router")
|
|
180
|
+
else "API key: not set (uses native AGY Google sign-in/config)"
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
def status_policy(self, config: ProviderConfig) -> ProviderStatusPolicy:
|
|
184
|
+
del config
|
|
185
|
+
return ProviderStatusPolicy(kind="native_agy")
|
|
186
|
+
|
|
187
|
+
def configuration_policy(
|
|
188
|
+
self, config: ProviderConfig
|
|
189
|
+
) -> ProviderConfigurationPolicy:
|
|
190
|
+
del config
|
|
191
|
+
return ProviderConfigurationPolicy(runtime_owns_model=True)
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
__all__ = ["AgyProviderAdapter", "CodexProviderAdapter"]
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
"""Self-hosted NVIDIA NIM provider adapter."""
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass, field, replace
|
|
4
|
+
|
|
5
|
+
from ..architecture import (
|
|
6
|
+
ProviderCapabilities,
|
|
7
|
+
ProviderConfig,
|
|
8
|
+
ProviderContextPolicy,
|
|
9
|
+
ProviderOptionPresentationPolicy,
|
|
10
|
+
ProviderStatusPolicy,
|
|
11
|
+
)
|
|
12
|
+
from .base import OpenAICompatibleProviderAdapter, provider_configuration
|
|
13
|
+
from .constants import DEFAULT_REQUEST_TIMEOUT_MS, PROVIDER_DEFAULT_BASE_URLS
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(frozen=True)
|
|
17
|
+
class SelfHostedNimProviderAdapter(OpenAICompatibleProviderAdapter):
|
|
18
|
+
name: str = "self-hosted-nim"
|
|
19
|
+
base_url: str = PROVIDER_DEFAULT_BASE_URLS["self-hosted-nim"]
|
|
20
|
+
configuration_defaults_value: dict = field(
|
|
21
|
+
default_factory=lambda: provider_configuration(
|
|
22
|
+
"model",
|
|
23
|
+
api_key="not-used",
|
|
24
|
+
custom_models=("model",),
|
|
25
|
+
native_compat=True,
|
|
26
|
+
rate_limit_rpm=0,
|
|
27
|
+
rate_limit_status=False,
|
|
28
|
+
context_window=32768,
|
|
29
|
+
max_output_tokens=4096,
|
|
30
|
+
temperature=0.7,
|
|
31
|
+
top_p=0.8,
|
|
32
|
+
context_reserve_tokens=1024,
|
|
33
|
+
request_timeout_ms=DEFAULT_REQUEST_TIMEOUT_MS,
|
|
34
|
+
stream_enabled=True,
|
|
35
|
+
stream_word_chunking=False,
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
send_placeholder_key: bool = True
|
|
39
|
+
capabilities_value: ProviderCapabilities = field(
|
|
40
|
+
default_factory=lambda: ProviderCapabilities(
|
|
41
|
+
upstream_protocol="openai_chat", local=True
|
|
42
|
+
)
|
|
43
|
+
)
|
|
44
|
+
|
|
45
|
+
def requires_catalog_model_selection(self, config: ProviderConfig) -> bool:
|
|
46
|
+
del config
|
|
47
|
+
return True
|
|
48
|
+
|
|
49
|
+
def option_presentation_policy(
|
|
50
|
+
self, config: ProviderConfig
|
|
51
|
+
) -> ProviderOptionPresentationPolicy:
|
|
52
|
+
return replace(super().option_presentation_policy(config), show_rate_limit=True)
|
|
53
|
+
|
|
54
|
+
def context_policy(self, config: ProviderConfig) -> ProviderContextPolicy:
|
|
55
|
+
del config
|
|
56
|
+
return ProviderContextPolicy(
|
|
57
|
+
capacity_strategy="remote_first",
|
|
58
|
+
settings_strategy="standard",
|
|
59
|
+
status_capacity_strategy="openai_budget",
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
def status_policy(self, config: ProviderConfig) -> ProviderStatusPolicy:
|
|
63
|
+
return replace(
|
|
64
|
+
super().status_policy(config),
|
|
65
|
+
unreachable_hint="Start NIM or set a reachable Anthropic-compatible Base URL before launching Claude Code.",
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
__all__ = ["SelfHostedNimProviderAdapter"]
|