JSPM

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

LLM-backed worox-graph composer: create, modify, explain, suggestConceptObjective, reviewConcept, catalog resolution/creation, scoping need match and scoping map creation plans, plus optional orchestrator — 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 using aifunctions-js and OpenRouter.

Graph structure: create, modify, explain. Product metadata: suggestConceptObjective (metadata.graphConcept). Concept QA: reviewConcept (verdict + findings, no graph rewrite). Managed catalogs (MetaDB / planning JSON only — host applies CRUD): suggestCatalogResolution, suggestCatalogCreations. Scoping-only: suggestScopingNeedMatch (natural-language need vs catalogCandidates.scopingMaps), suggestScopingMapCreation (scopingMapProposal + catalogRequestProposals).

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, 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.

    Registered tool ids (mirror GRAPH_COMPOSER_ACTION_REGISTRY): graph_create, graph_modify, graph_explain, graph_suggest_concept_objective, graph_suggest_catalog_resolution, graph_suggest_catalog_creations, graph_suggest_scoping_need_match, graph_suggest_scoping_map_creation, graph_review_concept.

    Pass catalogCandidates on GraphComposerAgentInput when the goal involves catalog or scoping tools (host loads rows from @woroces/worox-graph / MetaDB when applicable).

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,
});

Review concept (reviewConcept)

Requires existingGraph. Returns verdict (coherent, summary) and findings (category, severity, summary, optional nodeIds / suggestedChange). Optional suggestedConceptPatch (partial graphConcept keys). No graph, changelog, or explanation. Use for design review before heavy edits.

Catalog resolution & creation (suggestCatalogResolution, suggestCatalogCreations)

Both require existingGraph. Pass catalogCandidates (from worox-graph MetaDB list APIs or fixtures): aiSkills, utilitySkills, scopingMaps, narrixTemplates — see docs/worox-graphs-catalogs.md and docs/catalog-metadb-end-state-contract.md.

  • suggestCatalogResolution — Per-node style recommendations: skillResolution, scopingResolution, narrixResolution, gaps. Optional matchLists pre-pass (skills / scoping / narrix) injects catalogMatchHints into the worker prompt when catalogMatchListsAssist !== false (default) and an OpenRouter client is available.
  • suggestCatalogCreationscatalogRequestProposals (+ optional newSkillDescriptors). Host applies approved rows via worox-graph CRUD; this package emits JSON only.

Scoping need match & scoping map creation

  • suggestScopingNeedMatchDoes not require existingGraph (optional context). Requires non-empty catalogCandidates.scopingMaps. Put the data need in intent.description. Output: hasSuitableMatch, recommended (scopingMapId / questionId when true, null when false), gaps, optional alternatives. Optional matchLists injects scopingNeedMatchHints (same client / catalogMatchListsAssist flag).
  • suggestScopingMapCreation — Plan a new scoping map: scopingMapProposal + non-empty catalogRequestProposals. Host creates MetaDB artifacts; see WoroxScopingMapCatalogCreatePayload in src/scopingCatalogHostTypes.ts.

RunGraphComposerOptions (workers)

In addition to client, mode, model, temperature, maxTokens, askTimeoutMs, connectTimeoutMs:

  • catalogMatchListsAssist — When not false, enables matchLists pre-passes for suggestCatalogResolution, suggestCatalogCreations, and suggestScopingNeedMatch when a client is resolved (skips if no client).

Worker actions cheat sheet

intent.action existingGraph Notes
create No Full graph + changelog
modify Yes Patched graph + changelog
explain Yes explanation object only
suggestConceptObjective Yes graphConceptPatch
reviewConcept Yes verdict + findings
suggestCatalogResolution Yes Pass catalogCandidates; optional catalogMatchHints injection
suggestCatalogCreations Yes catalogRequestProposals
suggestScopingNeedMatch No* *Optional; requires non-empty catalogCandidates.scopingMaps
suggestScopingMapCreation No* *Optional; scopingMapProposal + catalogRequestProposals

Authoritative JSON shapes: functions/graph-composer/meta.json.

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, getActionDefinitionByToolName, requiredPromptPathsFromRegistry, loadWorkerBaseMarkdown Action registry + prompts.
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(), graphComposerPackRoot() Path to bundled functions/graph-composer pack.
readGraphComposerPromptFile(name) Read a file under functions/graph-composer/prompts/.
DEFAULT_UTILITY_SKILLS Default local skills when utilitySkills is omitted.
buildCatalogMatchHints, buildScopingNeedMatchHints Optional matchLists helpers (normally invoked inside runGraphWorker).
validateSuggestCatalogResolutionOutput, validateSuggestCatalogCreationsOutput, validateSuggestScopingNeedMatchOutput, validateSuggestScopingMapCreationOutput, validateReviewConceptOutput Offline output validators for tests / hosts.
Types: GraphComposerInput, GraphComposerAgentInput, GraphComposerIntent, CatalogCandidates, ScopingMapCandidate, NarrixTemplateCandidate, … See dist/index.d.ts.
WoroxScopingMapCatalogCreatePayload, WoroxScopedDataDocumentShape Host-side CRUD handoff (verify against @woroces/worox-graph).
parseGraphConceptStory, isGraphConceptStoryDescription, GRAPH_CONCEPT_STORY_MARKER, … Parse graph concept story text for create / modify / reviews.

RunGraphComposerOptions: client, mode, model, temperature, maxTokens, askTimeoutMs, connectTimeoutMs, catalogMatchListsAssist — 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

Published npm tarball still does not ship docs/; clone the repo or read these on GitHub for integration details.

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.