JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 319
  • Score
    100M100P100Q103386F
  • License MIT

LLM-backed worox-graph composer: create, modify, explain, suggestConceptObjective, suggestCatalogResolution, suggestCatalogCreations via OpenRouter and aifunctions-js

Package Exports

  • @x12i/graph-composer

Readme

@x12i/graph-composer

Location
GitHub (source) woroces/graph-composer — clone: git@github.com:woroces/graph-composer.git
npm (package) @x12i/graph-composer

The Git repo lives under the woroces org with repo name graph-composer. That is separate from the npm scope @x12i.

LLM-backed graph composer for the worox-graph DAG format: create, modify, explain, or suggestConceptObjective (primary intent / graph-level objective for metadata.graphConcept) using aifunctions-js and OpenRouter.

Architecture (two ways to run)

  1. Direct workers (runGraphComposer) — You set intent.action. Each action uses a dedicated system prompt (shared worox-graph fragments + one action-*.md file) plus the same skill catalogs and skill-mode gate as before. All graph-scoped actions are registered in src/graphComposerActions.ts; adding an action means extending that registry and adding prompt files (see functions/graph-composer/prompts/README.md).

  2. Orchestrator (runGraphComposerAgent) — You pass a natural-language goal. The orchestrator uses runJsonCompletion (structured JSON steps) to choose registered tools (graph_create, graph_modify, graph_explain, graph_suggest_concept_objective), then runs each selection via the same runGraphWorker path as direct mode. This costs more tokens and latency (multiple LLM rounds) than a single direct call.

Upstream feature request for first-class tool loops / worker profiles in aifunctions-js: docs/aifunctions-agent-toolbox-feature-request.md.

Install

npm install @x12i/graph-composer

Requires Node.js 18+.

Environment

Variable Required Description
OPENROUTER_API_KEY Yes (for API runs) OpenRouter API key.
LLM_MODEL_STRONG No Model slug when using mode: "strong" (default preset from aifunctions-js).
LLM_MODEL_NORMAL No Model slug for normal mode.
GRAPH_COMPOSER_LOGS_LEVEL No Log level for logs-gateway (info, warn, …).

Copy .env.example to .env for local development. Do not commit secrets.

Quick start (direct worker)

import { runGraphComposer } from "@x12i/graph-composer";

const result = await runGraphComposer(
  {
    intent: {
      action: "create",
      description: "Read a record, classify it, persist the result.",
    },
    skillMode: "locked",
    aiSkills: [
      {
        skillKey: "professional-answer",
        description: "Structured analysis with LLM",
        isLocal: false,
      },
    ],
    utilitySkills: [
      {
        skillKey: "scoped-data-reader",
        description: "Read scoped data",
        isLocal: true,
      },
      {
        skillKey: "scoped-answer-writer",
        description: "Persist results",
        isLocal: true,
      },
    ],
    constraints: { requireFinalizer: true },
  },
  {
    askTimeoutMs: 120_000,
    connectTimeoutMs: 60_000,
    maxTokens: 8192,
  }
);

Orchestrator (toolbox)

import { runGraphComposerAgent } from "@x12i/graph-composer";

const out = await runGraphComposerAgent(
  {
    goal:
      "Explain the attached graph for operators: summary, execution order, data flow.",
    existingGraph: myGraphJson,
    skillMode: "locked",
    aiSkills: [...],
    utilitySkills: [...],
  },
  {
    askTimeoutMs: 120_000,
    connectTimeoutMs: 60_000,
    maxTokens: 8192,
    maxOrchestratorSteps: 8,
  }
);
// out.orchestration.summary — orchestrator narrative
// out.orchestration.steps — which tools ran
// out.result — last worker JSON (e.g. explain payload)

runGraphComposerAgent uses the same OpenRouter client resolution as workers; pass options.model if you need an explicit model for orchestrator JSON steps (see aifunctions-js runJsonCompletion).

Explain an existing graph

Pass existingGraph (worox-graph JSON) and intent.action: "explain".

Suggest primary intent (suggestConceptObjective)

Generic API (any graph): set intent.action: "suggestConceptObjective", existingGraph (required), optional analysisContext, and the usual skill / constraint fields. This is not tied to a specific domain or subnet.

Bundled example only: inputSuggestConceptObjectiveNetworkVulnSubnet() and the sample graph under examples/ are fixtures for tests and docs—they illustrate one real graph, not a special-case API.

Optional intent.onlyIfEmpty: array of patch field names (primaryIntentType, primaryIntentStatement, businessObjective, primaryOutcome). The runtime drops any listed key from the model’s graphConceptPatch when existingGraph.metadata.graphConcept.<key> is already a non-empty string, and appends a short note to rationale when something was skipped.

