Skip to content

Graph tools

The tools an agent calls to build a graph: classify, add premises, and finish a run.

Each tool is one write to a run directory (session.write): it takes the run's lock, applies its operation to the current state, and is logged. A tool never writes graph JSON and never sets a credence: records go through the assembler, so every base and strength is the rubric's. A refused record is a result, not an error: it comes back with its code, the core's message and a fix saying what to change, and is kept in the run's rejections; the agent may simply call again.

  • classify types, splits and links chunks. A node already typed may be typed again, which first returns it to unassigned (assemble), but not once a check targets it: a failed check cannot be escaped by making its node a type no check applies to. A chunk already split cannot be split again.
  • add_premises adds the implicit premises of conclusions, as the premise records do.
  • run_checks checks and runs proposals of the maths check types (checks.run_maths), and adds a check node for each that runs, with its files in the run. A check is never withdrawn or run again on its target, nor run again on another target as another encoding of the same step.
  • judge_citation reads a citation's source itself, finds the agent's passage in it, and records a check that passes or fails as the agent judged only when the source is tied to the reference (citation); any other source gives an error, which moves no credence.
  • finish_run derives every assessed node's verdict from the checks that observe it, runs the core's check at the assessed level with rubric credences, and marks the run finished; the run's outputs are written then. Any later write marks it unfinished again.

start_run and get_state are in session.

add_premises(run, records, *, model, agent=None, note=None)

Add the implicit premises of conclusions.

Parameters:

Name Type Description Default
run Path

The run directory.

required
records Sequence[Any]

Premise records, each {"conclusion", "premises": [{"stated_at"} | {"statement"}, ...]}.

required
model str

The model making the call, as the harness reports it.

required
agent str | None

A name for the agent.

None
note str | None

Free text kept with the call.

None

Returns:

Type Description
dict[str, Any]

applied, the nodes created or changed (analyst premises included); refused, each

dict[str, Any]

refused record with its code and message; and overflow, premises beyond the rubric's limit.

Raises:

Type Description
RunError

If the rubric takes no premises, or the call as a whole is refused.

Source code in src/credencegraph_extract/tools.py
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
def add_premises(
    run: Path, records: Sequence[Any], *, model: str, agent: str | None = None, note: str | None = None
) -> dict[str, Any]:
    """Add the implicit premises of conclusions.

    Args:
        run: The run directory.
        records: Premise records, each ``{"conclusion", "premises": [{"stated_at"} | {"statement"}, ...]}``.
        model: The model making the call, as the harness reports it.
        agent: A name for the agent.
        note: Free text kept with the call.

    Returns:
        ``applied``, the nodes created or changed (analyst premises included); ``refused``, each
        refused record with its code and message; and ``overflow``, premises beyond the rubric's limit.

    Raises:
        RunError: If the rubric takes no premises, or the call as a whole is refused.
    """
    return write(run, ADD_PREMISES, {"records": _sent(records)}, model=model, agent=agent, note=note)

checked(graph)

Return the nodes a check targets: the sources of observes relations.

Parameters:

Name Type Description Default
graph Graph

The graph.

required

Returns:

Type Description
set[str]

Their ids.

Source code in src/credencegraph_extract/tools.py
143
144
145
146
147
148
149
150
151
152
def checked(graph: Graph) -> set[str]:
    """Return the nodes a check targets: the sources of ``observes`` relations.

    Args:
        graph: The graph.

    Returns:
        Their ids.
    """
    return {relation.source for relation in graph.relations.values() if relation.type == OBSERVES}

classify(run, records, *, model, agent=None, note=None)

Type, split and link chunks of a run's document.

Parameters:

Name Type Description Default
run Path

The run directory.

required
records Sequence[Any]

Classify records, each {"node", "type", "form"?, "rests_on"?, "hedge"?} or {"node", "split", "children"}.

required
model str

The model making the call, as the harness reports it.

required
agent str | None

A name for the agent, for runs with several.

None
note str | None

Free text kept with the call, never used in inference.

None

Returns:

Type Description
dict[str, Any]

applied, the nodes created or changed; refused, each refused record with its code,

dict[str, Any]

message and fix; and unmapped_hedges, hedge phrases the rubric does not list.

Raises:

