Taskweft.JSONLD.Loader (taskweft v0.4.0-dev.4)

Copy Markdown View Source

JSON-LD document loader for Taskweft planning domains.

Architecture

The C++ NIF (taskweft_nif) has its own minimal JSON parser (tw_loader.hpp) that reads compact JSON-LD with plain keys ("actions", "variables", etc.). Those keys are outside the @context vocabulary so a full JSON-LD expansion would drop them; we must keep the compact form for the NIF.

This module's job is therefore context resolution, not expansion:

  1. Parse the raw JSON with Jason.
  2. Resolve all @context entries — inline maps, local file references (e.g. "./udon-vm.jsonld"), and remote URLs — into a single merged map using JSON.LD.context/1.
  3. Validate the document type and required keys.
  4. Re-serialise to a compact JSON string with the fully-resolved context inlined, ready for the NIF.

C++ NIF contract

The NIF receives a compact JSON string where:

  • @context is a flat map of prefix → IRI (no @import, no arrays).
  • Planning keys ("actions", "variables", "methods", "goals") are plain strings not defined in @context — the loader preserves them as-is.
  • @type and @id are present but ignored by the C++ planner; this loader therefore validates @type on the Elixir side before the NIF call.

Error handling

Per project policy, every function returns {:ok, _} | {:error, reason} tuples. Reasons are human-readable strings suitable for surfacing to MCP clients.

Summary

Functions

Load a JSON-LD domain file, resolve all @context references, validate, and return a compact JSON string ready for the C++ NIF.

Process a JSON-LD domain string (with optional base_dir for resolving relative file-context references), validate, and return compact JSON for the C++ NIF.

Validate that a decoded JSON-LD document is a well-formed planning domain.

Functions

load_file(path)

@spec load_file(Path.t()) :: {:ok, String.t()} | {:error, String.t()}

Load a JSON-LD domain file, resolve all @context references, validate, and return a compact JSON string ready for the C++ NIF.

load_string(json, opts \\ [])

@spec load_string(
  String.t(),
  keyword()
) :: {:ok, String.t()} | {:error, String.t()}

Process a JSON-LD domain string (with optional base_dir for resolving relative file-context references), validate, and return compact JSON for the C++ NIF.

validate(doc, ctx)

@spec validate(map(), map()) :: :ok | {:error, String.t()}

Validate that a decoded JSON-LD document is a well-formed planning domain.

Runs in order: @type, name, top-level field shapes, goal/multigoal shapes, capability shapes, action/method call arity, action durations, variable substitution references. The first failure is returned; subsequent checks rely on the shape established by earlier ones (e.g. arity assumes actions is a map).