Stable result shape (top-level, in addition to action):

{
  "action": "suggestConceptObjective",
  "graphConceptPatch": {
    "primaryIntentType": "objective",
    "primaryIntentStatement": "One or two product-facing sentences describing what this graph achieves for the user.",
    "businessObjective": "",
    "primaryOutcome": ""
  },
  "rationale": "Optional short note for UI or logs."
}

primaryIntentType is one of: question, decision, action, objective (same vocabulary as playground INTENT_TYPE_OPTIONS). Apply the patch in the consumer with a shallow merge into metadata.graphConcept, e.g. { ...existing, ...graphConceptPatch }.

Types: GraphConceptPatch, GraphConceptPatchKey, PrimaryIntentType. Helper: applyGraphConceptPatchOnlyIfEmpty() (same merge rule the runtime uses after the LLM returns).

Example using the bundled fixture helper:

import { runGraphComposer, inputSuggestConceptObjectiveNetworkVulnSubnet } from "@x12i/graph-composer";

const result = await runGraphComposer(inputSuggestConceptObjectiveNetworkVulnSubnet(), {
  askTimeoutMs: 120_000,
  connectTimeoutMs: 60_000,
  maxTokens: 4096,
});

CLI (after install)

Core usage: pass a test-cases.json id (e.g. explain-basic, create-simple-linear) — these map to the pack’s machine fixtures.

Demo / smoke only (not the core API surface):

  • network-vuln — runs explain on the bundled subnet triage sample graph.
  • network-vuln-intent — runs suggestConceptObjective on the same sample graph.
export OPENROUTER_API_KEY=sk-or-...
npx @x12i/graph-composer explain-basic
npx @x12i/graph-composer network-vuln

Or use the binary name:

graph-composer explain-basic

API highlights

Export Purpose
runGraphComposer(input, options?) Direct worker for intent.action.
runGraphComposerAgent(input, options?) Orchestrator + toolbox (multi-step JSON).
runGraphWorker Same LLM path as runGraphComposer (used internally and for advanced composition).
getGraphComposerLlmClient Always returns an OpenRouter Client (orchestrator / custom ask use).
resolveGraphComposerClient Optional client + timeout wiring (may return undefined for executeSkill defaults).
GRAPH_COMPOSER_ACTION_REGISTRY, getActionDefinition, … Extensible action registry + prompt paths.
composeWorkerInstructions Build full system text for one action + catalogs + mode gate.
applyGraphConceptPatchOnlyIfEmpty Apply intent.onlyIfEmpty rules to a graphConceptPatch.
composeInstructions, formatSkillList Lower-level composition from a raw base string + skill lists.
getPackDir() Absolute path to the bundled functions/graph-composer pack.
graphComposerPackRoot() Same path as getPackDir().
readGraphComposerPromptFile(name) Read a file under functions/graph-composer/prompts/.
DEFAULT_UTILITY_SKILLS Default local skills when utilitySkills is omitted.

RunGraphComposerOptions includes client, mode, model, temperature, maxTokens, askTimeoutMs, and connectTimeoutMs — see integration handoff.

Bundled content

Published tarball includes:

  • dist/ — compiled ESM + TypeScript declarations
  • functions/graph-composer/prompts/ (per-action workers, shared/, orchestrator-system.md, judge-rules.md + JSON block, default-utility-skills.json), plus meta.json, test-cases.json
  • examples/network-vuln-subnet-triage.v2.json — sample worox graph

It does not include internal docs/, tests, or .env.

Development (this repo)

The repository may keep a duplicate of the sample graph under docs/examples/ for documentation. The published package only ships examples/; keep them in sync if you change the sample.

cp .env.example .env
npm install
npm run build
npm run verify:local
npm run typecheck
npm test          # live tests; needs OPENROUTER_API_KEY in .env

Optional: nx-config2 for scripts that load .env:

npx nx-config2 run --env-file .env -- npm test

Maintainer smoke (suggest only, truncated JSON): npm run suggest-smoke (repo only; uses scripts/run-suggest-concept-smoke.ts).

Documentation in this repo

Publishing (maintainers)

Scoped package @x12i/graph-composer uses publishConfig.access: "public". Ensure your npm user is a member of the x12i org (or owns the scope) and has a valid token in ~/.npmrc or project .npmrc (never commit tokens).

npm run build
npm publish

Confirm tarball: npm run pack:check (must not list docs/, .env, or test/).

License

MIT — see LICENSE.