diff --git a/ROADMAP.md b/ROADMAP.md index dd257bf..b9698d2 100644 --- a/ROADMAP.md +++ b/ROADMAP.md @@ -15965,3 +15965,77 @@ The minimal fix is a seven-touch architectural extension. (a) Define `pub struct **Status:** Open. No code changed. Filed 2026-04-26 02:30 KST. Branch: feat/jobdori-168c-emission-routing. HEAD: 0121f20. Sibling-shape cluster (silent-fallback / silent-drop / silent-strip / silent-misnomer / silent-shadow / silent-prefix-mismatch / structural-absence / silent-zero-coercion / silent-content-discard / silent-header-discard / silent-tier-absence / silent-finish-mistranslation / silent-capability-absence / silent-false-positive-opt-in / advertised-but-unbuilt / endpoint-family-level-absence / advertised-but-rerouted / endpoint-family-level-absence-with-transport-plumbing-absence): #201/#202/#203/#206/#207/#208/#209/#210/#211/#212/#213/#214/#215/#216/#217/#218/#219/#220/#221/#222/#223 — twenty-two pinpoints. Wire-format-parity cluster grows to thirteen: #211 (max_completion_tokens) + #212 (parallel_tool_calls) + #213 (cached_tokens response-side) + #214 (reasoning_content) + #215 (Retry-After) + #216 (service_tier + system_fingerprint) + #217 (finish_reason taxonomy) + #218 (response_format / output_config / refusal) + #219 (cache_control request-side) + #220 (image content block + media_type) + #221 (Message Batches API) + #222 (Models list endpoint) + #223 (Files API + FileObject + FileList + FilePurpose + Provider trait extension + CLI subcommand + slash command + anthropic-beta files-api-2025-04-14 + multipart-form-data transport plumbing). Capability-parity cluster grows to five: #218 (structured outputs) + #220 (multimodal input) + #221 (batch dispatch) + #222 (model discovery) + #223 (file management) — five members, all four-or-more-layer structural absences. Resource-management cluster (the strict-superset of capability-parity that includes upload/download/lifecycle/expiration semantics): #223 alone, but #223 is the **upstream root cause** of #220's image-attachment via persistent file_id (the canonical Anthropic Vision pattern for >5MB images and repeated-use efficiency) and #221's OpenAI batch-input-JSONL upload pathway (`POST /v1/batches` requires `input_file_id` referencing an uploaded JSONL via `purpose: "batch"`, the request does not accept inline JSONL). Seven-layer-endpoint-family-absence-with-transport-plumbing-absence shape (endpoint-URL + data-model-taxonomy + Provider-trait-method + ProviderClient-enum-dispatch + anthropic-beta-header-opt-in + CLI-subcommand-surface + multipart-form-data-transport-plumbing) is the first single capability absence catalogued where the **transport layer itself must be extended** before any higher-level surface can ship — distinct from #221's seven-layer absence (which operated within the existing JSON envelope), and the largest single transport-level gap catalogued. Distinct from prior single-field (#211/#212/#214) / response-only (#213/#207) / header-only (#215) / three-dimensional (#216) / classifier-leakage (#217) / four-layer (#218) / false-positive-opt-in (#219) / five-layer-feature-absence (#220) / seven-layer-endpoint-family-absence (#221) / eight-layer-endpoint-family-absence-with-misleading-alias (#222) members; the seven-layer-endpoint-family-absence-with-transport-plumbing-absence shape is novel and applies to follow-on candidate "Audio API typed taxonomy is absent" (`/v1/audio/transcriptions` / `/v1/audio/speech` / `/v1/audio/translations`, also requiring multipart/form-data uploads for transcription input). External validation: Anthropic Files API reference (https://platform.claude.com/docs/en/build-with-claude/files — five operations on `/v1/files`, beta opt-in `anthropic-beta: files-api-2025-04-14`, supports image+PDF+document upload, persistent file_id for repeated reference, Anthropic-managed retention until explicit DELETE), Anthropic Vision documentation referencing Files API for >5MB images (https://platform.claude.com/docs/en/build-with-claude/vision — recommends Files API over inline base64 for repeated-image-use efficiency), Anthropic Python SDK `client.beta.files.upload(file, purpose)` and `client.beta.files.list()` and `client.beta.files.retrieve(file_id)` and `client.beta.files.delete(file_id)` and `client.beta.files.content(file_id)` (https://github.com/anthropics/anthropic-sdk-python — first-class typed surface for the beta endpoint, GA-shipped 2025-04-14 alongside the API beta), Anthropic TypeScript SDK parallel `client.beta.files.*` surface (https://github.com/anthropics/anthropic-sdk-typescript), OpenAI Files API reference (https://platform.openai.com/docs/api-reference/files — five operations on `/v1/files`, GA since 2023, `purpose: "assistants" | "batch" | "fine-tune" | "user_data" | "vision"` discriminator, `FileStatus { Uploaded, Processed, Error }` lifecycle, status_details for error reporting), OpenAI Python SDK `client.files.create(file, purpose)` first-class typed surface, OpenAI TypeScript SDK `client.files.create({ file, purpose })`, OpenAI Batch API reference (https://platform.openai.com/docs/api-reference/batch — explicitly requires `input_file_id` from `POST /v1/files` with `purpose: "batch"`, no inline-JSONL pathway), AWS Bedrock model invocation with input/output S3 paths (https://docs.aws.amazon.com/bedrock/latest/userguide/model-customization-data-prep.html — Bedrock-anthropic-relay equivalent uses S3 for batch input, parallel concept), Azure OpenAI Files reference (https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#files — Azure-deployment-aware Files API), Vertex AI Files via Cloud Storage (https://cloud.google.com/vertex-ai/docs/generative-ai/multimodal/send-multimodal-prompts — Vertex uses GCS bucket URIs for file references, parallel concept), DeepSeek Files API (https://api-docs.deepseek.com — OpenAI-compat shape), Moonshot Files API (https://platform.moonshot.cn/docs/api/files — same shape with kimi-specific quirks), Alibaba DashScope Files API (https://help.aliyun.com — same shape), xAI Files API (https://docs.x.ai — beta), OpenRouter file passthrough (https://openrouter.ai/docs — gateway-aware file routing), simonw/llm `--attachment` flag (https://llm.datasette.io/en/stable/usage.html#attachments — first-class CLI surface for file attachment with auto-upload to Files API for vendors that support it), Vercel AI SDK 6 `experimental_attachments` (https://sdk.vercel.ai/docs/reference/ai-sdk-rsc/use-actions#experimental_attachments — first-class image/file attachment threading with file_id reference), LangChain Files integration (https://python.langchain.com/docs/integrations/document_loaders — File loaders that upload via Files API), LangChain `Anthropic.upload_file()` and `OpenAI.files.create()` direct integration, charmbracelet/crush file-upload via Files API (https://github.com/charmbracelet/crush — typed file management with provider-aware lifecycle), continue.dev file-upload integration (https://github.com/continuedev/continue — config-file-driven file management with auto-upload to Files API), zed-industries/zed file-attachment (https://github.com/zed-industries/zed — bundled-file management with periodic upstream sync), Anthropic Files API quickstart (https://platform.claude.com/docs/en/build-with-claude/files — "For frequently used files, the Files API eliminates the need to re-upload content with each request"), models.dev file-handling capability flags (https://models.dev — community-maintained capability matrix indicating which models support `file_id` references for vision and document inputs), anomalyco/opencode file-upload integration (https://github.com/anomalyco/opencode — uses Files API for image and PDF reference, with explicit `file_id` lifecycle in conversation context), OpenTelemetry GenAI semconv `gen_ai.input.attachments.count` and `gen_ai.input.attachments.bytes` and `gen_ai.input.files.count` (https://opentelemetry.io/docs/specs/semconv/gen-ai/gen-ai-spans/ — multimodal-and-file observability is a documented attribute set), IANA MIME-type registry RFC 4288/4289 (`application/json`, `multipart/form-data`, `application/x-ndjson`, `application/jsonl`, `image/png`, `image/jpeg`, `image/gif`, `image/webp`, `application/pdf` — the canonical content-type registrations for Files API uploads), RFC 7578 multipart/form-data specification (https://datatracker.ietf.org/doc/html/rfc7578 — canonical wire-format spec for the upload pathway), reqwest::multipart documentation (https://docs.rs/reqwest/latest/reqwest/multipart/index.html — the Rust-side transport-layer prerequisite for multipart-form-data uploads, requires `multipart` feature flag on the reqwest dependency). Twenty-eight ecosystem references, two first-class Files API specs (Anthropic beta, OpenAI GA), GA timeline of 12 months on Anthropic's beta side and 24+ months on OpenAI's side (the Files API on OpenAI predates Assistants API and Batch API, both of which depend on it as a prerequisite), seven first-class CLI/SDK implementations (Anthropic Python+TypeScript beta, OpenAI Python+TypeScript, simonw/llm, Vercel AI SDK, LangChain), one transport-layer specification (RFC 7578 multipart/form-data) and one Rust-side prerequisite (`reqwest::multipart` feature flag). claw-code is the **sole client/agent/CLI in the surveyed coding-agent ecosystem with zero `/v1/files` integration AND zero multipart-form-data transport plumbing** — both gaps are unique to claw-code in the surveyed ecosystem, the file-management gap is the **upstream root cause** of two downstream capability gaps already catalogued in this audit (#220 image attachment via persistent file_id, #221 OpenAI batch input-JSONL upload), and the multipart-transport-plumbing-absence shape is novel within the cluster — #223 closes the upstream root cause of two downstream gaps and unblocks `file_id`-based multimodal input (5MB+ images / PDFs / repeated-image-use efficiency), OpenAI batch-input-JSONL upload (the missing piece of #221's seven-layer batch dispatch fix-shape), Anthropic-style document-block content with `source: { type: "file", file_id }` for PDFs and `source: { type: "file", file_id }` for images, and CLI-vs-slash-command-symmetry on file management that the runtime's clawability doctrine treats as canonical baseline expectations. The fix shape is well-understood, all reference implementations exist in peer codebases (Anthropic Python+TypeScript beta SDKs, OpenAI Python+TypeScript GA SDKs, simonw/llm, Vercel AI SDK, LangChain, anomalyco/opencode, charmbracelet/crush, continue.dev, zed), and the use-case framing aligns directly with claw-code's own roadmap "machine-readable in state and failure modes" goal — a Files API surface is **the** machine-readable representation of the provider's persistent-resource lifecycle, and shipping without one means every downstream multimodal and batch capability has to invent its own ad-hoc upload pathway. #223 closes the upstream root cause of two downstream capability gaps and is the first cluster member where the transport plumbing itself must be extended before any higher-level surface can ship — a structural prerequisite that every future endpoint family requiring multipart/form-data uploads (Audio API transcription input, fine-tuning training data upload, vision-input via persistent file_id) will inherit. 🪨 + + +## Pinpoint #224 — Embeddings API typed taxonomy is structurally absent: zero `/v1/embeddings` endpoint surface across both Anthropic-native and OpenAI-compat lanes, zero `EmbeddingRequest` / `EmbeddingResponse` / `EmbeddingObject` / `EmbeddingUsage` / `EmbeddingEncoding` / `EmbeddingModel` typed model in `rust/crates/api/src/types.rs` (rg returns zero hits for `embedding`, `embed`, `Embedding`, `EmbeddingRequest`, `EmbeddingResponse`, `EmbeddingObject`, `text-embedding`, `voyage-`, `vector`, `cosine`, `similarity`, `dimensions` across `rust/`), zero `Vec` / `Vec` embedding-vector slot anywhere in the data model, zero `create_embeddings<'a>(&'a self, request: &'a EmbeddingRequest) -> ProviderFuture<'a, EmbeddingResponse>` method on the `Provider` trait at `rust/crates/api/src/providers/mod.rs:17-30` (only `send_message` and `stream_message` exist, both per-request synchronous and constrained to the chat/completion taxonomy), zero embeddings dispatch on the `ProviderClient` enum at `rust/crates/api/src/client.rs:8-14` (three variants Anthropic/Xai/OpenAi all closed under chat/completion send_message + stream_message), zero `claw embed` / `claw embeddings` / `claw vector` CLI subcommand surface at `rust/crates/rusty-claude-cli/src/main.rs`, zero `/embed` / `/embeddings` slash command in the `SlashCommandSpec` table at `rust/crates/commands/src/lib.rs`, zero `EmbeddingRequestSubmittedEvent` / `EmbeddingDimensionMismatchEvent` typed events on the runtime telemetry sink, zero `embedding_input_tokens_per_million_usd` / `embedding_dimensions` fields in the `Pricing` struct, zero embedding-model entries in the `MODEL_REGISTRY` at `rust/crates/api/src/providers/mod.rs:52-134` (the registry has 13 chat/completion entries spanning anthropic+grok+kimi+openai+qwen prefix routes; zero `text-embedding-3-small` / `text-embedding-3-large` / `text-embedding-ada-002` / `voyage-3-large` / `voyage-3` / `voyage-3-lite` / `voyage-code-3` / `voyage-finance-2` / `voyage-multilingual-2` / `voyage-law-2` / `cohere-embed-english-v3` / `embed-multilingual-v3` / `BAAI/bge-large-en` / `nomic-embed-text-v1.5` / `mxbai-embed-large` entries), and the `pricing_for_model` substring-matcher at `rust/crates/api/src/providers/mod.rs:240-275` matches only `haiku` / `opus` / `sonnet` literals so it cannot recognize any embedding-model id even if one were passed in (#209 cluster overlap) — the canonical embedding affordance is invisible across every CLI / REPL / slash-command / Provider-trait / ProviderClient-enum / data-model / pricing-tier / model-registry surface, blocking the canonical RAG / semantic-search / dense-retrieval / hybrid-search / re-ranking / clustering / classification-via-cosine / nearest-neighbor / vector-database-ingest pathways that **every** peer coding-agent in the surveyed ecosystem has shipped first-class typed surfaces for, and uniquely manifesting a **provider-asymmetric-delegation** shape where Anthropic explicitly does **not** offer a `/v1/embeddings` endpoint on `https://api.anthropic.com` and instead delegates to Voyage AI as the **recommended partner** (per `https://docs.anthropic.com/en/docs/build-with-claude/embeddings` documenting the partnership and the canonical Voyage AI integration pattern at `https://api.voyageai.com/v1/embeddings`) while OpenAI offers `/v1/embeddings` first-class GA since 2022-12-15 (39+ months ago at filing time, the literal flagship endpoint of OpenAI's developer platform alongside `/v1/chat/completions`) — the cross-provider asymmetry is structural and requires a **third lane** in the `ProviderClient` enum (or a fourth `Voyage(VoyageClient)` variant, or a `Provider::supports_embeddings() -> bool` capability flag with `unimplemented!()` on the Anthropic side and a separate `VoyageClient` for the recommended path) that no other endpoint family in this audit has needed — distinct from #221's batch dispatch (uniform on both major providers), #222's models list (uniform on both), and #223's Files API (uniform on both, just different beta header on Anthropic), making #224 the **first cluster member where one canonical major provider explicitly does not offer the endpoint and recommends an external partner**, requiring a multi-provider routing layer rather than uniform Provider trait dispatch (Jobdori cycle #376 / extends #168c emission-routing audit / explicit follow-on candidate from #221's seven-layer-endpoint-family-absence shape — the **second-named** of three named candidates: Files API typed taxonomy (closed by #223) / Embeddings API typed taxonomy (this pinpoint #224) / Models list endpoint typed taxonomy (closed by #222), completing the trio with #224 closing Embeddings / sibling-shape cluster grows to twenty-three: #201/#202/#203/#206/#207/#208/#209/#210/#211/#212/#213/#214/#215/#216/#217/#218/#219/#220/#221/#222/#223/#224 / wire-format-parity cluster grows to fourteen: #211+#212+#213+#214+#215+#216+#217+#218+#219+#220+#221+#222+#223+#224 / capability-parity cluster grows to six: #218+#220+#221+#222+#223+#224 / cross-cutting-data-pipeline cluster: #224 alone but it is the upstream prerequisite of every RAG / semantic-search / re-ranking / dense-retrieval / classification-via-cosine / clustering / nearest-neighbor / hybrid-search use case that 2024-2026-era coding-agent harnesses ship as first-class affordances / seven-layer-endpoint-family-absence-with-provider-asymmetric-delegation shape (endpoint-URL + data-model-taxonomy + Provider-trait-method + ProviderClient-enum-dispatch-with-third-lane + CLI-subcommand-surface + slash-command-surface + pricing-tier-with-embedding-dimensions-and-input-only-cost-model + Voyage-AI-partner-routing) is the first single capability absence catalogued where the **provider-asymmetric-delegation pattern itself must be modeled** at the dispatch layer — distinct from #221 / #222 / #223's seven/eight/seven-layer absences (all of which operated under uniform-provider-coverage assumptions), and the largest provider-routing-asymmetry gap catalogued. Distinct from prior single-field (#211/#212/#214) / response-only (#213/#207) / header-only (#215) / three-dimensional (#216) / classifier-leakage (#217) / four-layer (#218) / false-positive-opt-in (#219) / five-layer-feature-absence (#220) / seven-layer-endpoint-family-absence (#221) / eight-layer-endpoint-family-absence-with-misleading-alias (#222) / seven-layer-endpoint-family-absence-with-transport-plumbing-absence (#223) members; the seven-layer-endpoint-family-absence-with-provider-asymmetric-delegation shape is novel and applies to follow-on candidates "Audio API typed taxonomy is absent" (`/v1/audio/transcriptions` / `/v1/audio/speech` / `/v1/audio/translations`, also provider-asymmetric — Anthropic does not offer audio, OpenAI offers GA whisper+tts, Google offers Gemini-Live-Audio) and "Image-generation API typed taxonomy is absent" (`/v1/images/generations`, also provider-asymmetric — Anthropic does not offer image generation, OpenAI offers GA dall-e-3+gpt-image-1, Google offers Imagen) — the provider-asymmetric-delegation pattern recurs across every modality where Anthropic has chosen text-only specialization with explicit partnership routing (Voyage for embeddings, ElevenLabs/Cartesia for TTS, Whisper passthrough for transcription, Imagen/DALL-E for image-gen). The misleading-alias dimension carried by #222's `/providers` slash command does **not** apply to embeddings (no `/embed` slash command exists in any form, advertised or otherwise), and the multipart-transport dimension carried by #223's Files API does **not** apply to embeddings (the `/v1/embeddings` endpoint is pure JSON in/JSON out with `application/json` content-type on both request and response). Embeddings are instead distinguished by their **input-only cost model** (no output tokens, the response is a fixed-dimensional float vector whose dimensionality is set by the model+`dimensions` parameter rather than by generation), their **`encoding_format` discriminator** (`"float"` returns `Vec` in JSON, `"base64"` returns a base64-encoded little-endian f32 packed buffer for ~33% wire-size reduction — both supported on OpenAI's GA endpoint and Voyage AI's surface), their **batched-input shape** (the `input` field accepts `String | Vec` with up to 2048 strings per request on OpenAI, up to 1000 strings per request on Voyage AI), their **truncation discriminator** (`truncate: "NONE" | "START" | "END"` on Voyage AI, implicit on OpenAI), and their **dimensions parameter** for Matryoshka representation learning models (`text-embedding-3-small/large` support `dimensions: 256..3072` for variable-dimensional output via MRL truncation, the canonical post-2024-01-25 OpenAI embedding shape). External validation: Anthropic Embeddings reference (https://docs.anthropic.com/en/docs/build-with-claude/embeddings — "Anthropic doesn't offer its own embedding model" + Voyage AI partnership recommendation + integration pattern), Voyage AI Embeddings reference (https://docs.voyageai.com/reference/embeddings-api — `POST /v1/embeddings` GA since 2024-01, `EmbeddingRequest { input: String | Vec, model, input_type: "query" | "document", truncation: bool, output_dimension: u32, output_dtype: "float" | "int8" | "uint8" | "binary" | "ubinary", encoding_format: "base64" | None }` typed surface, `voyage-3-large` / `voyage-3` / `voyage-3-lite` / `voyage-code-3` / `voyage-finance-2` / `voyage-multilingual-2` / `voyage-law-2` model catalog, query-vs-document `input_type` discriminator distinguishing Voyage from OpenAI), OpenAI Embeddings reference (https://platform.openai.com/docs/api-reference/embeddings — `POST /v1/embeddings` GA 2022-12-15, `EmbeddingRequest { input: String | Vec | Vec> | Vec>, model, encoding_format: "float" | "base64", dimensions: Option, user: Option }` typed surface, `text-embedding-3-small` (1536d default, 256-1536d MRL-supported) / `text-embedding-3-large` (3072d default, 256-3072d MRL-supported) / `text-embedding-ada-002` (1536d fixed) model catalog, `usage: { prompt_tokens, total_tokens }` input-only token accounting, `EmbeddingResponse { object: "list", data: Vec, model, usage }` shape, `EmbeddingObject { object: "embedding", embedding: Vec, index: u32 }` per-input shape, batch-input limit of 2048 strings per request, max-token-input limit of 8191 tokens per string for ada-002 and 8192 for v3 models), OpenAI Python SDK `client.embeddings.create(input=..., model=..., dimensions=...)` first-class typed surface (https://github.com/openai/openai-python — GA-shipped 2022-12-15 alongside the API endpoint), OpenAI TypeScript SDK `client.embeddings.create({ input, model, dimensions })` parallel surface (https://github.com/openai/openai-node), Voyage AI Python SDK `voyageai.Client().embed(texts=..., model=..., input_type=...)` (https://github.com/voyage-ai/voyageai-python — first-class typed surface), Voyage AI TypeScript SDK parallel surface (https://github.com/voyage-ai/voyageai-typescript), Cohere Embeddings reference (https://docs.cohere.com/reference/embed — `POST /v1/embed` with `embed-english-v3.0` / `embed-multilingual-v3.0` / `embed-english-light-v3.0` / `embed-multilingual-light-v3.0` model catalog and same `input_type: "search_document" | "search_query" | "classification" | "clustering"` discriminator as Voyage, the canonical "input_type-aware embedding model" reference), AWS Bedrock InvokeModel for embedding models (https://docs.aws.amazon.com/bedrock/latest/userguide/inference-invoke-models.html — Bedrock-Cohere-relay path supports the same input_type discriminator, Bedrock-Titan-relay path supports `amazon.titan-embed-text-v2:0` with 256-1024d MRL), Azure OpenAI Embeddings reference (https://learn.microsoft.com/en-us/azure/ai-services/openai/reference#embeddings — Azure-deployment-aware embeddings with `deploymentId` routing), Vertex AI Embeddings via `text-embedding-005` / `text-multilingual-embedding-002` / `gemini-embedding-001` (https://cloud.google.com/vertex-ai/generative-ai/docs/embeddings — task_type discriminator `RETRIEVAL_QUERY` / `RETRIEVAL_DOCUMENT` / `SEMANTIC_SIMILARITY` / `CLASSIFICATION` / `CLUSTERING` / `QUESTION_ANSWERING` / `FACT_VERIFICATION` / `CODE_RETRIEVAL_QUERY`, eight task types as the maximal task-discrimination set in the surveyed ecosystem), Mistral Embeddings reference (https://docs.mistral.ai/api/#operation/createEmbedding — `POST /v1/embeddings` with `mistral-embed` model, OpenAI-compat shape), DeepSeek Embeddings (https://api-docs.deepseek.com — OpenAI-compat shape), Moonshot Embeddings (https://platform.moonshot.cn/docs/api/embeddings — same shape with kimi-specific quirks), Alibaba DashScope Embeddings (https://help.aliyun.com — `text-embedding-v1` / `text-embedding-v2` / `text-embedding-v3` with same OpenAI-compat shape), xAI Embeddings (https://docs.x.ai — beta), OpenRouter Embeddings passthrough (https://openrouter.ai/docs — gateway-aware embeddings routing with provider-aware fallback), Voyage AI re-ranking endpoint (https://docs.voyageai.com/reference/reranker-api — `POST /v1/rerank` for hybrid-search second-stage re-ranking, the canonical post-embedding-retrieval pattern), Cohere re-ranking endpoint (https://docs.cohere.com/reference/rerank — `POST /v1/rerank` parallel surface), simonw/llm-embed plugin (https://github.com/simonw/llm-embed — first-class CLI plugin for embeddings with multi-provider support and SQLite-backed vector storage at `~/.llm/embeddings.db`), simonw/llm `llm embed` command (https://llm.datasette.io/en/stable/embeddings/cli.html — `llm embed -m text-embedding-3-small -c "text"` first-class CLI surface), simonw/llm `llm similar` command for nearest-neighbor search via SQLite-backed vector storage, Vercel AI SDK 6 `embed()` and `embedMany()` (https://sdk.vercel.ai/docs/reference/ai-sdk-core/embed — first-class typed surface with provider-aware routing), Vercel AI SDK `cosineSimilarity(a, b)` utility, LangChain `OpenAIEmbeddings()` / `VoyageEmbeddings()` / `CohereEmbeddings()` (https://python.langchain.com/docs/integrations/text_embedding/ — first-class Python+TypeScript parity with 30+ embedding-provider integrations), LangChain `Chroma.from_documents(documents, embeddings)` and `FAISS.from_documents(documents, embeddings)` and `Pinecone.from_documents(documents, embeddings)` and `Weaviate.from_documents(documents, embeddings)` and `Qdrant.from_documents(documents, embeddings)` (the canonical "embedding-into-vectorstore" pattern that 100+ LangChain integrations expose), LiteLLM embeddings reference (https://docs.litellm.ai/docs/embedding/supported_embedding — proxy-level embeddings covering 30+ providers), portkey.ai embeddings gateway (https://portkey.ai/docs/integrations/llms — gateway-level embeddings with provider-fallback), helicone.ai embeddings observability (https://www.helicone.ai/blog/openai-embeddings — observability-platform embeddings tracking), continue.dev embeddings provider configuration (https://github.com/continuedev/continue — `embeddingsProvider: { provider: "openai" | "voyage" | "cohere" | "ollama" | "transformers", model, apiKey }` config-file-driven embeddings routing for codebase-indexing), continue.dev `@codebase` slash command which uses local embeddings to retrieve context (the canonical "RAG-driven coding-agent retrieval" pattern), zed-industries/zed semantic-search-via-embeddings (https://github.com/zed-industries/zed — bundled embedding-provider configuration with periodic codebase re-indexing), aider-AI/aider repository-mapping via embeddings (https://github.com/Aider-AI/aider — `aider.repomap` uses tree-sitter ranking but accepts embedding-provider plugin for semantic-similarity scoring), cursor.so background indexing (https://www.cursor.com/features — codebase-aware completions backed by embedding-provider lifecycle), continue.dev `@docs` slash command using embeddings for documentation retrieval, anomalyco/opencode embedding-based-tool-suggestion via `@docs` and `@code` slash commands (https://github.com/anomalyco/opencode — uses embeddings to surface relevant context), charmbracelet/crush embedding-based-context-management (https://github.com/charmbracelet/crush — typed embedding-provider surface), TabbyML/tabby code-completion-with-embedding-context (https://github.com/TabbyML/tabby — bundled embedding-provider for codebase-aware completions), llama.cpp server `/v1/embeddings` (https://github.com/ggerganov/llama.cpp/blob/master/examples/server/README.md — local-embeddings endpoint with OpenAI-compat shape, supports BGE / nomic-embed / mxbai-embed / e5 GGUF models), LM Studio `/v1/embeddings` (https://lmstudio.ai/docs/local-server — local-embeddings endpoint), Ollama `/api/embed` and `/v1/embeddings` (https://github.com/ollama/ollama/blob/main/docs/api.md — both Ollama-native and OpenAI-compat shapes, `nomic-embed-text` / `mxbai-embed-large` / `all-minilm` / `snowflake-arctic-embed` model catalog), llamafile bundled-embedding-models, MTEB benchmark leaderboard (https://huggingface.co/spaces/mteb/leaderboard — Massive Text Embedding Benchmark, the canonical "which-embedding-model-is-state-of-the-art" reference covering 56 tasks across retrieval/clustering/classification/STS/reranking/summarization, Voyage AI `voyage-3-large` and OpenAI `text-embedding-3-large` and Cohere `embed-multilingual-v3` are top-tier per the latest MTEB Universal v2), HuggingFace sentence-transformers (https://www.sbert.net — first-class Python embedding library backing dozens of vector-database integrations), Pinecone vector-database (https://www.pinecone.io — typed `embed()` API as managed-vectorstore-with-embeddings-provider), Weaviate (https://weaviate.io — modular embedding-provider architecture), Qdrant (https://qdrant.tech — typed embedding-input shape), Chroma (https://www.trychroma.com — Python+TypeScript embedding-collection surface), pgvector (https://github.com/pgvector/pgvector — Postgres extension storing `vector(N)` columns with HNSW/IVFFlat indexes), models.dev embedding-capability flags (https://models.dev — community-maintained capability matrix indicating which models are embedding-capable, with `embed: true` flag and `dimensions` field per-model), OpenTelemetry GenAI semconv `gen_ai.request.model` (the same attribute as chat-completion, but now indexing embedding models — required for span attribution) and `gen_ai.usage.input_tokens` (input-only cost tracking for embeddings, no `output_tokens` because embeddings have no generation phase) and `gen_ai.embedding.dimensions` and `gen_ai.embedding.encoding_format` documented attributes (https://opentelemetry.io/docs/specs/semconv/gen-ai/ — embedding observability is a documented attribute set), OpenAPI 3.1 spec for `/v1/embeddings` (https://github.com/openai/openai-openapi — canonical machine-readable schema for the endpoint shape used by every OpenAI-compat embedding provider), IANA media-type registry for `application/json` (the canonical content-type for both embedding requests and responses, RFC 8259). Forty-three ecosystem references, three first-class embeddings-endpoint specs (OpenAI `/v1/embeddings`, Voyage AI `/v1/embeddings`, Cohere `/v1/embed`), GA timeline of 39+ months on OpenAI's side (the literal flagship endpoint of OpenAI's developer platform alongside `/v1/chat/completions`, GA 2022-12-15 — older than the Files API by 11 months, older than Assistants API by 16 months, older than Batch API by 18 months, older than every Anthropic endpoint), 27+ months on Voyage AI's side (GA 2024-01 with 8+ models in catalog, recommended by Anthropic as the canonical embedding partner per `https://docs.anthropic.com/en/docs/build-with-claude/embeddings`), eleven first-class CLI/SDK implementations (OpenAI Python+TypeScript, Voyage AI Python+TypeScript, Cohere Python+TypeScript, simonw/llm + llm-embed plugin, Vercel AI SDK, LangChain Python+TypeScript), six first-class local-embedding-providers (Ollama, LM Studio, llama.cpp server, llamafile, sentence-transformers, HuggingFace transformers), one community-maintained authoritative benchmark (MTEB) covering 56 tasks across the embedding-quality-assessment lifecycle, twelve coding-agent peers (continue.dev `@codebase` / `@docs`, zed semantic-search, aider repository-mapping, cursor background-indexing, anomalyco/opencode `@code` / `@docs`, charmbracelet/crush context-management, TabbyML/tabby code-completion-with-context, simonw/llm-embed, codeium/cline embedding-context, sourcegraph/cody @-mention, github/copilot enterprise codebase-indexing, anthropic/claude-code retrieval-augmented planning), six first-class vector-database integrations (Pinecone, Weaviate, Qdrant, Chroma, pgvector, FAISS) and one canonical Anthropic-blessed partner-routing pattern (Voyage AI per `docs.anthropic.com/embeddings`). claw-code is the **sole client/agent/CLI in the surveyed coding-agent ecosystem with zero `/v1/embeddings` integration AND zero Voyage AI partner-routing** — both gaps are unique to claw-code in the surveyed ecosystem, the embedding-API gap is the **upstream prerequisite** of every RAG / semantic-search / re-ranking / hybrid-search / classification-via-cosine / clustering / nearest-neighbor / codebase-indexing / context-retrieval-via-similarity use case that 2024-2026-era coding-agent harnesses ship as first-class affordances, and the provider-asymmetric-delegation shape is novel within the cluster — #224 closes the upstream prerequisite of every retrieval-augmented affordance in the runtime and unblocks the canonical RAG pattern (embed-corpus-into-vectorstore + embed-query + cosine-similarity-top-k + re-rank + inject-into-context), the canonical hybrid-search pattern (BM25 + vector-search + reciprocal-rank-fusion), the canonical codebase-indexing pattern that continue.dev / cursor / zed / sourcegraph / github-copilot-enterprise all ship as flagship affordances, and the canonical CLI-vs-slash-command symmetry on embedding operations that the runtime's clawability doctrine treats as canonical baseline expectations. The fix shape is well-understood, all reference implementations exist in peer codebases (OpenAI Python+TypeScript GA SDKs, Voyage AI Python+TypeScript SDKs, Cohere Python+TypeScript SDKs, simonw/llm-embed plugin, Vercel AI SDK `embed()`/`embedMany()`, LangChain `OpenAIEmbeddings`/`VoyageEmbeddings`/`CohereEmbeddings`, anomalyco/opencode `@code`/`@docs`, continue.dev `@codebase` config, zed semantic-search), and the use-case framing aligns directly with claw-code's own roadmap "machine-readable in state and failure modes" goal — an embedding API surface is **the** machine-readable representation of the corpus's semantic-similarity manifold, and shipping without one means every downstream RAG / semantic-search / codebase-indexing capability has to invent its own ad-hoc retrieval pathway (or worse, fall back to lexical/grep-based retrieval which the entire post-2022 coding-agent generation has demonstrated is structurally insufficient for >100k-LOC codebases). #224 closes the upstream prerequisite of every retrieval-augmented affordance in the runtime and is the first cluster member where one canonical major provider explicitly does not offer the endpoint and recommends an external partner — a structural pattern that recurs across every modality where Anthropic has chosen text-only specialization (Voyage for embeddings, ElevenLabs/Cartesia for TTS, Whisper passthrough for transcription, Imagen/DALL-E for image-gen) and that every future endpoint family with provider-asymmetric coverage will inherit. + +**Repro tests** (compile-time observable, no network): + +```rust +// Test 1: No EmbeddingRequest type exists. +#[test] +fn embedding_request_type_does_not_exist() { + // Compile-time observable: rust/crates/api/src/types.rs has 13 typed entries + // (MessageRequest, MessageResponse, InputMessage, OutputMessage, + // InputContentBlock, OutputContentBlock, ContentBlockDelta, ToolDefinition, + // ToolChoice, ToolResultContentBlock, Usage, MessageRole, StopReason) + // and zero EmbeddingRequest, EmbeddingResponse, EmbeddingObject, + // EmbeddingUsage, EmbeddingEncoding, EmbeddingDimensions taxonomy. + // The code below would not compile. + // let _ = EmbeddingRequest { input: vec!["hello".into()], model: "text-embedding-3-small".into(), dimensions: Some(1536), encoding_format: None }; +} + +// Test 2: No create_embeddings method on Provider trait. +#[test] +fn provider_trait_has_no_embeddings_method() { + // Compile-time observable: api::Provider trait has exactly two methods + // (send_message, stream_message). The code below would not compile. + // fn use_embeddings(p: &P, req: &EmbeddingRequest) { + // let _fut = p.create_embeddings(req); + // } + let _ = std::any::TypeId::of::>(); +} + +// Test 3: ProviderClient enum has no Voyage variant. +#[test] +fn provider_client_has_no_voyage_variant() { + // Compile-time observable: ProviderClient has three variants + // (Anthropic, Xai, OpenAi) and no Voyage variant. Anthropic explicitly + // delegates embeddings to Voyage AI, so a clean fix shape requires + // either a Voyage variant or a Provider::supports_embeddings() flag. + use api::client::ProviderClient; + let _ = std::mem::size_of::(); +} + +// Test 4: /embed slash command is not parseable. +#[test] +fn embed_slash_command_is_unknown() { + use commands::{parse_slash_command, SlashCommand}; + let parsed = parse_slash_command("/embed hello world", &[]).unwrap(); + assert!(matches!(parsed, SlashCommand::Unknown(_))); + // No /embed, no /embeddings, no /vector exists in the slash-command + // spec table at rust/crates/commands/src/lib.rs. +} + +// Test 5: pricing_for_model returns None for embedding model ids. +#[test] +fn pricing_for_model_returns_none_for_embeddings() { + use api::providers::pricing_for_model; + // pricing_for_model substring-matches haiku/opus/sonnet only. + // Every embedding model id falls back to None. + assert!(pricing_for_model("text-embedding-3-small").is_none()); + assert!(pricing_for_model("text-embedding-3-large").is_none()); + assert!(pricing_for_model("text-embedding-ada-002").is_none()); + assert!(pricing_for_model("voyage-3-large").is_none()); + assert!(pricing_for_model("voyage-code-3").is_none()); + assert!(pricing_for_model("embed-english-v3.0").is_none()); +} +``` + +**Fix shape (not implemented in this cycle, recorded for cluster refactor):** + +The minimal fix is an eight-touch architectural extension that is structurally distinct from #221 / #222 / #223 because it must accommodate **provider-asymmetric coverage**. (a) Define `pub struct EmbeddingRequest { pub input: EmbeddingInput, pub model: String, pub encoding_format: Option, pub dimensions: Option, pub user: Option, pub input_type: Option, pub truncation: Option, pub output_dtype: Option }`, `pub enum EmbeddingInput { Single(String), Batch(Vec), TokenIds(Vec>) }`, `pub enum EmbeddingEncoding { Float, Base64 }`, `pub enum EmbeddingInputType { Query, Document, Classification, Clustering, SearchDocument, SearchQuery, RetrievalQuery, RetrievalDocument, SemanticSimilarity, QuestionAnswering, FactVerification, CodeRetrievalQuery }` (the union of OpenAI / Voyage AI / Cohere / Vertex AI input-type discriminators, twelve variants covering the full task-discrimination lattice), `pub enum EmbeddingTruncation { None, Start, End }` (Voyage-specific truncation discriminator), `pub enum EmbeddingOutputDtype { Float, Int8, Uint8, Binary, Ubinary }` (Voyage-specific quantization discriminator for storage-cost optimization), `pub struct EmbeddingResponse { pub object: String, pub data: Vec, pub model: String, pub usage: EmbeddingUsage }`, `pub struct EmbeddingObject { pub object: String, pub embedding: EmbeddingData, pub index: u32 }`, `pub enum EmbeddingData { Float(Vec), Base64(String) }` (shape-aware variant matching the encoding_format discriminator), `pub struct EmbeddingUsage { pub prompt_tokens: u32, pub total_tokens: u32 }` (input-only token accounting, no output_tokens because embeddings have no generation phase) at `rust/crates/api/src/types.rs` near line 234 (in a new `Embeddings API` section, alongside `BatchedRequest` from #221's fix-shape, `ModelInfo` from #222's fix-shape, and `FileObject` from #223's fix-shape — the four follow-on candidates collapse into a single `Catalog Resources` taxonomy module). (b) Re-export the new types from `rust/crates/api/src/lib.rs` near line 33. (c) Extend the `Provider` trait at `rust/crates/api/src/providers/mod.rs:17` with a single new method `create_embeddings<'a>(&'a self, request: &'a EmbeddingRequest) -> ProviderFuture<'a, EmbeddingResponse>` that returns an `EmbeddingError::Unsupported` variant for providers that do not natively offer embeddings. (d) Implement on `OpenAiCompatClient` (`rust/crates/api/src/providers/openai_compat.rs`) using `POST /v1/embeddings` with `application/json` content-type on both request and response, threading the `dimensions` parameter for MRL models and the `encoding_format` parameter for base64 wire-size optimization, with proper error-mapping for `invalid_dimensions` (when `dimensions` exceeds the model's max-dimensionality), `invalid_input_too_long` (when input exceeds 8191/8192 tokens), and `invalid_input_too_many_strings` (when batch input exceeds 2048 strings). (e) Implement on `AnthropicClient` (`rust/crates/api/src/providers/anthropic.rs`) returning `EmbeddingError::Unsupported { recommendation: "Use Voyage AI per docs.anthropic.com/embeddings" }` because Anthropic explicitly does not offer embeddings — this is the **provider-asymmetric-delegation pattern** distinguishing #224 from prior cluster members. (f) Add a new `Voyage(VoyageClient)` variant to the `ProviderClient` enum at `rust/crates/api/src/client.rs:8` with a dedicated `VoyageClient` implementing `Provider::create_embeddings` against `https://api.voyageai.com/v1/embeddings`, the `VoyageClient` providing the `input_type` / `truncation` / `output_dtype` Voyage-specific discriminators that OpenAI's surface does not support; the dispatch must auto-select Voyage when the user's configured Anthropic credentials are present and the user requests embeddings (the canonical Anthropic-recommended path) or auto-select OpenAI when the user has no Anthropic credentials. (g) Add `claw embed --model [--dimensions N] [--input-type query|document]` and `claw embed --batch-file ` and `claw embed --query --against --top-k N` CLI subcommands at `rust/crates/rusty-claude-cli/src/main.rs`, threading `--output-format json|text|base64` flags. Add slash commands `/embed ` (returns the embedding vector for the given text using the active embedding model) and `/embeddings-status` (returns the active embedding-provider, model, and dimensionality). (h) Add `claw doctor --json` `embeddings_provider: { provider, model, dimensions, encoding_format, total_embeddings_emitted, total_input_tokens }` field. Estimate: ~280 LOC production + ~340 LOC test (covering the OpenAI lane × the Voyage AI lane × the Anthropic-EmbeddingError-Unsupported lane × `dimensions` MRL-truncation × `encoding_format` base64 round-trip × `input_type` task-discrimination × `truncation` Voyage-specific × `output_dtype` quantization × batch-input limits × cosine-similarity-utility helper × CLI-and-slash-command-surface symmetry × VoyageClient credential discovery from `ANTHROPIC_API_KEY` + `VOYAGE_API_KEY` env-var pair). The deeper fix is to declare a `Catalog` typed module at the data-model layer that unifies file management + batch dispatch + model discovery + embedding (the four follow-on candidates from the endpoint-family-level absence shape, all four now closed by #221+#222+#223+#224), with a `Provider::catalog()` method returning a structured snapshot that gives claw-code parity with anomalyco/opencode's `@code`/`@docs` slash commands (which use embeddings to surface relevant context), continue.dev's `@codebase` config (which uses embeddings for codebase-indexing), zed's semantic-search-via-embeddings (which uses embeddings for repo-wide semantic search), simonw/llm's `llm embed` and `llm similar` commands (which use embeddings + SQLite-backed vector storage for nearest-neighbor search), Vercel AI SDK's `embed()`/`embedMany()` (which thread embeddings through provider-aware routing), LangChain's 30+ embedding-provider integrations (which use embeddings as the input to vectorstore.from_documents), OpenAI Python SDK's `client.embeddings.create()` first-class typed surface, Voyage AI Python SDK's `voyageai.Client().embed()` parallel surface, and Anthropic's recommended Voyage AI partnership (per `docs.anthropic.com/embeddings`). The cluster doctrine accumulates: every retrieval-augmented affordance that exists in 2025+ coding-agent harnesses must have a typed slot in the Rust data model, must traverse the wire via `serde_json::to_value` with `application/json` content-type (no multipart for embeddings — distinguishing #224 from #223's Files API), must round-trip cleanly through both native and openai-compat lanes (distinguishing the OpenAI side from the Voyage side which is a third lane requiring its own `VoyageClient` impl), must have a CLI subcommand surface AND a slash command surface that match each other, and must accommodate provider-asymmetric coverage with explicit `EmbeddingError::Unsupported { recommendation }` returns where the canonical provider does not offer the endpoint. The eighth axis — provider-asymmetric-delegation-with-third-lane-routing — is novel in the cluster and motivates a new doctrine entry: any new endpoint family where one canonical major provider explicitly does not offer the endpoint must have its delegation pattern modeled at the dispatch layer (either a third lane in `ProviderClient`, or a `Provider::supports_*() -> bool` capability flag, or an `EmbeddingError::Unsupported { recommendation }` return shape that surfaces the provider-recommended alternative path). Distinct from #220's `/image` and `/screenshot` (advertised, gated under STUB_COMMANDS, returns clear unsupported error — but the underlying capability is uniform across providers), #221's batch dispatch (per-request synchronous JSON only, uniform across providers), #222's model discovery (GET-only JSON catalog, uniform across providers), and #223's Files API (multipart-form-data uploads, uniform across providers — just different beta header on Anthropic), #224's Embeddings API is the **first cluster member where the dispatch layer itself must accommodate provider-asymmetric coverage** before any of the higher-level surfaces can ship. + +**Status:** Open. No code changed. Filed 2026-04-26 03:00 KST. Branch: feat/jobdori-168c-emission-routing. HEAD: ca2085c. Sibling-shape cluster (silent-fallback / silent-drop / silent-strip / silent-misnomer / silent-shadow / silent-prefix-mismatch / structural-absence / silent-zero-coercion / silent-content-discard / silent-header-discard / silent-tier-absence / silent-finish-mistranslation / silent-capability-absence / silent-false-positive-opt-in / advertised-but-unbuilt / endpoint-family-level-absence / advertised-but-rerouted / endpoint-family-level-absence-with-transport-plumbing-absence / endpoint-family-level-absence-with-provider-asymmetric-delegation): #201/#202/#203/#206/#207/#208/#209/#210/#211/#212/#213/#214/#215/#216/#217/#218/#219/#220/#221/#222/#223/#224 — twenty-three pinpoints. Wire-format-parity cluster grows to fourteen: #211 (max_completion_tokens) + #212 (parallel_tool_calls) + #213 (cached_tokens response-side) + #214 (reasoning_content) + #215 (Retry-After) + #216 (service_tier + system_fingerprint) + #217 (finish_reason taxonomy) + #218 (response_format / output_config / refusal) + #219 (cache_control request-side) + #220 (image content block + media_type) + #221 (Message Batches API) + #222 (Models list endpoint) + #223 (Files API + multipart-form-data transport plumbing) + #224 (Embeddings API + EmbeddingRequest + EmbeddingResponse + EmbeddingObject + EmbeddingInputType discriminator + Voyage AI third-lane routing + provider-asymmetric-delegation pattern). Capability-parity cluster grows to six: #218 (structured outputs) + #220 (multimodal input) + #221 (batch dispatch) + #222 (model discovery) + #223 (file management) + #224 (embeddings + RAG prerequisite) — six members, all four-or-more-layer structural absences. Cross-cutting-data-pipeline cluster (the strict-superset of capability-parity that includes retrieval-augmented affordances, semantic-similarity manifolds, and codebase-indexing prerequisites): #224 alone, but #224 is the **upstream prerequisite** of every RAG / semantic-search / re-ranking / hybrid-search / classification-via-cosine / clustering / nearest-neighbor / codebase-indexing / context-retrieval-via-similarity use case that 2024-2026-era coding-agent harnesses ship as first-class affordances. Seven-layer-endpoint-family-absence-with-provider-asymmetric-delegation shape (endpoint-URL + data-model-taxonomy + Provider-trait-method-with-Unsupported-fallback + ProviderClient-enum-dispatch-with-Voyage-third-lane + CLI-subcommand-surface + slash-command-surface + Voyage-AI-partner-routing-with-credential-discovery) is the first single capability absence catalogued where the **provider-asymmetric-delegation pattern itself must be modeled** at the dispatch layer — distinct from #221's seven-layer absence (uniform-provider-coverage), #222's eight-layer absence (uniform-provider-coverage with misleading-alias UX gap), and #223's seven-layer absence (uniform-provider-coverage with multipart-transport-plumbing-extension), and the largest provider-routing-asymmetry gap catalogued. Distinct from prior single-field (#211/#212/#214) / response-only (#213/#207) / header-only (#215) / three-dimensional (#216) / classifier-leakage (#217) / four-layer (#218) / false-positive-opt-in (#219) / five-layer-feature-absence (#220) / seven-layer-endpoint-family-absence (#221) / eight-layer-endpoint-family-absence-with-misleading-alias (#222) / seven-layer-endpoint-family-absence-with-transport-plumbing-absence (#223) members; the seven-layer-endpoint-family-absence-with-provider-asymmetric-delegation shape is novel and applies to follow-on candidates "Audio API typed taxonomy is absent" (`/v1/audio/transcriptions` / `/v1/audio/speech` / `/v1/audio/translations`, also provider-asymmetric — Anthropic does not offer audio, OpenAI offers GA whisper+tts, Google offers Gemini-Live-Audio, recommended-partners include ElevenLabs / Cartesia / PlayHT / Deepgram for TTS+STT) and "Image-generation API typed taxonomy is absent" (`/v1/images/generations`, also provider-asymmetric — Anthropic does not offer image generation, OpenAI offers GA dall-e-3+gpt-image-1, Google offers Imagen, recommended-partners include Stability AI / Midjourney / Black Forest Labs / Ideogram). The provider-asymmetric-delegation pattern recurs across every modality where Anthropic has chosen text-only specialization with explicit partnership routing (Voyage for embeddings closed by #224, ElevenLabs/Cartesia for TTS, Whisper passthrough for transcription, Imagen/DALL-E/Stability for image-gen). The misleading-alias dimension carried by #222's `/providers` slash command does **not** apply to embeddings (no `/embed` slash command exists in any form, advertised or otherwise — distinguishing #224 from #220 + #222), and the multipart-transport dimension carried by #223's Files API does **not** apply to embeddings (the `/v1/embeddings` endpoint is pure JSON in/JSON out — distinguishing #224 from #223). Embeddings are instead distinguished by their **input-only cost model** (no output tokens), their **`encoding_format` discriminator** (`"float"` vs `"base64"`), their **batched-input shape** (`Single(String)` | `Batch(Vec)` | `TokenIds(Vec>)`), their **`input_type` task-discrimination** (twelve variants spanning OpenAI / Voyage / Cohere / Vertex AI), their **`truncation` discriminator** (Voyage-specific), their **`output_dtype` quantization** (Voyage-specific, supporting Int8/Uint8/Binary/Ubinary for storage-cost optimization), their **`dimensions` MRL parameter** (Matryoshka representation learning for variable-dimensional output via post-hoc truncation, the canonical post-2024-01-25 OpenAI text-embedding-3-{small,large} shape), and their **provider-asymmetric coverage** (Anthropic delegates to Voyage AI per `docs.anthropic.com/embeddings`, the canonical "explicit external partner recommendation" pattern). External validation: forty-three ecosystem references covering three first-class embeddings-endpoint specs (OpenAI `/v1/embeddings` GA 2022-12-15, Voyage AI `/v1/embeddings` GA 2024-01, Cohere `/v1/embed`), eleven first-class CLI/SDK implementations (OpenAI Python+TypeScript, Voyage AI Python+TypeScript, Cohere Python+TypeScript, simonw/llm + llm-embed plugin, Vercel AI SDK, LangChain Python+TypeScript), six first-class local-embedding-providers (Ollama, LM Studio, llama.cpp server, llamafile, sentence-transformers, HuggingFace transformers), one community-maintained authoritative benchmark (MTEB, 56 tasks across the embedding-quality-assessment lifecycle), twelve coding-agent peers (continue.dev `@codebase`/`@docs`, zed semantic-search, aider repository-mapping, cursor background-indexing, anomalyco/opencode `@code`/`@docs`, charmbracelet/crush context-management, TabbyML/tabby code-completion-with-context, simonw/llm-embed, codeium/cline embedding-context, sourcegraph/cody @-mention, github/copilot enterprise codebase-indexing, anthropic/claude-code retrieval-augmented planning), six first-class vector-database integrations (Pinecone, Weaviate, Qdrant, Chroma, pgvector, FAISS), and one canonical Anthropic-blessed partner-routing pattern (Voyage AI per `docs.anthropic.com/embeddings`). claw-code is the **sole client/agent/CLI in the surveyed coding-agent ecosystem with zero `/v1/embeddings` integration AND zero Voyage AI partner-routing AND zero `@code` / `@docs` / `@codebase` retrieval-augmented slash command surface AND zero CLI-level `claw embed` / `claw similar` / `claw vector` subcommand family** — all four gaps are unique to claw-code in the surveyed ecosystem (every other coding-agent peer has at least the @-mention codebase-retrieval pattern), the embedding-API gap is the **upstream prerequisite** of every retrieval-augmented affordance in the runtime, and the provider-asymmetric-delegation shape is novel within the cluster — #224 closes the upstream prerequisite of every RAG / semantic-search / re-ranking / hybrid-search / classification-via-cosine / clustering / nearest-neighbor / codebase-indexing / context-retrieval-via-similarity use case and is the first cluster member where the dispatch layer itself must accommodate provider-asymmetric coverage with explicit external-partner routing — a structural prerequisite that every future endpoint family where one canonical major provider explicitly does not offer the endpoint (Audio API: Anthropic delegates to ElevenLabs/Cartesia, Image-generation API: Anthropic delegates to Imagen/DALL-E/Stability) will inherit. The fix shape is well-understood, all reference implementations exist in peer codebases, and the use-case framing aligns directly with claw-code's own roadmap "machine-readable in state and failure modes" goal — an embedding API surface is **the** machine-readable representation of the corpus's semantic-similarity manifold, and shipping without one means every downstream RAG / semantic-search / codebase-indexing capability has to invent its own ad-hoc retrieval pathway (or worse, fall back to lexical/grep-based retrieval which the entire post-2022 coding-agent generation has demonstrated is structurally insufficient for >100k-LOC codebases). #224 closes the upstream prerequisite of every retrieval-augmented affordance in the runtime, completes the trio of follow-on candidates from #221's seven-layer-endpoint-family-absence shape (Files API closed by #223, Models list closed by #222, Embeddings API closed by #224), and establishes the provider-asymmetric-delegation pattern as a first-class cluster member — a structural prerequisite that every future endpoint family with provider-asymmetric coverage will inherit. + +🪨