Repository navigation
feat(model-provider): offers/runs contract, openai_compat + h3_video adapters (stacked on collaboration-candidate) - #17
Conversation
…adapters (P0–P3) Anders-aligned model provider capsule: one contract for inference from any backend (local, Sparks/LAN, Carrier-reached, hosted). - offer/run JSON schemas (elastos.model.offer/v1); offers_list gated on configured backends (flash_url / h3_url from env — SSRF-closed) - run state machine + registry with concurrency policy; runs_get returns full events; runs_cancel cooperative - openai_compat adapter: Flash chat, content:null/reasoning quirk normalization, policy_violation error codes - h3_video adapter: multipart submit, streaming download to .partial, sha256 mid-stream, content-addressed rename (32-hex id), dogfood sidecar json - plumbing: registry reserved name, spawn block, provider proxy allowlist, provider_resource model arm + fail-closed tests - scripts/model-provider-smoke.sh: end-to-end P0–P3 gate harness Gates: docs/00-handoff/model-provider-gates/P0..P3 in Sparks. Co-authored-by: Cursor <cursoragent@cursor.com>
…e, control-plane registration Ports the dogfooded esp capsule shape onto the rebased base: - offer.rs: model descriptor wrapped in elastos.service.offer/v1 with service_kind "model" (Anders' publish contract); no placeholder DIDs. - main.rs: offers derive from configured services only — no fallback offer; runs_create on an unconfigured chat backend fails closed with "chat backend is not configured" instead of dispatching to an empty URL. - adapters: drop wall-clock run ceilings (caller owns the compute; runs end on completion, cancel, or genuine upstream failure); h3_video artifacts are content-addressed (sha256[..32]) with .partial → atomic rename. - server_infra: register model-provider on the gateway control-plane path too (spawn_host_providers=false), passing operator env (OLLAMA_URL/ OLLAMA_MODEL/CREATIVE_URL) through Init config.extra — SSRF-closed, matching the ai-provider pattern. llama/ai/availability gating unchanged. - gateway_provider_proxy: record that per-principal grant enforcement for model/runs_create is Runtime-owned; no provider-side grant store. - gateway_tests/model: runs_create dispatch via app allowlist (interim, pre Runtime grant enforcement). Co-authored-by: Cursor <cursoragent@cursor.com>
…cement test - run.rs: terminal runs carry terminal_at and are evicted on the next create after a 10-minute TTL. The registry is a run surface, not a retention store — offer policy declares data_retention_seconds: 0; the TTL exists only so clients can fetch final events/artifacts. 3 unit tests. - handlers/provider.rs tests: prove the session path derives elastos://model/<offer>/runs_create + Action::Execute and that enforce_capability denies tokenless delegated calls and Read-scoped tokens, and admits an Execute token (A15). Resolved without code change: - A13 (cancel honesty): the ported adapters already check the cancel flag between stream chunks and mid-download, removing .partial output; the h3_video header documents that the sync upstream has no remote abort. - A14 (audit_events): every provider capsule's manifest declares audit_events as Runtime-projection policy (19/19 capsules) — the declaration is the convention, emission is Runtime-side. No deviation; wiring lands with the Runtime grant work. Co-authored-by: Cursor <cursoragent@cursor.com>
|
For the base, I think the model-provider core should be extracted onto For grants, Inbox should handle the approval experience, while the common Runtime provider boundary enforces the resulting grant. The Home gateway should authenticate the launch, derive the principal and session, then enter that same Runtime path. The model provider should not maintain a separate grant store. The current Home route still dispatches after checking only the Home token, so this remains open. Runs should belong to the stable principal, not only the temporary session. Runtime should keep the mapping to the provider run and issue a narrow per-run capability or opaque handle. This allows a later authenticated session belonging to the same principal to recover the run. It also provides a clean path for revocation and deliberate delegation. Packaging can be a separate stacked slice, but it must land before the feature is called installable. The current For the protected-content questions, I cannot find A few implementation details also need correction. The current provider reaches LAN or hosted backends through direct HTTP rather than the future Runtime-selected Carrier route, and video output is written directly into the Library directory layout instead of crossing the Runtime object boundary. The video offer advertises settings the implementation rejects, accepts a reference input it ignores, and ignores the configured chat model name. The old The smoke script uses an undefined variable, expects the old video filename format and expects a duration limit that the implementation does not enforce. The offers/runs direction is good and worth preserving, but principal grants, run ownership, truthful packaging, transport and object boundaries, contract accuracy and working proof should be addressed before merge. |
|
Not implementing #17 this week — leaving it open as the offers/runs direction you said to preserve. Your review stands and we will not merge this stack as-is:
Current Home ask for review is #23 (first-run URUX on the harness freeze). After that lands and you name the base, we will come back to a smaller 0.7-dev extraction rather than keep stacking on |
|
@SashaMIT superseded by the current model contract. |
|
@SashaMIT confirmed: please close (superseded by the current model contract); move any idea worth keeping to an issue first. |
|
Closing as superseded by the current model contract. I checked develop: elastos-model-contract, provider_resource.rs and the h3_video adapter exist there, and docs/MODEL_PROVIDER.md binds runs to the consumer principal, capsule and run (this PR's open A11). |
Summary
One commit (
3027d9540, +2473, 17 files) stacked on the frozenreview/collaboration-candidatetip (b07160cf1). Rebase completed with zero textual conflicts; one semantic drift found and fixed (newGatewayStatecollaboration fields ingateway_tests/model.rs).Adds the model-provider capsule and its Runtime integration:
capsules/model-provider/: offers/runs contract with two adapters —openai_compat(chat) andh3_video(video). SSRF-closed: upstream URLs come only from Initextra(operator config), never from requests. No env vars. No placeholder DIDs in offers.elastos-server/src/provider_resource.rs: mapsmodelscheme ops to capability resources (elastos://model/<offer_id>/<op>); unknown ops fail closed.elastos-server/src/server_infra.rs: spawns and registers the capsule alongside existing providers.elastos-server/src/api/gateway_provider_proxy.rs: Home-gui-token-gated ops (offers_list,runs_create,runs_get,runs_events,runs_cancel,ping).elastos-server/src/api/gateway_tests/model.rs: 12 gateway tests.scripts/model-provider-smoke.sh: operator smoke harness.Verification (gate run on this branch, 14 Aug)
cargo fmt --all -- --check— cleangit diff --check— cleanscripts/check-wci-alignment.sh— OKcargo test -p elastos-server model— 12 passed, 0 failedKnown follow-ups (not claimed here)
runs_createis not yet wired; where should it live? (Q2)components.jsonpackaging for the capsule not included (Q4).runs_get/runs_events/runs_cancelanyrun_id. We did not improvise a capsule-side ACL; see Q3.Questions for Anders
review/collaboration-candidatethe right base, or do you want this retargeted toupstream/0.7-dev? (One commit; retarget is cheap.)run_idto the session that created it?components.jsonpackaging for new capsules belong in this PR or in your release process?feat/protected-content-contractsreview (38/38 tests green, spec fully matched):CarrierEndpointIdtightening — any wire-compat impact on Irzhy's dKMS port if the encoding narrows?Test plan
cargo test -p elastos-server model(12/12)scripts/model-provider-smoke.sh) against live pair A — pending Sparks availabilityMade with Cursor
Part of #84.
Part of #85.