Example 25: Embedder
What It Is
Embedder is the provider boundary for semantic comparison inside DAG nodes. The Archivist provisions an embedder cascade, injects the selected embedder through services, and uses vectors for intent classification, memory recall, ranking, and similarity checks.
The graph does not need to know whether vectors come from local Ollama, a browser-capable backend, or a cloud service. Nodes ask for an EmbedderInterface; application bootstrapping decides which implementation is available.
How It Works
The host provisions an EmbedderInterface before DAG execution and passes it through service injection. Nodes call the embedder to produce vectors, then apply domain logic such as cosine similarity or threshold routing. The registry and cascade mirror the LLM adapter surface, so availability probing and provider selection happen outside the graph.
That symmetry is deliberate. If your application can configure chat providers through an adapter cascade, it can configure embedding providers through the same registry/cascade style.
Diagrams, Examples, and Outputs
DAG registration and diagram
The embedder is injected service state; the graph shows where semantic recall and ranking fit in the live flow. The Archivist and The Dispatcher own this principle through intent classification and semantic recall.
Archivist embedder DAG
55 placements{
"@context": {
"@version": 1.1,
"name": {
"@id": "https://noocodec.dev/ontology/dag/name"
},
"version": {
"@id": "https://noocodec.dev/ontology/dag/version"
},
"entrypoints": {
"@id": "https://noocodec.dev/ontology/dag/entrypoints",
"@container": "@index"
},
"nodes": {
"@id": "https://noocodec.dev/ontology/dag/nodes",
"@container": "@set"
},
"outputs": {
"@id": "https://noocodec.dev/ontology/dag/outputs"
},
"node": {
"@id": "https://noocodec.dev/ontology/dag/node"
},
"dag": {
"@id": "https://noocodec.dev/ontology/dag/dag"
},
"body": {
"@id": "https://noocodec.dev/ontology/dag/body"
},
"source": {
"@id": "https://noocodec.dev/ontology/dag/source"
},
"sources": {
"@id": "https://noocodec.dev/ontology/dag/sources",
"@container": "@index"
},
"itemKey": {
"@id": "https://noocodec.dev/ontology/dag/itemKey"
},
"execution": {
"@id": "https://noocodec.dev/ontology/dag/execution"
},
"concurrency": {
"@id": "https://noocodec.dev/ontology/dag/concurrency"
},
"throttle": {
"@id": "https://noocodec.dev/ontology/dag/throttle"
},
"reservoir": {
"@id": "https://noocodec.dev/ontology/dag/reservoir"
},
"gather": {
"@id": "https://noocodec.dev/ontology/dag/gather"
},
"dagReference": {
"@id": "https://noocodec.dev/ontology/dag/dagReference",
"@type": "@id"
},
"DagReference": {
"@id": "https://noocodec.dev/ontology/dag/DagReference"
},
"from": {
"@id": "https://noocodec.dev/ontology/dag/from"
},
"path": {
"@id": "https://noocodec.dev/ontology/dag/path"
},
"candidates": {
"@id": "https://noocodec.dev/ontology/dag/candidates",
"@container": "@set"
},
"candidateDag": {
"@id": "https://noocodec.dev/ontology/dag/candidateDag",
"@type": "@id"
},
"selectedDag": {
"@id": "https://noocodec.dev/ontology/dag/selectedDag",
"@type": "@id"
},
"resultField": {
"@id": "https://noocodec.dev/ontology/dag/resultField"
},
"policy": {
"@id": "https://noocodec.dev/ontology/dag/policy"
},
"reducer": {
"@id": "https://noocodec.dev/ontology/dag/reducer"
},
"outcome": {
"@id": "https://noocodec.dev/ontology/dag/outcome"
},
"phase": {
"@id": "https://noocodec.dev/ontology/dag/phase"
},
"stateMapping": {
"@id": "https://noocodec.dev/ontology/dag/stateMapping"
},
"container": {
"@id": "https://noocodec.dev/ontology/dag/container"
},
"DAG": {
"@id": "https://noocodec.dev/ontology/dag/DAG"
},
"Placement": {
"@id": "https://noocodec.dev/ontology/dag/Placement"
},
"SingleNode": {
"@id": "https://noocodec.dev/ontology/dag/SingleNode"
},
"ScatterNode": {
"@id": "https://noocodec.dev/ontology/dag/ScatterNode"
},
"EmbeddedDAGNode": {
"@id": "https://noocodec.dev/ontology/dag/EmbeddedDAGNode"
},
"GatherNode": {
"@id": "https://noocodec.dev/ontology/dag/GatherNode"
},
"TerminalNode": {
"@id": "https://noocodec.dev/ontology/dag/TerminalNode"
},
"PhaseNode": {
"@id": "https://noocodec.dev/ontology/dag/PhaseNode"
}
},
"@id": "urn:noocodec:dag:the-archivist",
"@type": "DAG",
"name": "the-archivist",
"version": "6.0",
"entrypoints": {
"main": "urn:noocodec:dag:the-archivist/node/park-for-input"
},
"nodes": [
{
"@id": "urn:noocodec:dag:the-archivist/node/setup",
"@type": "PhaseNode",
"name": "setup",
"node": "urn:noocodec:node:pre-run-setup",
"phase": "pre"
},
{
"@id": "urn:noocodec:dag:the-archivist/node/park-for-input",
"@type": "SingleNode",
"name": "park-for-input",
"node": "urn:noocodec:node:park-for-input",
"outputs": {
"parked": "urn:noocodec:dag:the-archivist/node/park-for-input",
"resumed": "urn:noocodec:dag:the-archivist/node/recall-context"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recall-context",
"@type": "SingleNode",
"name": "recall-context",
"node": "urn:noocodec:node:recall-context",
"outputs": {
"recalled": "urn:noocodec:dag:the-archivist/node/classify-intent"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/classify-intent",
"@type": "SingleNode",
"name": "classify-intent",
"node": "urn:noocodec:node:classify-intent",
"outputs": {
"lookup-author": "urn:noocodec:dag:the-archivist/node/author-search",
"find-reviews": "urn:noocodec:dag:the-archivist/node/reviews-extract",
"describe-book": "urn:noocodec:dag:the-archivist/node/describe-extract",
"recommend-similar": "urn:noocodec:dag:the-archivist/node/recommend-similar",
"recall-memories": "urn:noocodec:dag:the-archivist/node/memory-recall",
"on-topic": "urn:noocodec:dag:the-archivist/node/on-topic-search",
"recommend-top-rated": "urn:noocodec:dag:the-archivist/node/recommend-extract",
"off-topic": "urn:noocodec:dag:the-archivist/node/decline-off-topic",
"retry": "urn:noocodec:dag:the-archivist/node/classify-intent",
"salvage": "urn:noocodec:dag:the-archivist/node/classify-intent-salvage"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/classify-intent-salvage",
"@type": "SingleNode",
"name": "classify-intent-salvage",
"node": "urn:noocodec:node:classify-intent-salvage",
"outputs": {
"done": "urn:noocodec:dag:the-archivist/node/on-topic-search"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/on-topic-search",
"@type": "EmbeddedDAGNode",
"name": "on-topic-search",
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/compose-loop",
"error": "urn:noocodec:dag:the-archivist/node/compose-empty"
},
"dag": "urn:noocodec:dag:book-search-scatter",
"stateMapping": {
"output": {
"terms": "terms",
"toolPlan": "toolPlan",
"candidates": "candidates",
"shortlist": "shortlist",
"priorContext": "priorContext",
"failureCause": "failureCause"
}
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/author-search",
"@type": "EmbeddedDAGNode",
"name": "author-search",
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/group-by-year",
"error": "urn:noocodec:dag:the-archivist/node/compose-empty"
},
"dag": "urn:noocodec:dag:book-search-scatter",
"stateMapping": {
"output": {
"terms": "terms",
"toolPlan": "toolPlan",
"candidates": "candidates",
"shortlist": "shortlist",
"priorContext": "priorContext",
"failureCause": "failureCause"
}
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/group-by-year",
"@type": "SingleNode",
"name": "group-by-year",
"node": "urn:noocodec:node:group-by-year",
"outputs": {
"ordered": "urn:noocodec:dag:the-archivist/node/compose-loop"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/reviews-extract",
"@type": "SingleNode",
"name": "reviews-extract",
"node": "urn:noocodec:node:extract-query",
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/reviews-decide-tools",
"retry": "urn:noocodec:dag:the-archivist/node/reviews-extract",
"salvage": "urn:noocodec:dag:the-archivist/node/reviews-extract-salvage"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/reviews-extract-salvage",
"@type": "SingleNode",
"name": "reviews-extract-salvage",
"node": "urn:noocodec:node:extract-query-salvage",
"outputs": {
"done": "urn:noocodec:dag:the-archivist/node/reviews-decide-tools"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/reviews-decide-tools",
"@type": "SingleNode",
"name": "reviews-decide-tools",
"node": "urn:noocodec:node:decide-tools",
"outputs": {
"tools": "urn:noocodec:dag:the-archivist/node/reviews-build-worksets",
"no-tools": "urn:noocodec:dag:the-archivist/node/reviews-build-worksets",
"retry": "urn:noocodec:dag:the-archivist/node/reviews-decide-tools",
"salvage": "urn:noocodec:dag:the-archivist/node/reviews-decide-tools-salvage"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/reviews-decide-tools-salvage",
"@type": "SingleNode",
"name": "reviews-decide-tools-salvage",
"node": "urn:noocodec:node:decide-tools-salvage",
"outputs": {
"done": "urn:noocodec:dag:the-archivist/node/reviews-build-worksets"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/reviews-build-worksets",
"@type": "SingleNode",
"name": "reviews-build-worksets",
"node": "urn:noocodec:node:build-book-worksets",
"outputs": {
"ready": "urn:noocodec:dag:the-archivist/node/reviews-scatter"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/reviews-scatter",
"@type": "ScatterNode",
"name": "reviews-scatter",
"source": "bookWorksets",
"body": {
"dag": {
"@type": "DagReference",
"from": "item",
"path": "dagIri",
"candidates": [
"urn:noocodec:tool:web_search_books",
"urn:noocodec:tool:google_books_search",
"urn:noocodec:tool:subject_search",
"urn:noocodec:tool:wikipedia_summary"
]
}
},
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/reviews-gather",
"error": "urn:noocodec:dag:the-archivist/node/reviews-gather",
"empty": "urn:noocodec:dag:the-archivist/node/reviews-rank"
},
"itemKey": "currentItem",
"reducer": "any-success",
"execution": {
"mode": "item",
"concurrency": 4
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/reviews-gather",
"@type": "GatherNode",
"name": "reviews-gather",
"sources": {
"urn:noocodec:dag:the-archivist/node/reviews-scatter": {}
},
"gather": {
"strategy": "tool-candidate-merge"
},
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/reviews-rank",
"error": "urn:noocodec:dag:the-archivist/node/reviews-rank",
"empty": "urn:noocodec:dag:the-archivist/node/reviews-rank"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/reviews-rank",
"@type": "SingleNode",
"name": "reviews-rank",
"node": "urn:noocodec:node:rank-by-rating",
"outputs": {
"ranked": "urn:noocodec:dag:the-archivist/node/reviews-merge"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/reviews-merge",
"@type": "SingleNode",
"name": "reviews-merge",
"node": "urn:noocodec:node:merge-candidates",
"outputs": {
"ranked": "urn:noocodec:dag:the-archivist/node/reviews-record",
"empty": "urn:noocodec:dag:the-archivist/node/compose-empty"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/reviews-record",
"@type": "SingleNode",
"name": "reviews-record",
"node": "urn:noocodec:node:record-findings",
"outputs": {
"recorded": "urn:noocodec:dag:the-archivist/node/reviews-gate"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/reviews-gate",
"@type": "SingleNode",
"name": "reviews-gate",
"node": "urn:noocodec:node:has-citations-gate",
"outputs": {
"pass": "urn:noocodec:dag:the-archivist/node/reviews-recall",
"fail": "urn:noocodec:dag:the-archivist/node/compose-empty"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/reviews-recall",
"@type": "SingleNode",
"name": "reviews-recall",
"node": "urn:noocodec:node:recall-past-visits",
"outputs": {
"recalled": "urn:noocodec:dag:the-archivist/node/compose-loop"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-extract",
"@type": "SingleNode",
"name": "recommend-extract",
"node": "urn:noocodec:node:extract-query",
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/recommend-decide-tools",
"retry": "urn:noocodec:dag:the-archivist/node/recommend-extract",
"salvage": "urn:noocodec:dag:the-archivist/node/recommend-extract-salvage"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-extract-salvage",
"@type": "SingleNode",
"name": "recommend-extract-salvage",
"node": "urn:noocodec:node:extract-query-salvage",
"outputs": {
"done": "urn:noocodec:dag:the-archivist/node/recommend-decide-tools"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-decide-tools",
"@type": "SingleNode",
"name": "recommend-decide-tools",
"node": "urn:noocodec:node:decide-tools",
"outputs": {
"tools": "urn:noocodec:dag:the-archivist/node/recommend-build-worksets",
"no-tools": "urn:noocodec:dag:the-archivist/node/recommend-build-worksets",
"retry": "urn:noocodec:dag:the-archivist/node/recommend-decide-tools",
"salvage": "urn:noocodec:dag:the-archivist/node/recommend-decide-tools-salvage"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-decide-tools-salvage",
"@type": "SingleNode",
"name": "recommend-decide-tools-salvage",
"node": "urn:noocodec:node:decide-tools-salvage",
"outputs": {
"done": "urn:noocodec:dag:the-archivist/node/recommend-build-worksets"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-build-worksets",
"@type": "SingleNode",
"name": "recommend-build-worksets",
"node": "urn:noocodec:node:build-book-worksets",
"outputs": {
"ready": "urn:noocodec:dag:the-archivist/node/recommend-scatter"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-scatter",
"@type": "ScatterNode",
"name": "recommend-scatter",
"source": "bookWorksets",
"body": {
"dag": {
"@type": "DagReference",
"from": "item",
"path": "dagIri",
"candidates": [
"urn:noocodec:tool:web_search_books",
"urn:noocodec:tool:google_books_search",
"urn:noocodec:tool:subject_search",
"urn:noocodec:tool:wikipedia_summary"
]
}
},
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/recommend-gather",
"error": "urn:noocodec:dag:the-archivist/node/recommend-gather",
"empty": "urn:noocodec:dag:the-archivist/node/recommend-rank"
},
"itemKey": "currentItem",
"reducer": "any-success",
"execution": {
"mode": "item",
"concurrency": 4
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-gather",
"@type": "GatherNode",
"name": "recommend-gather",
"sources": {
"urn:noocodec:dag:the-archivist/node/recommend-scatter": {}
},
"gather": {
"strategy": "tool-candidate-merge"
},
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/recommend-rank",
"error": "urn:noocodec:dag:the-archivist/node/recommend-rank",
"empty": "urn:noocodec:dag:the-archivist/node/recommend-rank"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-rank",
"@type": "SingleNode",
"name": "recommend-rank",
"node": "urn:noocodec:node:rank-by-rating",
"outputs": {
"ranked": "urn:noocodec:dag:the-archivist/node/recommend-merge"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-merge",
"@type": "SingleNode",
"name": "recommend-merge",
"node": "urn:noocodec:node:merge-candidates",
"outputs": {
"ranked": "urn:noocodec:dag:the-archivist/node/recommend-record",
"empty": "urn:noocodec:dag:the-archivist/node/compose-empty"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-record",
"@type": "SingleNode",
"name": "recommend-record",
"node": "urn:noocodec:node:record-findings",
"outputs": {
"recorded": "urn:noocodec:dag:the-archivist/node/recommend-gate"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-gate",
"@type": "SingleNode",
"name": "recommend-gate",
"node": "urn:noocodec:node:has-citations-gate",
"outputs": {
"pass": "urn:noocodec:dag:the-archivist/node/recommend-recall",
"fail": "urn:noocodec:dag:the-archivist/node/compose-empty"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-recall",
"@type": "SingleNode",
"name": "recommend-recall",
"node": "urn:noocodec:node:recall-past-visits",
"outputs": {
"recalled": "urn:noocodec:dag:the-archivist/node/compose-loop"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/describe-extract",
"@type": "SingleNode",
"name": "describe-extract",
"node": "urn:noocodec:node:extract-query",
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/describe-decide-tools",
"retry": "urn:noocodec:dag:the-archivist/node/describe-extract",
"salvage": "urn:noocodec:dag:the-archivist/node/describe-extract-salvage"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/describe-extract-salvage",
"@type": "SingleNode",
"name": "describe-extract-salvage",
"node": "urn:noocodec:node:extract-query-salvage",
"outputs": {
"done": "urn:noocodec:dag:the-archivist/node/describe-decide-tools"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/describe-decide-tools",
"@type": "SingleNode",
"name": "describe-decide-tools",
"node": "urn:noocodec:node:decide-tools",
"outputs": {
"tools": "urn:noocodec:dag:the-archivist/node/describe-build-worksets",
"no-tools": "urn:noocodec:dag:the-archivist/node/describe-build-worksets",
"retry": "urn:noocodec:dag:the-archivist/node/describe-decide-tools",
"salvage": "urn:noocodec:dag:the-archivist/node/describe-decide-tools-salvage"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/describe-decide-tools-salvage",
"@type": "SingleNode",
"name": "describe-decide-tools-salvage",
"node": "urn:noocodec:node:decide-tools-salvage",
"outputs": {
"done": "urn:noocodec:dag:the-archivist/node/describe-build-worksets"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/describe-build-worksets",
"@type": "SingleNode",
"name": "describe-build-worksets",
"node": "urn:noocodec:node:build-book-worksets",
"outputs": {
"ready": "urn:noocodec:dag:the-archivist/node/describe-scatter"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/describe-scatter",
"@type": "ScatterNode",
"name": "describe-scatter",
"source": "bookWorksets",
"body": {
"dag": {
"@type": "DagReference",
"from": "item",
"path": "dagIri",
"candidates": [
"urn:noocodec:tool:web_search_books",
"urn:noocodec:tool:google_books_search",
"urn:noocodec:tool:subject_search",
"urn:noocodec:tool:wikipedia_summary"
]
}
},
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/describe-gather",
"error": "urn:noocodec:dag:the-archivist/node/compose-empty",
"empty": "urn:noocodec:dag:the-archivist/node/compose-empty"
},
"itemKey": "currentItem",
"reducer": "any-success",
"execution": {
"mode": "item",
"concurrency": 4
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/describe-gather",
"@type": "GatherNode",
"name": "describe-gather",
"sources": {
"urn:noocodec:dag:the-archivist/node/describe-scatter": {}
},
"gather": {
"strategy": "tool-candidate-merge"
},
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/describe-pick",
"error": "urn:noocodec:dag:the-archivist/node/compose-empty",
"empty": "urn:noocodec:dag:the-archivist/node/compose-empty"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/describe-pick",
"@type": "SingleNode",
"name": "describe-pick",
"node": "urn:noocodec:node:pick-best-match",
"outputs": {
"picked": "urn:noocodec:dag:the-archivist/node/describe-merge"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/describe-merge",
"@type": "SingleNode",
"name": "describe-merge",
"node": "urn:noocodec:node:merge-candidates",
"outputs": {
"ranked": "urn:noocodec:dag:the-archivist/node/describe-record",
"empty": "urn:noocodec:dag:the-archivist/node/compose-empty"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/describe-record",
"@type": "SingleNode",
"name": "describe-record",
"node": "urn:noocodec:node:record-findings",
"outputs": {
"recorded": "urn:noocodec:dag:the-archivist/node/describe-gate"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/describe-gate",
"@type": "SingleNode",
"name": "describe-gate",
"node": "urn:noocodec:node:has-citations-gate",
"outputs": {
"pass": "urn:noocodec:dag:the-archivist/node/describe-recall",
"fail": "urn:noocodec:dag:the-archivist/node/compose-empty"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/describe-recall",
"@type": "SingleNode",
"name": "describe-recall",
"node": "urn:noocodec:node:recall-past-visits",
"outputs": {
"recalled": "urn:noocodec:dag:the-archivist/node/compose-loop"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/recommend-similar",
"@type": "SingleNode",
"name": "recommend-similar",
"node": "urn:noocodec:node:recommend-similar",
"outputs": {
"seeded": "urn:noocodec:dag:the-archivist/node/similar-search",
"empty": "urn:noocodec:dag:the-archivist/node/compose-empty"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/similar-search",
"@type": "EmbeddedDAGNode",
"name": "similar-search",
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/compose-loop",
"error": "urn:noocodec:dag:the-archivist/node/compose-empty"
},
"dag": "urn:noocodec:dag:book-search-scatter",
"stateMapping": {
"output": {
"terms": "terms",
"toolPlan": "toolPlan",
"candidates": "candidates",
"shortlist": "shortlist",
"priorContext": "priorContext",
"failureCause": "failureCause"
}
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/compose-loop",
"@type": "EmbeddedDAGNode",
"name": "compose-loop",
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/respond-to-visitor",
"error": "urn:noocodec:dag:the-archivist/node/compose-empty"
},
"dag": "urn:noocodec:dag:compose-retry-loop",
"stateMapping": {
"output": {
"draft": "draft",
"approvalState": "approvalState"
}
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/respond-to-visitor",
"@type": "SingleNode",
"name": "respond-to-visitor",
"node": "urn:noocodec:node:respond-to-visitor",
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/end"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/memory-recall",
"@type": "SingleNode",
"name": "memory-recall",
"node": "urn:noocodec:node:recall-memories",
"outputs": {
"recalled": "urn:noocodec:dag:the-archivist/node/compose-memory-recall"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/compose-memory-recall",
"@type": "SingleNode",
"name": "compose-memory-recall",
"node": "urn:noocodec:node:compose-memory-response",
"outputs": {
"drafted": "urn:noocodec:dag:the-archivist/node/respond-to-visitor",
"retry": "urn:noocodec:dag:the-archivist/node/compose-memory-recall",
"salvage": "urn:noocodec:dag:the-archivist/node/compose-memory-salvage"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/compose-memory-salvage",
"@type": "SingleNode",
"name": "compose-memory-salvage",
"node": "urn:noocodec:node:compose-memory-salvage",
"outputs": {
"done": "urn:noocodec:dag:the-archivist/node/respond-to-visitor"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/decline-off-topic",
"@type": "SingleNode",
"name": "decline-off-topic",
"node": "urn:noocodec:node:decline-off-topic",
"outputs": {
"success": "urn:noocodec:dag:the-archivist/node/end"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/compose-empty",
"@type": "SingleNode",
"name": "compose-empty",
"node": "urn:noocodec:node:compose-empty",
"outputs": {
"drafted": "urn:noocodec:dag:the-archivist/node/respond-to-visitor",
"retry": "urn:noocodec:dag:the-archivist/node/compose-empty",
"salvage": "urn:noocodec:dag:the-archivist/node/compose-empty-salvage"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/compose-empty-salvage",
"@type": "SingleNode",
"name": "compose-empty-salvage",
"node": "urn:noocodec:node:compose-empty-salvage",
"outputs": {
"done": "urn:noocodec:dag:the-archivist/node/respond-to-visitor"
}
},
{
"@id": "urn:noocodec:dag:the-archivist/node/end",
"@type": "TerminalNode",
"name": "end",
"outcome": "completed"
}
]
}Mermaid source
%%{init: {"flowchart":{"nodeSpacing":92,"rankSpacing":104,"padding":28}}}%%
flowchart TB
%% the-archivist (v6.0)
entry_main(["main"])
entry_main --> urn_noocodec_dag_the-archivist/node/park-for-input
urn_noocodec_dag_the-archivist/node/setup(["setup (pre)"])
urn_noocodec_dag_the-archivist/node/park-for-input["park-for-input"]
urn_noocodec_dag_the-archivist/node/park-for-input -->|parked| urn_noocodec_dag_the-archivist/node/park-for-input
urn_noocodec_dag_the-archivist/node/park-for-input -->|resumed| urn_noocodec_dag_the-archivist/node/recall-context
urn_noocodec_dag_the-archivist/node/recall-context["recall-context"]
urn_noocodec_dag_the-archivist/node/recall-context -->|recalled| urn_noocodec_dag_the-archivist/node/classify-intent
urn_noocodec_dag_the-archivist/node/classify-intent["classify-intent"]
urn_noocodec_dag_the-archivist/node/classify-intent -->|lookup-author| urn_noocodec_dag_the-archivist/node/author-search
urn_noocodec_dag_the-archivist/node/classify-intent -->|find-reviews| urn_noocodec_dag_the-archivist/node/reviews-extract
urn_noocodec_dag_the-archivist/node/classify-intent -->|describe-book| urn_noocodec_dag_the-archivist/node/describe-extract
urn_noocodec_dag_the-archivist/node/classify-intent -->|recommend-similar| urn_noocodec_dag_the-archivist/node/recommend-similar
urn_noocodec_dag_the-archivist/node/classify-intent -->|recall-memories| urn_noocodec_dag_the-archivist/node/memory-recall
urn_noocodec_dag_the-archivist/node/classify-intent -->|on-topic| urn_noocodec_dag_the-archivist/node/on-topic-search
urn_noocodec_dag_the-archivist/node/classify-intent -->|recommend-top-rated| urn_noocodec_dag_the-archivist/node/recommend-extract
urn_noocodec_dag_the-archivist/node/classify-intent -->|off-topic| urn_noocodec_dag_the-archivist/node/decline-off-topic
urn_noocodec_dag_the-archivist/node/classify-intent -->|retry| urn_noocodec_dag_the-archivist/node/classify-intent
urn_noocodec_dag_the-archivist/node/classify-intent -->|salvage| urn_noocodec_dag_the-archivist/node/classify-intent-salvage
urn_noocodec_dag_the-archivist/node/classify-intent-salvage["classify-intent-salvage"]
urn_noocodec_dag_the-archivist/node/classify-intent-salvage -->|done| urn_noocodec_dag_the-archivist/node/on-topic-search
urn_noocodec_dag_the-archivist/node/on-topic-search[["on-topic-search"]]
urn_noocodec_dag_the-archivist/node/on-topic-search -->|success| urn_noocodec_dag_the-archivist/node/compose-loop
urn_noocodec_dag_the-archivist/node/on-topic-search -->|error| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/author-search[["author-search"]]
urn_noocodec_dag_the-archivist/node/author-search -->|success| urn_noocodec_dag_the-archivist/node/group-by-year
urn_noocodec_dag_the-archivist/node/author-search -->|error| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/group-by-year["group-by-year"]
urn_noocodec_dag_the-archivist/node/group-by-year -->|ordered| urn_noocodec_dag_the-archivist/node/compose-loop
urn_noocodec_dag_the-archivist/node/reviews-extract["reviews-extract"]
urn_noocodec_dag_the-archivist/node/reviews-extract -->|success| urn_noocodec_dag_the-archivist/node/reviews-decide-tools
urn_noocodec_dag_the-archivist/node/reviews-extract -->|retry| urn_noocodec_dag_the-archivist/node/reviews-extract
urn_noocodec_dag_the-archivist/node/reviews-extract -->|salvage| urn_noocodec_dag_the-archivist/node/reviews-extract-salvage
urn_noocodec_dag_the-archivist/node/reviews-extract-salvage["reviews-extract-salvage"]
urn_noocodec_dag_the-archivist/node/reviews-extract-salvage -->|done| urn_noocodec_dag_the-archivist/node/reviews-decide-tools
urn_noocodec_dag_the-archivist/node/reviews-decide-tools["reviews-decide-tools"]
urn_noocodec_dag_the-archivist/node/reviews-decide-tools -->|tools| urn_noocodec_dag_the-archivist/node/reviews-build-worksets
urn_noocodec_dag_the-archivist/node/reviews-decide-tools -->|no-tools| urn_noocodec_dag_the-archivist/node/reviews-build-worksets
urn_noocodec_dag_the-archivist/node/reviews-decide-tools -->|retry| urn_noocodec_dag_the-archivist/node/reviews-decide-tools
urn_noocodec_dag_the-archivist/node/reviews-decide-tools -->|salvage| urn_noocodec_dag_the-archivist/node/reviews-decide-tools-salvage
urn_noocodec_dag_the-archivist/node/reviews-decide-tools-salvage["reviews-decide-tools-salvage"]
urn_noocodec_dag_the-archivist/node/reviews-decide-tools-salvage -->|done| urn_noocodec_dag_the-archivist/node/reviews-build-worksets
urn_noocodec_dag_the-archivist/node/reviews-build-worksets["reviews-build-worksets"]
urn_noocodec_dag_the-archivist/node/reviews-build-worksets -->|ready| urn_noocodec_dag_the-archivist/node/reviews-scatter
urn_noocodec_dag_the-archivist/node/reviews-scatter[/"reviews-scatter"/]
urn_noocodec_dag_the-archivist/node/reviews-scatter -->|success| urn_noocodec_dag_the-archivist/node/reviews-gather
urn_noocodec_dag_the-archivist/node/reviews-scatter -->|error| urn_noocodec_dag_the-archivist/node/reviews-gather
urn_noocodec_dag_the-archivist/node/reviews-scatter -->|empty| urn_noocodec_dag_the-archivist/node/reviews-rank
urn_noocodec_dag_the-archivist/node/reviews-gather{"reviews-gather"}
urn_noocodec_dag_the-archivist/node/reviews-gather -->|success| urn_noocodec_dag_the-archivist/node/reviews-rank
urn_noocodec_dag_the-archivist/node/reviews-gather -->|error| urn_noocodec_dag_the-archivist/node/reviews-rank
urn_noocodec_dag_the-archivist/node/reviews-gather -->|empty| urn_noocodec_dag_the-archivist/node/reviews-rank
urn_noocodec_dag_the-archivist/node/reviews-rank["reviews-rank"]
urn_noocodec_dag_the-archivist/node/reviews-rank -->|ranked| urn_noocodec_dag_the-archivist/node/reviews-merge
urn_noocodec_dag_the-archivist/node/reviews-merge["reviews-merge"]
urn_noocodec_dag_the-archivist/node/reviews-merge -->|ranked| urn_noocodec_dag_the-archivist/node/reviews-record
urn_noocodec_dag_the-archivist/node/reviews-merge -->|empty| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/reviews-record["reviews-record"]
urn_noocodec_dag_the-archivist/node/reviews-record -->|recorded| urn_noocodec_dag_the-archivist/node/reviews-gate
urn_noocodec_dag_the-archivist/node/reviews-gate["reviews-gate"]
urn_noocodec_dag_the-archivist/node/reviews-gate -->|pass| urn_noocodec_dag_the-archivist/node/reviews-recall
urn_noocodec_dag_the-archivist/node/reviews-gate -->|fail| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/reviews-recall["reviews-recall"]
urn_noocodec_dag_the-archivist/node/reviews-recall -->|recalled| urn_noocodec_dag_the-archivist/node/compose-loop
urn_noocodec_dag_the-archivist/node/recommend-extract["recommend-extract"]
urn_noocodec_dag_the-archivist/node/recommend-extract -->|success| urn_noocodec_dag_the-archivist/node/recommend-decide-tools
urn_noocodec_dag_the-archivist/node/recommend-extract -->|retry| urn_noocodec_dag_the-archivist/node/recommend-extract
urn_noocodec_dag_the-archivist/node/recommend-extract -->|salvage| urn_noocodec_dag_the-archivist/node/recommend-extract-salvage
urn_noocodec_dag_the-archivist/node/recommend-extract-salvage["recommend-extract-salvage"]
urn_noocodec_dag_the-archivist/node/recommend-extract-salvage -->|done| urn_noocodec_dag_the-archivist/node/recommend-decide-tools
urn_noocodec_dag_the-archivist/node/recommend-decide-tools["recommend-decide-tools"]
urn_noocodec_dag_the-archivist/node/recommend-decide-tools -->|tools| urn_noocodec_dag_the-archivist/node/recommend-build-worksets
urn_noocodec_dag_the-archivist/node/recommend-decide-tools -->|no-tools| urn_noocodec_dag_the-archivist/node/recommend-build-worksets
urn_noocodec_dag_the-archivist/node/recommend-decide-tools -->|retry| urn_noocodec_dag_the-archivist/node/recommend-decide-tools
urn_noocodec_dag_the-archivist/node/recommend-decide-tools -->|salvage| urn_noocodec_dag_the-archivist/node/recommend-decide-tools-salvage
urn_noocodec_dag_the-archivist/node/recommend-decide-tools-salvage["recommend-decide-tools-salvage"]
urn_noocodec_dag_the-archivist/node/recommend-decide-tools-salvage -->|done| urn_noocodec_dag_the-archivist/node/recommend-build-worksets
urn_noocodec_dag_the-archivist/node/recommend-build-worksets["recommend-build-worksets"]
urn_noocodec_dag_the-archivist/node/recommend-build-worksets -->|ready| urn_noocodec_dag_the-archivist/node/recommend-scatter
urn_noocodec_dag_the-archivist/node/recommend-scatter[/"recommend-scatter"/]
urn_noocodec_dag_the-archivist/node/recommend-scatter -->|success| urn_noocodec_dag_the-archivist/node/recommend-gather
urn_noocodec_dag_the-archivist/node/recommend-scatter -->|error| urn_noocodec_dag_the-archivist/node/recommend-gather
urn_noocodec_dag_the-archivist/node/recommend-scatter -->|empty| urn_noocodec_dag_the-archivist/node/recommend-rank
urn_noocodec_dag_the-archivist/node/recommend-gather{"recommend-gather"}
urn_noocodec_dag_the-archivist/node/recommend-gather -->|success| urn_noocodec_dag_the-archivist/node/recommend-rank
urn_noocodec_dag_the-archivist/node/recommend-gather -->|error| urn_noocodec_dag_the-archivist/node/recommend-rank
urn_noocodec_dag_the-archivist/node/recommend-gather -->|empty| urn_noocodec_dag_the-archivist/node/recommend-rank
urn_noocodec_dag_the-archivist/node/recommend-rank["recommend-rank"]
urn_noocodec_dag_the-archivist/node/recommend-rank -->|ranked| urn_noocodec_dag_the-archivist/node/recommend-merge
urn_noocodec_dag_the-archivist/node/recommend-merge["recommend-merge"]
urn_noocodec_dag_the-archivist/node/recommend-merge -->|ranked| urn_noocodec_dag_the-archivist/node/recommend-record
urn_noocodec_dag_the-archivist/node/recommend-merge -->|empty| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/recommend-record["recommend-record"]
urn_noocodec_dag_the-archivist/node/recommend-record -->|recorded| urn_noocodec_dag_the-archivist/node/recommend-gate
urn_noocodec_dag_the-archivist/node/recommend-gate["recommend-gate"]
urn_noocodec_dag_the-archivist/node/recommend-gate -->|pass| urn_noocodec_dag_the-archivist/node/recommend-recall
urn_noocodec_dag_the-archivist/node/recommend-gate -->|fail| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/recommend-recall["recommend-recall"]
urn_noocodec_dag_the-archivist/node/recommend-recall -->|recalled| urn_noocodec_dag_the-archivist/node/compose-loop
urn_noocodec_dag_the-archivist/node/describe-extract["describe-extract"]
urn_noocodec_dag_the-archivist/node/describe-extract -->|success| urn_noocodec_dag_the-archivist/node/describe-decide-tools
urn_noocodec_dag_the-archivist/node/describe-extract -->|retry| urn_noocodec_dag_the-archivist/node/describe-extract
urn_noocodec_dag_the-archivist/node/describe-extract -->|salvage| urn_noocodec_dag_the-archivist/node/describe-extract-salvage
urn_noocodec_dag_the-archivist/node/describe-extract-salvage["describe-extract-salvage"]
urn_noocodec_dag_the-archivist/node/describe-extract-salvage -->|done| urn_noocodec_dag_the-archivist/node/describe-decide-tools
urn_noocodec_dag_the-archivist/node/describe-decide-tools["describe-decide-tools"]
urn_noocodec_dag_the-archivist/node/describe-decide-tools -->|tools| urn_noocodec_dag_the-archivist/node/describe-build-worksets
urn_noocodec_dag_the-archivist/node/describe-decide-tools -->|no-tools| urn_noocodec_dag_the-archivist/node/describe-build-worksets
urn_noocodec_dag_the-archivist/node/describe-decide-tools -->|retry| urn_noocodec_dag_the-archivist/node/describe-decide-tools
urn_noocodec_dag_the-archivist/node/describe-decide-tools -->|salvage| urn_noocodec_dag_the-archivist/node/describe-decide-tools-salvage
urn_noocodec_dag_the-archivist/node/describe-decide-tools-salvage["describe-decide-tools-salvage"]
urn_noocodec_dag_the-archivist/node/describe-decide-tools-salvage -->|done| urn_noocodec_dag_the-archivist/node/describe-build-worksets
urn_noocodec_dag_the-archivist/node/describe-build-worksets["describe-build-worksets"]
urn_noocodec_dag_the-archivist/node/describe-build-worksets -->|ready| urn_noocodec_dag_the-archivist/node/describe-scatter
urn_noocodec_dag_the-archivist/node/describe-scatter[/"describe-scatter"/]
urn_noocodec_dag_the-archivist/node/describe-scatter -->|success| urn_noocodec_dag_the-archivist/node/describe-gather
urn_noocodec_dag_the-archivist/node/describe-scatter -->|error| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/describe-scatter -->|empty| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/describe-gather{"describe-gather"}
urn_noocodec_dag_the-archivist/node/describe-gather -->|success| urn_noocodec_dag_the-archivist/node/describe-pick
urn_noocodec_dag_the-archivist/node/describe-gather -->|error| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/describe-gather -->|empty| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/describe-pick["describe-pick"]
urn_noocodec_dag_the-archivist/node/describe-pick -->|picked| urn_noocodec_dag_the-archivist/node/describe-merge
urn_noocodec_dag_the-archivist/node/describe-merge["describe-merge"]
urn_noocodec_dag_the-archivist/node/describe-merge -->|ranked| urn_noocodec_dag_the-archivist/node/describe-record
urn_noocodec_dag_the-archivist/node/describe-merge -->|empty| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/describe-record["describe-record"]
urn_noocodec_dag_the-archivist/node/describe-record -->|recorded| urn_noocodec_dag_the-archivist/node/describe-gate
urn_noocodec_dag_the-archivist/node/describe-gate["describe-gate"]
urn_noocodec_dag_the-archivist/node/describe-gate -->|pass| urn_noocodec_dag_the-archivist/node/describe-recall
urn_noocodec_dag_the-archivist/node/describe-gate -->|fail| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/describe-recall["describe-recall"]
urn_noocodec_dag_the-archivist/node/describe-recall -->|recalled| urn_noocodec_dag_the-archivist/node/compose-loop
urn_noocodec_dag_the-archivist/node/recommend-similar["recommend-similar"]
urn_noocodec_dag_the-archivist/node/recommend-similar -->|seeded| urn_noocodec_dag_the-archivist/node/similar-search
urn_noocodec_dag_the-archivist/node/recommend-similar -->|empty| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/similar-search[["similar-search"]]
urn_noocodec_dag_the-archivist/node/similar-search -->|success| urn_noocodec_dag_the-archivist/node/compose-loop
urn_noocodec_dag_the-archivist/node/similar-search -->|error| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/compose-loop[["compose-loop"]]
urn_noocodec_dag_the-archivist/node/compose-loop -->|success| urn_noocodec_dag_the-archivist/node/respond-to-visitor
urn_noocodec_dag_the-archivist/node/compose-loop -->|error| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/respond-to-visitor["respond-to-visitor"]
urn_noocodec_dag_the-archivist/node/respond-to-visitor -->|success| urn_noocodec_dag_the-archivist/node/end
urn_noocodec_dag_the-archivist/node/memory-recall["memory-recall"]
urn_noocodec_dag_the-archivist/node/memory-recall -->|recalled| urn_noocodec_dag_the-archivist/node/compose-memory-recall
urn_noocodec_dag_the-archivist/node/compose-memory-recall["compose-memory-recall"]
urn_noocodec_dag_the-archivist/node/compose-memory-recall -->|drafted| urn_noocodec_dag_the-archivist/node/respond-to-visitor
urn_noocodec_dag_the-archivist/node/compose-memory-recall -->|retry| urn_noocodec_dag_the-archivist/node/compose-memory-recall
urn_noocodec_dag_the-archivist/node/compose-memory-recall -->|salvage| urn_noocodec_dag_the-archivist/node/compose-memory-salvage
urn_noocodec_dag_the-archivist/node/compose-memory-salvage["compose-memory-salvage"]
urn_noocodec_dag_the-archivist/node/compose-memory-salvage -->|done| urn_noocodec_dag_the-archivist/node/respond-to-visitor
urn_noocodec_dag_the-archivist/node/decline-off-topic["decline-off-topic"]
urn_noocodec_dag_the-archivist/node/decline-off-topic -->|success| urn_noocodec_dag_the-archivist/node/end
urn_noocodec_dag_the-archivist/node/compose-empty["compose-empty"]
urn_noocodec_dag_the-archivist/node/compose-empty -->|drafted| urn_noocodec_dag_the-archivist/node/respond-to-visitor
urn_noocodec_dag_the-archivist/node/compose-empty -->|retry| urn_noocodec_dag_the-archivist/node/compose-empty
urn_noocodec_dag_the-archivist/node/compose-empty -->|salvage| urn_noocodec_dag_the-archivist/node/compose-empty-salvage
urn_noocodec_dag_the-archivist/node/compose-empty-salvage["compose-empty-salvage"]
urn_noocodec_dag_the-archivist/node/compose-empty-salvage -->|done| urn_noocodec_dag_the-archivist/node/respond-to-visitor
urn_noocodec_dag_the-archivist/node/end((("end")))The embedding surface provides a provider-agnostic interface for text embedding. The browser Archivist provisions an offline-capable embedder cascade, builds an intent classifier, and injects the selected embedder into ArchivistServices.
Run
npm run docs:devOpen The Archivist; the browser runner provisions the embedder during session boot when supported.
What It Lets You Do
Embedders let applications add semantic comparison to DAG nodes without tying the graph to one vector provider. Use them for intent classification, memory recall, deduplication, ranking, and similarity checks that should work across browser, local, or cloud embedding backends.
The application benefit is portability: change vector providers, dimensions, or selection order in service setup while keeping DAG topology and node routes stable.
Code Samples
The provisioner snippet builds the embedder cascade. The browser services snippet shows how the selected embedder becomes part of the Archivist service record passed to node constructors.
/**
* EmbedderProvisioner: memoized browser embedder selection and IntentClassifier
* construction.
*
* Walks a preference-ordered candidate list (transformers → tensorflow →
* web-llm), selects the first embedder that probes true via EmbedderCascade,
* connects it, and builds an IntentClassifier against it. The result is
* memoized: every caller across backend swaps reuses the same instance.
*
* On any failure (no candidate probes true, CDN import fails, connect or
* anchor-embed throws) the provisioner returns `{ embedder: null,
* intentClassifier: null }` so callers keep working with LLM-only
* classification.
*/
import type { EmbedderInterface } from '@studnicky/dagonizer/contracts';
import { EmbedderCascade, EmbedderRegistry } from '@studnicky/dagonizer/adapter';
import type { AdapterCapabilitiesType, AdapterDescriptorShapeType } from '@studnicky/dagonizer/adapter';
import { TransformersEmbedder } from '@studnicky/dagonizer-embedder-transformers';
import { UniversalSentenceEncoderEmbedder } from '@studnicky/dagonizer-embedder-tensorflow';
import { WebLlmEmbedder } from '@studnicky/dagonizer-embedder-web-llm';
import { IntentClassifier } from './IntentClassifier.ts';
export type EmbedderProvisionResultType = {
readonly embedder: EmbedderInterface | null;
readonly intentClassifier: IntentClassifier | null;
};
// Embedder adapters are not LLM adapters; these capability fields satisfy the
// shared AdapterDescriptorShapeType but carry no semantic meaning for embedders.
const EMBEDDER_CAPABILITIES: AdapterCapabilitiesType = {
'toolUse': 'none',
'structuredOutput': false,
'jsonMode': false,
};
type CandidateEntry = {
readonly descriptor: AdapterDescriptorShapeType;
readonly factory: () => EmbedderInterface;
};
/**
* Provisioning options. A Vite consumer supplies the transformers embedder's
* served asset paths (from the `virtual:transformers-embedder-assets` module the
* package's Vite plugin exposes) so the model + WASM load from the app's own
* bundle — fully offline, no CDN. Absent (node, or no plugin) the embedder
* uses its package-local vendored `models/`.
*/
export type EmbedderProvisionOptionsType = {
readonly transformersLocalModelPath?: string;
readonly transformersWasmPaths?: string;
};
// Memoized in-flight promise; populated on the first call to provision().
let provisionPromise: Promise<EmbedderProvisionResultType> | null = null;
/**
* EmbedderProvisioner: memoized browser embedder + IntentClassifier factory.
*/
export class EmbedderProvisioner {
/**
* Provision a browser embedder and build an IntentClassifier against it.
*
* Memoized: subsequent calls return the same Promise without re-running
* the cascade. Returns `{ embedder: null, intentClassifier: null }` when
* no candidate is available or any step throws.
*/
static provision(options: EmbedderProvisionOptionsType = {}): Promise<EmbedderProvisionResultType> {
if (provisionPromise !== null) return provisionPromise;
provisionPromise = EmbedderProvisioner.#run(options);
return provisionPromise;
}
/**
* Preference order: WASM-floor transformers first (always available), then
* tensorflow USE, then WebGPU-gated web-llm. The transformers candidate is
* parameterised by the browser asset paths supplied to `provision()`.
*/
static #candidates(options: EmbedderProvisionOptionsType): readonly CandidateEntry[] {
const transformersOptions = {
...(options.transformersLocalModelPath !== undefined ? { 'localModelPath': options.transformersLocalModelPath } : {}),
...(options.transformersWasmPaths !== undefined ? { 'wasmPaths': options.transformersWasmPaths } : {}),
};
return [
{
'descriptor': { 'provider': 'transformers', 'model': 'Xenova/all-MiniLM-L6-v2', 'capabilities': EMBEDDER_CAPABILITIES },
'factory': () => new TransformersEmbedder(transformersOptions),
},
{
'descriptor': { 'provider': 'tensorflow', 'model': 'universal-sentence-encoder', 'capabilities': EMBEDDER_CAPABILITIES },
'factory': () => new UniversalSentenceEncoderEmbedder(),
},
{
'descriptor': { 'provider': 'web-llm', 'model': 'snowflake-arctic-embed-s-q0f32-MLC-b4', 'capabilities': EMBEDDER_CAPABILITIES },
'factory': () => new WebLlmEmbedder(),
},
];
}
static async #run(options: EmbedderProvisionOptionsType): Promise<EmbedderProvisionResultType> {
try {
const candidates = EmbedderProvisioner.#candidates(options);
const registry = new EmbedderRegistry();
for (const candidate of candidates) {
registry.register(candidate.descriptor, candidate.factory);
}
const preferences = candidates.map((c) => ({
'provider': c.descriptor.provider,
'model': c.descriptor.model,
}));
const cascade = new EmbedderCascade(registry, preferences);
const embedder = await cascade.select();
await embedder.connect();
const intentClassifier = await IntentClassifier.create(embedder);
return { embedder, intentClassifier };
} catch (err) {
console.warn('[EmbedderProvisioner] embedder unavailable; using LLM-only intent classification:', err);
return { 'embedder': null, 'intentClassifier': null };
}
}
}/** Build a real services record for the checkpoint resume path. */
function buildServices(): ArchivistServices {
const llm = makeLlm();
if (llm === null) throw new Error('no backend selected');
return {
'webSearch': webSearchTool,
'googleBooks': googleBooksTool,
'subjectSearch': subjectSearchTool,
'wikipediaSummary': wikipediaSummaryTool,
'memory': memoryStore,
'llm': llm,
'embedder': embedder.value,
'nodeTimeouts': {},
};
}Details for Nerds
OllamaEmbedder. Calls Ollama's/api/embeddingsendpoint. Constructed with{ model?, baseUrl?, dimensions? }: no API key required for local usage.selectEmbeddingModel()discovers an installed embedding model from/api/tags; known model dimensions are resolved from a built-in table, and unknown models requiredimensionsexplicitly.probe(). IssuesGET /api/tagswith a 500 ms timeout against the configured base URL. Returnstruewhen the daemon answers2xx,falseon timeout or connection error. Symmetric withOllamaApiAdapter.probe()so a single running Ollama daemon makes both surfaces available.EmbedderRegistry. Stores embedders keyed by(provider, model)pairs. API mirrorsLlmAdapterRegistryfor consistency.EmbedderCascade. Walks the preference list and returns the first available embedder. Throws when no embedder probes as available.- Cosine similarity. The example computes
dot(a, b) / (|a| × |b|)directly on the returned vectors. Identical strings score 1.0; semantically related strings score higher than unrelated ones.
Related Concepts
- Example 24: LLM Adapter - LlmAdapterRegistry, LlmAdapterCascade, and chat surface
- Example 26: Tool Use - Tool definition, ToolCallCodec, and adapter dispatch
- The Archivist - EmbedderCascade for intent classification
- Reference: Contracts - Embedder, EmbedderRegistry, EmbedderCascade contracts