Type Description
RunError

If the call as a whole is refused (records not a list, the run busy or malformed).

Source code in src/credencegraph_extract/tools.py
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
def classify(
    run: Path, records: Sequence[Any], *, model: str, agent: str | None = None, note: str | None = None
) -> dict[str, Any]:
    """Type, split and link chunks of a run's document.

    Args:
        run: The run directory.
        records: Classify records, each ``{"node", "type", "form"?, "rests_on"?, "hedge"?}`` or
            ``{"node", "split", "children"}``.
        model: The model making the call, as the harness reports it.
        agent: A name for the agent, for runs with several.
        note: Free text kept with the call, never used in inference.

    Returns:
        ``applied``, the nodes created or changed; ``refused``, each refused record with its code,
        message and ``fix``; and ``unmapped_hedges``, hedge phrases the rubric does not list.

    Raises:
        RunError: If the call as a whole is refused (``records`` not a list, the run busy or malformed).
    """
    return write(run, CLASSIFY, {"records": _sent(records)}, model=model, agent=agent, note=note)

finish_run(run, *, model, agent=None, note=None)

Derive the verdicts, check the graph with the core, and write the run's outputs.

It may be called again after later writes, which mark the run unfinished.

Parameters:

Name Type Description Default
run Path

The run directory.

required
model str

The model making the call, as the harness reports it.

required
agent str | None

A name for the agent.

None
note str | None

Free text kept with the call.

None

Returns:

Type Description
dict[str, Any]

findings, every violation the core's check reports at the assessed level with rubric

dict[str, Any]

credences, and ok, whether there are none.

Source code in src/credencegraph_extract/tools.py
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
def finish_run(run: Path, *, model: str, agent: str | None = None, note: str | None = None) -> dict[str, Any]:
    """Derive the verdicts, check the graph with the core, and write the run's outputs.

    It may be called again after later writes, which mark the run unfinished.

    Args:
        run: The run directory.
        model: The model making the call, as the harness reports it.
        agent: A name for the agent.
        note: Free text kept with the call.

    Returns:
        ``findings``, every violation the core's check reports at the ``assessed`` level with rubric
        credences, and ``ok``, whether there are none.
    """
    return write(run, FINISH, {}, model=model, agent=agent, note=note)

judge_citation(run, target, reference, source, passage, *, supports, model, agent=None, note=None, fetcher=fetch)

Record a citation check: read the source, find the passage, and decide whether the source is tied to the reference.

The tool reads the source itself; it never takes the text from the agent. A local source is a file of the run's copy of the cited works; a URL is fetched under the fetch policy (fetch). What was read (the file or URLs, the digests of the bytes and of their text, where the passage is, and what ties the source to the reference) is logged with the call, not the bytes, which are kept in sources/ only when the run stores its sources. The check passes or fails, as the agent judged, only when the passage is in the source and the source is tied to the reference (citation.tie); otherwise it is an error, which moves no credence. A target whose citation check passed or failed takes no other; one whose checks erred may be checked again.

Parameters:

Name Type Description Default
run Path

The run directory.

required
target str

The citing node.

required
reference str

The id of the bibliography entry (r-N), not its key.

required
source str

A file of the run's cited works, by name or path, or an http or https URL.

required
passage str

The passage of the source the target rests on, verbatim.

required
supports bool

Whether the passage supports the target.

required
model str

The model making the call, as the harness reports it.

required
agent str | None

A name for the agent.

None
note str | None

Free text kept with the call.

None
fetcher Callable[[str], Any]

Fetches a URL under the fetch policy; fetch.fetch by default.

fetch

Returns:

Type Description
dict[str, Any]

check, the id of the check, result, tied and detail; or check None and

dict[str, Any]

refused, with the refusal's code, message and fix.

Raises:

Type Description
RunError

If an argument is not of its type, or the call as a whole is refused.

