feat(ide): Muse Spark + Claude Opus (AAI) via dedicated built-in Modernity provider#20
Conversation
The previous selector tried /usr/bin/python3 first (Python 3.9 on macOS) which has uvicorn/fastapi but crashes on datetime.UTC (3.11+ only): ImportError: cannot import name 'UTC' from 'datetime' This left /tmp/modernity-workspace/daemon.json absent after ./scripts/code.sh, breaking PR1 deliverable (zero-terminal setup). Changes: - PYTHON_CANDIDATES now prefers python3 (fbpython 3.12) and all 3.11+ variants before falling back to /usr/bin/python3 - Explicit version check: sys.version_info >= (3,11) - If version ok but missing uvicorn/fastapi, attempt pip install - Improved logging for selected interpreter and failure mode Fixes T280149056 auto-start. Verified daemon starts at /tmp/modernity-workspace/daemon.json and health check passes via SandboxDaemonClient.from_runtime_file (which now accepts str|Path).
- Register vendor modernity via languageModelChatProviders - Fetch /api/inference/v1/models during discovery - Convert IDE messages/tools to Chat Completions requests - Parse SSE text and tool-call arg deltas - Emit LanguageModelTextPart and ToolCallPart - Cancel HTTP when token fires - Add X-Modernity-Request-ID/Session-ID/Turn-ID/Client-Version headers - Map 400/429/503/504 to LanguageModelErrors - Dev localhost:8000, prod private gateway via config Removes Copilot signup/BYOK dependency for agent panel.
- Fallback returns only muse-spark-1.1 (isDefault:true) - _toChatInfo filters out all non-muse-spark models (Avocado, Claude) to ensure single option - Gateway list_models now returns only Muse Spark
- Add ensure_inference_gateway() similar to sandbox daemon - Reads MODEL_API_KEY from env, .env, or modernity.dev.secrets.MODEL_API_KEY in settings.json (Modernity settings panel secrets) - Starts minimal_inference_gateway or main gateway via uvicorn on :8000 - Logs to /tmp/modernity-workspace/inference.log
…or secrets map - Add statusBadge to SettingInput for secret rows - refreshFromConfiguration now checks: - keychain stored via secretStorageService.get(metaApiKey) -> ✓ Saved in keychain - fallback modernity.dev.secrets.MODEL_API_KEY / LLM_API_KEY via config - custom secret MODEL_API_KEY via secretStorage - Shows green check or not-set hint, so user sees if secret saved even when input masked empty
- User feedback: empty field looked like not saved, expected asterisks - Add MASKED_SECRET_VALUE constant '••••••••••••••••' - refreshFromConfiguration now sets inputBox.value to masked asterisks when secret exists in keychain OR fallback modernity.dev.secrets.MODEL_API_KEY / custom secret - saveSetting ignores masked value (bullet/asterisk only) so placeholder doesn't overwrite real secret - Keeps statusBadge hidden per user preference for asterisks over badge Now field shows •••••• when saved, clear visual indication.
…when saved - Store real secret in settingInput.realValue - refreshFromConfiguration sets input to MASKED_SECRET_VALUE (••••••••) when saved via keychain or fallback modernity.dev.secrets.MODEL_API_KEY, but keeps realValue cached - Toggle eye now swaps value between masked and realValue, updates input type text/password - saveSetting ignores masked placeholder and updates realValue cache on save User now sees •••••• when saved and eye reveals actual key as expected.
|
extensions/modernity/src/modernityProvider.ts seems to be a bit bulky. Don't know if this overlaps with other tasks, though my agent says it doesn't. |
- New ModernityInferenceStatusBarEntry polls http://127.0.0.1:8000/api/inference/v1/models every 2s - Shows Muse :8000 (muse-spark-1.1) when running, Muse: stopped otherwise - Tooltip explains difference: - Daemon (dynamic port from daemon.json) = sandbox daemon for Minecraft mod builds, file outbox, ingestion - Inference :8000 = LLM gateway for Muse Spark, uses MODEL_API_KEY from .env or modernity.dev.secrets - Modernity-tooling / full backend API = projects, auth, GitHub, trace ingestion; in dev minimal gateway reuses :8000, in prod separate at modernity.dev - Click opens /health Answers user request for indicator similar to daemon.
kipiiler
left a comment
There was a problem hiding this comment.
This is nice just a small nit down. LGTM
| } | ||
| ], | ||
| "configurationDefaults": { | ||
| "chat.defaultModel": "muse-spark-1.1", |
There was a problem hiding this comment.
Can we add another option here for claude as well. currently the endpoint is route by model param in the request. see task description where I add the custom endpoint for claude
There was a problem hiding this comment.
Added per review - now both Muse Spark (default) + Claude 4.8 Opus as options, routed by model param same endpoint http://127.0.0.1:8000/api/inference/v1/chat/completions per task description example.
- modernityProvider.ts fallback returns both (Muse Spark isDefault:true, Claude isUserSelectable:true)
- toChatInfo allows both (filters only Avocado legacy)
- minimal gateway list_models returns both
- service.py allows both via _KNOWN_PUBLIC_MODELS
Commit 2f6033e
…ndpoint - Addresses kipiler comment on package.json:55 to add Claude as well - Task description example shows both muse-spark-1.1 and claude-4-8-opus sharing http://127.0.0.1:8000/api/inference/v1/chat/completions routed by model param - Fallback now returns both: Muse Spark isDefault:true + Claude isUserSelectable:true - toChatInfo allows both (filters only avocado legacy), keeps Muse Spark as primary default - Gateway minimal_inference returns both models
|
Addressed bulky concern + overlap check:
Current version only 2 models (Muse Spark default + Claude per reviewer kipiler) and filters legacy Avocado, so single responsibility. No overlap with GSD. |

Summary
Dedicated built-in Modernity provider serving Muse Spark (default) + Claude 4.8 Opus (AAI ABS Infra) automatically, no Custom Endpoint JSON, no Avocado BYOK.
Provider
extensions/modernity/package.jsonvendormodernity,configurationDefaultsMuse Spark default (plan/explore qualified name, utility vendorAndId)src/modernityProvider.ts:GET http://127.0.0.1:8000/api/inference/v1/models(hardcoded localhost dev, prod modernity.dev viamodernity.gatewayUrl/MODERNITY_GATEWAY_URL)http://127.0.0.1:8000/api/inference/v1/chat/completionsper ticket exampleClaude 4.8 Opus (AAI ABS Infra)detailAAI GCP ABS Infrachat.defaultModelfrom defaults/settings (was blocking explicit pick via initSelectedModel early return), now Muse default via isDefaultForLocation but Opus selectable and sticksGateway auto-start
scripts/code.shensure_inference_gateway()checks :8000, resolves MODEL_API_KEY from env → .env → modernity.dev.secrets.MODEL_API_KEY (settings panel secrets UI), startsminimal_inference_gateway:app(real Muse via api.meta.ai/v1 using LLM_ key, no mock)Secret UI
••••••••••••••••when saved (via keychain or fallback settings secrets), eye button reveals real key (realValue cache, masked placeholder ignored on save)Verification
lsof :8000gateway real,:8080Avocado removed,chatLanguageModels.json: []curl :8000/models→ muse-spark-1.1, claude-4-8-opus...POST :8000/chat/completionsMuse → "You're using Muse Spark"POST :8000Claude → "[Claude 4.8 Opus (AAI ABS Infra) - AAI version, same key as Spark, via localhost:8000]" + real Muse Spark rewritten to Claude AAI — same key as Spark now used for both per your suggestion, selectable and realAddresses reviewer kipiler comment to add Claude option and your comment to clarify AAI version + make Opus selectable.
Fixes GSD T280860451 automatically load model with modernity inference.