npm.io
2.17.0 • Published 2 weeks ago

@x12i/graphenix-core

Licence
MIT
Version
2.17.0
Deps
1
Size
112 kB
Vulns
0
Weekly
0

@x12i/graphenix-core

Core tier of the Graphenix ecosystem — Format 2.1.0 JSON wire layout (@x12i/graphenix-core@^2.3.0 on npm).

Execution-neutral graph description: JSON schema, TypeScript types, validation, and CRUD helpers. Profile packages build strict subtypes on top of this core via generic metadata, typed parameters, and validateGraphWithProfile().

Install

npm install @x12i/graphenix-core

Validate a graph document

import {
  validateGraph,
  GRAPHENIX_FORMAT_VERSION,
  type GraphDocument
} from "@x12i/graphenix-core";

const doc: GraphDocument = {
  formatVersion: GRAPHENIX_FORMAT_VERSION,
  id: "graph:auth/user-signup",
  graph: {
    nodes: [],
    edges: [],
    inputs: [],
    outputs: []
  }
};

const result = validateGraph(doc);
if (!result.valid) {
  console.error(result.errors);
}

Each error is a GraphValidationError:

  • message — human-readable message
  • path — JSON Pointer to the failing instance
  • keyword / params — from AJV when applicable
  • source'graphenix' or 'profile'
  • code — optional profile-specific error code

Document fields

Field Required Description
formatVersion yes Must be "2.1.0" — export GRAPHENIX_FORMAT_VERSION. Persist validators reject 2.0.0, 2.1.1, and other drift (AUTHORING_FORMAT_VERSION_UNSUPPORTED); use legacy import adapters for uplift, not silent migration.
id yes Globally unique graph identifier
revision no Version of this graph document (not the format version)
graph yes Structural graph (nodes, edges, inputs, outputs)
metadata no Document metadata, extensions, summary contracts
types no Custom type definitions
subgraphs no Inlined reusable graphs

Graph metadata (format 2.1.0)

Executable-profile graphs use first-class graph metadata fields. Core validates object shape; profile packages validate semantics.

graph.metadata
├── graphEntry      entry contract, execution schema
├── graphResponse   response shape, final output schema
├── modelConfig     graph-wide AI model cases (profile packages validate)
└── data            optional client keys (variables, presets, …)
{
  "graph": {
    "metadata": {
      "modelConfig": { "cases": [] },
      "data": { "variables": {} }
    }
  }
}

Do not emit metadata.extensions on new authoring graphs. Migration from 2.0.0 layout: docs/guides/migration-tier-1-authoring.md.


Generic types for profile subtypes

import type { GraphDocument, GraphMetadata, GraphenixMetadata } from "@x12i/graphenix-core";

interface X12iGraphMetadata extends GraphMetadata {
  modelConfig: { cases: unknown[] };
  data?: { variables?: Record<string, unknown> };
}

type X12iNodeParameters = { skillKey: string };

type X12iExecutableGraphDocument = GraphDocument<
  GraphenixMetadata,
  X12iGraphMetadata,
  X12iNodeParameters,
  GraphenixMetadata
>;

Aliases: GraphNode, GraphEdge, GraphPort, GraphType, Subgraph.


Profile validation

import {
  validateGraphWithProfile,
  type GraphProfileValidator,
  type GraphValidationError
} from "@x12i/graphenix-core";

const validateX12iProfile: GraphProfileValidator = (doc) => {
  const errors: GraphValidationError[] = [];
  const modelConfig = doc.graph.metadata?.modelConfig;
  if (!modelConfig || typeof modelConfig !== "object") {
    errors.push({
      source: "profile",
      code: "GRAPHENIX_MODEL_CONFIG_MISSING",
      message: "Executable profile is missing modelConfig.",
      path: "/graph/metadata/modelConfig"
    });
  }
  return { valid: errors.length === 0, errors };
};

validateGraphWithProfile(doc, validateX12iProfile);

Base validation runs first; profile validation runs only when base validation passes.


Input and output contracts

Per-port input contractgraph.inputs[].contract:

{
  "id": "rawRecord",
  "type": "object",
  "target": { "nodeId": "q1", "portId": "record" },
  "contract": {
    "semanticKind": "record",
    "required": true,
    "schema": { "type": "object" }
  }
}

Per-port output contractgraph.outputs[].contract:

{
  "id": "graph-output:final",
  "type": "builtin:object",
  "source": { "nodeId": "node:finalizer", "portId": "out:final" },
  "contract": {
    "semanticKind": "final-output",
    "required": true,
    "schema": { "type": "object" }
  }
}

Graph-level summary contracts — complement per-port contracts:

Layer Purpose
graph.inputs[].contract Contract for a specific graph input port
metadata.graphEntry Summary contract for graph invocation
graph.outputs[].contract Contract for a specific graph output port
metadata.graphResponse Summary contract for final graph result

Optional AJV checks against executionSchema / finalOutputSchema:

import {
  validateExecutionAgainstContract,
  validateFinalOutputAgainstContract
} from "@x12i/graphenix-core";

See docs/interop-worox-graph.md for worox-graph interop notes.


CRUD helpers

Immutable by default; pass { mutate: true } to modify in place.

import { addNode, updateNode, removeNode, addEdge } from "@x12i/graphenix-core";
  • Nodes: getNode, addNode, updateNode, removeNode
  • Edges: getEdge, addEdge, updateEdge, removeEdge
  • Types: getType, addType, updateType, removeType
  • Subgraphs: getSubgraph, addSubgraph, updateSubgraph, removeSubgraph

Test Utilities (Golden Fixtures)

The core package provides utilities for maintaining "golden" fixtures. This is particularly useful during the authoring stage to ensure the generated documents match a stable reference, helping the user understand the structure of what they have.

import { assertGoldenFixture } from "@x12i/graphenix-core/test-utils";

const actual = { /* ... your generated graph ... */ };
const fixturePath = "./fixtures/my-graph.json";

// Asserts that 'actual' matches the JSON in 'fixturePath'.
// If the file is missing or differs, it throws an error.
// Set UPDATE_FIXTURES=true to create or update the fixture automatically.
assertGoldenFixture(actual, fixturePath, {
  graphenixMasks: true // Automatically mask dynamic fields like planId, createdAt, etc.
});
Option Purpose
update If true, creates/updates the fixture file.
graphenixMasks If true, masks common dynamic fields (planId, createdAt, *Hash, etc.).
mask Array of additional keys to mask recursively.
scrub Custom function to transform data before comparison.
API Purpose
matchGoldenFixture Returns a structured result (pass, wrote, actual, expected, message)
assertGoldenFixture Throws an AssertionError if the match fails (and update is not enabled)
maskKeys Recursive helper to replace keys with placeholders

JSON Schema

Published at schema/graphenix-format-2.1.0.schema.json ($id: https://graphenix.dev/schema/graphenix-format-2.1.0.json). Legacy 2.0.0 schema retained for reference only.

Full field reference: GRAPHENIX-FORMAT.md.


Development

From the monorepo root:

npm install
npm run build
npm test

Or from this package:

npm run build
npm test

Notes

  • Execution-agnostic — core defines structure only.
  • Profile packages enforce execution semantics via metadata.modelConfig, typed node parameters, and profile validators.
  • Client-specific fields live in metadata.data; core validates object type only.
  • Task-node field names and phase vocabulary: GLOSSARY.md (monorepo root).

Keywords