Source code in src/credencegraph_extract/tools.py
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
def judge_citation(  # noqa: PLR0913 - the check, what the agent judged, and who makes the call
    run: Path,
    target: str,
    reference: str,
    source: str,
    passage: str,
    *,
    supports: bool,
    model: str,
    agent: str | None = None,
    note: str | None = None,
    fetcher: Callable[[str], Any] = fetch,
) -> dict[str, Any]:
    """Record a citation check: read the source, find the passage, and decide whether the source is tied to the reference.

    The tool reads the source itself; it never takes the text from the agent. A local source is a file
    of the run's copy of the cited works; a URL is fetched under the fetch policy (``fetch``). What was
    read (the file or URLs, the digests of the bytes and of their text, where the passage is, and what
    ties the source to the reference) is logged with the call, not the bytes, which are kept in
    ``sources/`` only when the run stores its sources. The check passes or fails, as the agent judged,
    only when the passage is in the source and the source is tied to the reference
    (``citation.tie``); otherwise it is an ``error``, which moves no credence. A target whose citation
    check passed or failed takes no other; one whose checks erred may be checked again.

    Args:
        run: The run directory.
        target: The citing node.
        reference: The id of the bibliography entry (``r-N``), not its key.
        source: A file of the run's cited works, by name or path, or an ``http`` or ``https`` URL.
        passage: The passage of the source the target rests on, verbatim.
        supports: Whether the passage supports the target.
        model: The model making the call, as the harness reports it.
        agent: A name for the agent.
        note: Free text kept with the call.
        fetcher: Fetches a URL under the fetch policy; ``fetch.fetch`` by default.

    Returns:
        ``check``, the id of the check, ``result``, ``tied`` and ``detail``; or ``check`` ``None`` and
        ``refused``, with the refusal's code, message and ``fix``.

    Raises:
        RunError: If an argument is not of its type, or the call as a whole is refused.
    """
    args = {
        "target": target,
        "reference": reference,
        "source": source,
        "passage": passage,
        "supports": supports,
        "read": _observe(run, reference, source, passage, fetcher),
        "versions": versions(),
    }
    return write(run, JUDGE_CITATION, args, model=model, agent=agent, note=note)

run_checks(run, proposals, *, model, agent=None, note=None)

Check and run proposals of the maths check types: recompute-numbers and rederive-maths.

A check, once run, is part of the run: it cannot be withdrawn or run again on the same target, nor run again on another target in another encoding of the same step. The versions of the code that runs the checks are recorded with the call.

Parameters:

Name Type Description Default
run Path

The run directory.

required
proposals Sequence[Any]

Check proposals, each {"target", "type": "recompute-numbers", "nodes", "expression", "expected"} or {"target", "type": "rederive-maths", "nodes", "lhs", "rhs", "symbols", "assumption"}.

required
model str

The model making the call, as the harness reports it.

required
agent str | None

A name for the agent.

None
note str | None

Free text kept with the call.

None

Returns:

Type Description
dict[str, Any]

checks, each check run with its id, type, target, result and detail (a rederive-maths

dict[str, Any]

that errs is followed by its numeric fallback when the rubric declares one); and refused,

dict[str, Any]

each refused proposal with its code, message and fix.

Raises:

Type Description
RunError

If the call as a whole is refused.

Source code in src/credencegraph_extract/tools.py
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
def run_checks(
    run: Path, proposals: Sequence[Any], *, model: str, agent: str | None = None, note: str | None = None
) -> dict[str, Any]:
    """Check and run proposals of the maths check types: ``recompute-numbers`` and ``rederive-maths``.

    A check, once run, is part of the run: it cannot be withdrawn or run again on the same target, nor
    run again on another target in another encoding of the same step. The versions of the code that
    runs the checks are recorded with the call.

    Args:
        run: The run directory.
        proposals: Check proposals, each ``{"target", "type": "recompute-numbers", "nodes", "expression",
            "expected"}`` or ``{"target", "type": "rederive-maths", "nodes", "lhs", "rhs", "symbols",
            "assumption"}``.
        model: The model making the call, as the harness reports it.
        agent: A name for the agent.
        note: Free text kept with the call.

    Returns:
        ``checks``, each check run with its id, type, target, result and detail (a ``rederive-maths``
        that errs is followed by its numeric fallback when the rubric declares one); and ``refused``,
        each refused proposal with its code, message and ``fix``.

    Raises:
        RunError: If the call as a whole is refused.
    """
    args = {"proposals": _sent(proposals), "versions": versions()}
    return write(run, RUN_CHECKS, args, model=model, agent=agent, note=note)