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)
Direct workers (
runGraphComposer) — You setintent.action. Each action uses a dedicated system prompt (shared worox-graph fragments + oneaction-*.mdfile) plus the same skill catalogs and skill-mode gate as before. All graph-scoped actions are registered insrc/graphComposerActions.ts; adding an action means extending that registry and adding prompt files (seefunctions/graph-composer/prompts/README.md).Orchestrator (
runGraphComposerAgent) — You pass a natural-languagegoal. The orchestrator usesrunJsonCompletion(structured JSON steps) to choose registered tools, then runs each selection via the samerunGraphWorkerpath 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
catalogCandidatesonGraphComposerAgentInputwhen 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-composerRequires 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. OptionalmatchListspre-pass (skills / scoping / narrix) injectscatalogMatchHintsinto the worker prompt whencatalogMatchListsAssist !== false(default) and an OpenRouter client is available.suggestCatalogCreations—catalogRequestProposals(+ optionalnewSkillDescriptors). Host applies approved rows via worox-graph CRUD; this package emits JSON only.
Scoping need match & scoping map creation
suggestScopingNeedMatch— Does not requireexistingGraph(optional context). Requires non-emptycatalogCandidates.scopingMaps. Put the data need inintent.description. Output:hasSuitableMatch,recommended(scopingMapId/questionIdwhen true,nullwhen false),gaps, optionalalternatives. OptionalmatchListsinjectsscopingNeedMatchHints(same client /catalogMatchListsAssistflag).suggestScopingMapCreation— Plan a new scoping map:scopingMapProposal+ non-emptycatalogRequestProposals. Host creates MetaDB artifacts; seeWoroxScopingMapCatalogCreatePayloadinsrc/scopingCatalogHostTypes.ts.
RunGraphComposerOptions (workers)
In addition to client, mode, model, temperature, maxTokens, askTimeoutMs, connectTimeoutMs:
catalogMatchListsAssist— When notfalse, enablesmatchListspre-passes forsuggestCatalogResolution,suggestCatalogCreations, andsuggestScopingNeedMatchwhen 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— runssuggestConceptObjectiveon the same sample graph.
export OPENROUTER_API_KEY=sk-or-...
npx @x12i/graph-composer explain-basic
npx @x12i/graph-composer network-vulnOr use the binary name:
graph-composer explain-basicAPI 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 declarationsfunctions/graph-composer/—prompts/(per-action workers,shared/,orchestrator-system.md,judge-rules.md+ JSON block,default-utility-skills.json), plusmeta.json,test-cases.jsonexamples/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 .envOptional: nx-config2 for scripts that load .env:
npx nx-config2 run --env-file .env -- npm testMaintainer smoke (suggest only, truncated JSON): npm run suggest-smoke (repo only; uses scripts/run-suggest-concept-smoke.ts).
Documentation in this repo
- Handoff / forward notes: docs/integration-handoff.md
- Catalog shapes & inspection: docs/worox-graphs-catalogs.md
- MetaDB / host CRUD handoff: docs/catalog-metadb-end-state-contract.md
- aifunctions-js agent toolbox FR: docs/aifunctions-agent-toolbox-feature-request.md
- Verify suggestConceptObjective: docs/verify-suggest-concept-objective.md
- aifunctions-js transport report: docs/report-aifunctions-js-undici-http.md
- Historical spec: docs/specs.md — not published on npm
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 publishConfirm tarball: npm run pack:check (must not list docs/, .env, or test/).
License
MIT — see LICENSE.