Skip to content

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
DAG JSON-LD registered with the dispatcher
{
  "@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 generated from the same DAG
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

bash
npm run docs:dev

Open 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.

ts
/**
 * 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 };
    }
  }
}
vue
/** 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/embeddings endpoint. 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 require dimensions explicitly.
  • probe(). Issues GET /api/tags with a 500 ms timeout against the configured base URL. Returns true when the daemon answers 2xx, false on timeout or connection error. Symmetric with OllamaApiAdapter.probe() so a single running Ollama daemon makes both surfaces available.
  • EmbedderRegistry. Stores embedders keyed by (provider, model) pairs. API mirrors LlmAdapterRegistry for 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.

Watched over by the Order of Dagon.