Skip to content

zettelkasten.auto_note

zettelkasten.auto_note

Auto-draft a glossary/concept note via a one-shot in-process agent.

The Inspect view's "Add" fields call this: given a bare label (and, for a concept, optional context about what the user means), run the zettelkasten dashboard agent once (with read-only graph access) to research and draft a concise note, returned as structured fields the route turns into a note of the requested kind.

Two kinds are supported
  • definition — an objective, dictionary-style definition of a term.
  • concept — a substantive "your own thinking" note about an idea, which is more discursive and can be seeded with user context.

The agent NEVER writes here — the route does the deterministic note write — so the agent's only job is to produce good, grounded JSON. This mirrors :mod:zettelkasten.outline's DRAFT split (engine gathers/writes; agent drafts) and reuses its one-shot agent plumbing so the two configs cannot drift.

draft_note

draft_note(term: str, *, kind: str = 'definition', context: str = '', graph: str | None = None, draft_fn: 'Callable[[str, str], str] | None' = None) -> dict[str, Any]

Research term with the one-shot agent and return structured fields.

kind is one of :data:KINDS. Returns {title, body, aliases, tags}. draft_fn(system, prompt) -> str is injectable so tests can stub the agent deterministically; it defaults to running the in-process zettelkasten dashboard agent once. Raises ValueError when the input can't be drafted or the reply can't be parsed, and RuntimeError when the agent errors.

Source code in zettelkasten/auto_note.py
def draft_note(
    term: str,
    *,
    kind: str = "definition",
    context: str = "",
    graph: str | None = None,
    draft_fn: "Callable[[str, str], str] | None" = None,
) -> dict[str, Any]:
    """Research ``term`` with the one-shot agent and return structured fields.

    ``kind`` is one of :data:`KINDS`. Returns ``{title, body, aliases, tags}``.
    ``draft_fn(system, prompt) -> str`` is injectable so tests can stub the agent
    deterministically; it defaults to running the in-process zettelkasten
    dashboard agent once. Raises ``ValueError`` when the input can't be drafted
    or the reply can't be parsed, and ``RuntimeError`` when the agent errors.
    """
    term = (term or "").strip()
    if not term:
        raise ValueError("a term is required")
    if kind not in _SYSTEMS:
        raise ValueError(f"unknown kind '{kind}'")

    prompt = _build_prompt(term, kind, (context or "").strip(), graph)
    fn = draft_fn or _default_draft_fn
    text = fn(_SYSTEMS[kind], prompt)
    return _normalize(_extract_json(text), fallback_title=term)