@exellix/graph-composer 2.0.7 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +28 -2
- package/dist/canonicalGraphDocument.d.ts.map +1 -1
- package/dist/canonicalGraphDocument.js +1 -0
- package/dist/canonicalGraphWarnings.d.ts.map +1 -1
- package/dist/canonicalGraphWarnings.js +1 -0
- package/dist/graphComposerLogging.d.ts +45 -0
- package/dist/graphComposerLogging.d.ts.map +1 -0
- package/dist/graphComposerLogging.js +132 -0
- package/dist/graphEngineBridge.d.ts +1 -1
- package/dist/graphEngineBridge.d.ts.map +1 -1
- package/dist/graphEngineBridge.js +1 -1
- package/dist/graphModelLayers.d.ts +91 -0
- package/dist/graphModelLayers.d.ts.map +1 -0
- package/dist/graphModelLayers.js +322 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/runGraphComposer.d.ts +13 -5
- package/dist/runGraphComposer.d.ts.map +1 -1
- package/dist/runGraphComposer.js +37 -12
- package/functions/graph-composer/metadata/log-diagnostics.json +20 -0
- package/functions/graph-composer/prompts/action-explain.md +2 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -38,7 +38,7 @@ Requires **Node.js 20+** (Catalox embedder and this package align on `>=20`).
|
|
|
38
38
|
| `OPENROUTER_API_KEY` | **Yes** (for API runs) | OpenRouter API key. |
|
|
39
39
|
| `LLM_MODEL_STRONG` | No | Model slug when using `mode: "strong"` (default preset from @x12i/funcx). |
|
|
40
40
|
| `LLM_MODEL_NORMAL` | No | Model slug for `normal` mode. |
|
|
41
|
-
| `GRAPH_COMPOSER_LOGS_LEVEL` | No | Log level for [@x12i/logxer](https://www.npmjs.com/package/@x12i/logxer) (`info`, `warn`, …). |
|
|
41
|
+
| `GRAPH_COMPOSER_LOGS_LEVEL` | No | Log level for [@x12i/logxer](https://www.npmjs.com/package/@x12i/logxer) (`debug`, `info`, `warn`, `off`, …). Overridable in code via `configureGraphComposerLogging` or per-call `logsLevel`. Uses diagnostic catalog `functions/graph-composer/metadata/log-diagnostics.json` (code `GRAPH_COMPOSER_WORKER_FAILED` on worker errors). |
|
|
42
42
|
|
|
43
43
|
Copy [`.env.example`](./.env.example) to `.env` for local development. **Do not commit secrets.**
|
|
44
44
|
|
|
@@ -158,7 +158,30 @@ const result = await runGraphComposer(inputSuggestConceptObjectiveNetworkVulnSub
|
|
|
158
158
|
|
|
159
159
|
**Requires** `existingGraph`. Returns **`verdict`** (`coherent`, `summary`) and **`findings`** (category, severity, summary, optional **`taskIndex`**, **`proposal`**, `nodeIds`, `suggestedChange`). When **`metadata.graphConcept.coreTasks`** is non-empty, the model should return **`graphConceptPatch`** or **`suggestedConceptPatch`** (same partial shape; prefer one) with **`coreTasks`** index-aligned to that array and partial **`requirements`** (`skill`, `catalogBinding`, `narrix`, `memoryIO`, optional **`webScoping`**, etc.) inferred from the graph and catalogs. When a single value cannot be chosen, the model may return **`requirementOptions`** (ranked **`candidates`** per `taskIndex` + dot-path **`field`**, plus **`needsNewArtifact`**). Optional extended string fields on the patch (e.g. `expectedInput`, `outputDescription`) and optional **`catalogProposals`** for catalog gaps. No `graph`, `changelog`, or `explanation`. Use for design review before heavy edits.
|
|
160
160
|
|
|
161
|
-
**Tracing:** For `reviewConcept` only, `runGraphWorker` logs a **redacted** JSON snapshot of the serialized worker request and the **raw LLM worker response** (@x12i/funcx function-pack invocation): at **`debug`** by default (
|
|
161
|
+
**Tracing:** For `reviewConcept` only, `runGraphWorker` logs a **redacted** JSON snapshot of the serialized worker request and the **raw LLM worker response** (@x12i/funcx function-pack invocation): at **`debug`** by default (`logsLevel: "debug"` or `GRAPH_COMPOSER_LOGS_LEVEL=debug`), or at **`info`** when **`traceReviewConceptIo: true`** is passed in `RunGraphComposerOptions`. Payloads are capped (~500k chars) and keys matching secrets (`apiKey`, `password`, `token`, etc.) are replaced with `[redacted]`. Pass **`logContext`** (`jobId`, `runId`, `graphId`, …) in `RunGraphComposerOptions` so all logs correlate in Mongo/query APIs via logxer `runWithLogContext`.
|
|
162
|
+
|
|
163
|
+
### Logging from downstream hosts
|
|
164
|
+
|
|
165
|
+
Set the threshold once at process startup, per request, or via env:
|
|
166
|
+
|
|
167
|
+
```ts
|
|
168
|
+
import {
|
|
169
|
+
configureGraphComposerLogging,
|
|
170
|
+
getGraphComposerLoggingConfig,
|
|
171
|
+
runGraphComposer,
|
|
172
|
+
} from "@x12i/graph-composer";
|
|
173
|
+
|
|
174
|
+
// Process-wide (e.g. after reading your service config)
|
|
175
|
+
configureGraphComposerLogging({ logsLevel: "info" });
|
|
176
|
+
|
|
177
|
+
// Per invocation — wins over configure + env for that call only
|
|
178
|
+
await runGraphComposer(input, { logsLevel: "debug", logContext: { jobId: "j-1" } });
|
|
179
|
+
|
|
180
|
+
// Inspect effective level (after overrides)
|
|
181
|
+
const { logsLevel, debugEnabled, envKeys } = getGraphComposerLoggingConfig();
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Precedence per worker run: **`options.logsLevel`** → **`configureGraphComposerLogging`** → **`GRAPH_COMPOSER_LOGS_LEVEL`** (or legacy `GRAPH_COMPOSER_LOG_LEVEL`) → default **`warn`**. Use **`off`** / **`none`** / **`silent`** to silence graph-composer logs. **`getGraphComposerLogger()`** returns the shared logxer instance if you need `getJobLogs` / `scopeLogs` from the same sink.
|
|
162
185
|
|
|
163
186
|
### Generate example input
|
|
164
187
|
|
|
@@ -195,6 +218,8 @@ Both **require** `existingGraph`. Pass **`catalogCandidates`** (from **Catalox**
|
|
|
195
218
|
In addition to `client`, `mode`, `model`, `temperature`, `maxTokens`, `askTimeoutMs`, `connectTimeoutMs`:
|
|
196
219
|
|
|
197
220
|
- **`catalogMatchListsAssist`** — When not `false`, enables **`matchLists`** pre-passes for `suggestCatalogResolution`, `suggestCatalogCreations`, and **`suggestScopingNeedMatch`** when a client is resolved (skips if no client).
|
|
221
|
+
- **`logsLevel`** — Per-call log threshold (`debug`, `info`, `off`, …). Overrides `configureGraphComposerLogging` and env for that run.
|
|
222
|
+
- **`logContext`** — Correlation ids (`jobId`, `runId`, `graphId`, …) on every log line via logxer `runWithLogContext`.
|
|
198
223
|
- **`traceReviewConceptIo`** — When `true`, emit **`reviewConcept`** request/response trace logs at **`info`** (still redacted). When `false` (default), the same traces use **`debug`** only.
|
|
199
224
|
|
|
200
225
|
### Worker actions cheat sheet
|
|
@@ -258,6 +283,7 @@ graph-composer explain-basic
|
|
|
258
283
|
| `loadCatalogCandidatesFromCatalox`, `createCatalox`, `unifiedCatalogItemToSkillDescriptor`, … | Build `catalogCandidates` from **Catalox** catalogs; see [`docs/catalog-metadb-end-state-contract.md`](./docs/catalog-metadb-end-state-contract.md). |
|
|
259
284
|
| `reportTaskNodeProtocolGaps` | Offline list of **AI task** nodes violating **`taskConfiguration.aiTaskProfile`** (pre/post, **`webScoping.questions`** when enabled, **`inputSynthesis`** fields when synthesis is on). See `docs/task-node-execution-protocol.md`. |
|
|
260
285
|
| `collectCanonicalGraphWarnings` | Warn-first **`@exellix/graph-engine`** canonical checks (top-level keys, metadata placement, memory paths, model profile aliases). |
|
|
286
|
+
| `analyzeGraphModelLayers`, `stampGraphModelLayersOnGraph`, `graphModelLayerLegend` | **Model map** for AI nodes: which `@x12i/ai-profiles` names win (PRE/MAIN/POST), resolved provider ids, precedence layer + color stack — **model JSON only** unless you pass an explicit `runtime` overlay. Stamp with `stampGraphModelLayersOnGraph` before explain/UI. |
|
|
261
287
|
| `assertCanonicalGraphDocument` | Re-exported from graph-engine — **`validateCreateModifyOutput` hard-fails** when the canonicalized graph does not pass. |
|
|
262
288
|
| `GRAPH_ENGINE_MEMORY_PATH_ROOTS` | Re-exported memory path allowlist from graph-engine — use for validation parity, not a forked copy. |
|
|
263
289
|
| `WoroxScopingMapCatalogCreatePayload`, `WoroxScopedDataDocumentShape` | Host-side CRUD handoff (align field names with your persisted catalog / scoping schema). |
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonicalGraphDocument.d.ts","sourceRoot":"","sources":["../src/canonicalGraphDocument.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"canonicalGraphDocument.d.ts","sourceRoot":"","sources":["../src/canonicalGraphDocument.ts"],"names":[],"mappings":"AAAA;;GAEG;AAmbH,qFAAqF;AACrF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAc7E;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAiCtF;AAED,wBAAgB,6BAA6B,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAWpF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"canonicalGraphWarnings.d.ts","sourceRoot":"","sources":["../src/canonicalGraphWarnings.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"canonicalGraphWarnings.d.ts","sourceRoot":"","sources":["../src/canonicalGraphWarnings.ts"],"names":[],"mappings":"AAwIA;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAuHrE"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { type LogLevel, type Logxer } from "@x12i/logxer";
|
|
2
|
+
/** Canonical env prefix for graph-composer logs (`GRAPH_COMPOSER_LOGS_LEVEL`, …). */
|
|
3
|
+
export declare const GRAPH_COMPOSER_LOG_ENV_PREFIX = "GRAPH_COMPOSER";
|
|
4
|
+
export type { LogLevel };
|
|
5
|
+
/** Accepted inputs for `configureGraphComposerLogging` and `RunGraphComposerOptions.logsLevel`. */
|
|
6
|
+
export type GraphComposerLogsLevelInput = LogLevel | "off" | "none" | "silent" | (string & {});
|
|
7
|
+
export type GraphComposerLoggingConfig = {
|
|
8
|
+
/** Effective threshold after overrides (`off` when logging is disabled). */
|
|
9
|
+
logsLevel: LogLevel | "off";
|
|
10
|
+
/** True when package logging is silenced (`off` / `none` / `silent`). */
|
|
11
|
+
logsDisabled: boolean;
|
|
12
|
+
/** Whether `debug` (and `verbose`) lines are emitted. */
|
|
13
|
+
debugEnabled: boolean;
|
|
14
|
+
envKeys: {
|
|
15
|
+
canonical: string;
|
|
16
|
+
legacy: string;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Parse a log-level string (case-insensitive). Unknown values disable logging (`off`).
|
|
21
|
+
* Accepts logxer synonyms: `off`, `none`, `silent`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseGraphComposerLogsLevel(raw: string | undefined): {
|
|
24
|
+
logsLevel: LogLevel | "off";
|
|
25
|
+
logsDisabled: boolean;
|
|
26
|
+
};
|
|
27
|
+
/**
|
|
28
|
+
* Process-wide logging for graph-composer (downstream hosts, servers, CLIs).
|
|
29
|
+
*
|
|
30
|
+
* Precedence for each `runGraphComposer` / `runGraphComposerAgent` call:
|
|
31
|
+
* `options.logsLevel` → `configureGraphComposerLogging` → `GRAPH_COMPOSER_LOGS_LEVEL` env → default `warn`.
|
|
32
|
+
*/
|
|
33
|
+
export declare function configureGraphComposerLogging(options: {
|
|
34
|
+
logsLevel?: GraphComposerLogsLevelInput;
|
|
35
|
+
}): void;
|
|
36
|
+
/** Current effective logging configuration (after env + programmatic overrides). */
|
|
37
|
+
export declare function getGraphComposerLoggingConfig(perCall?: GraphComposerLogsLevelInput): GraphComposerLoggingConfig;
|
|
38
|
+
/** Shared @x12i/logxer instance for graph-composer (diagnostics catalog attached). */
|
|
39
|
+
export declare function getGraphComposerLogger(): Logxer;
|
|
40
|
+
/**
|
|
41
|
+
* Run `fn` with a temporary log threshold (`options.logsLevel` on workers).
|
|
42
|
+
* Restores the previous threshold when `fn` completes.
|
|
43
|
+
*/
|
|
44
|
+
export declare function withGraphComposerLogsLevel<T>(logsLevel: GraphComposerLogsLevelInput | undefined, fn: () => T | Promise<T>): Promise<T>;
|
|
45
|
+
//# sourceMappingURL=graphComposerLogging.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphComposerLogging.d.ts","sourceRoot":"","sources":["../src/graphComposerLogging.ts"],"names":[],"mappings":"AAEA,OAAO,EAML,KAAK,QAAQ,EACb,KAAK,MAAM,EACZ,MAAM,cAAc,CAAC;AAGtB,qFAAqF;AACrF,eAAO,MAAM,6BAA6B,mBAAmB,CAAC;AAE9D,YAAY,EAAE,QAAQ,EAAE,CAAC;AAEzB,mGAAmG;AACnG,MAAM,MAAM,2BAA2B,GACnC,QAAQ,GACR,KAAK,GACL,MAAM,GACN,QAAQ,GACR,CAAC,MAAM,GAAG,EAAE,CAAC,CAAC;AAElB,MAAM,MAAM,0BAA0B,GAAG;IACvC,4EAA4E;IAC5E,SAAS,EAAE,QAAQ,GAAG,KAAK,CAAC;IAC5B,yEAAyE;IACzE,YAAY,EAAE,OAAO,CAAC;IACtB,yDAAyD;IACzD,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAC;QAClB,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC;CACH,CAAC;AA+DF;;;GAGG;AACH,wBAAgB,2BAA2B,CACzC,GAAG,EAAE,MAAM,GAAG,SAAS,GACtB;IAAE,SAAS,EAAE,QAAQ,GAAG,KAAK,CAAC;IAAC,YAAY,EAAE,OAAO,CAAA;CAAE,CAMxD;AAoCD;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAAC,OAAO,EAAE;IACrD,SAAS,CAAC,EAAE,2BAA2B,CAAC;CACzC,GAAG,IAAI,CAMP;AAED,oFAAoF;AACpF,wBAAgB,6BAA6B,CAC3C,OAAO,CAAC,EAAE,2BAA2B,GACpC,0BAA0B,CAY5B;AAED,sFAAsF;AACtF,wBAAgB,sBAAsB,IAAI,MAAM,CAE/C;AAED;;;GAGG;AACH,wBAAsB,0BAA0B,CAAC,CAAC,EAChD,SAAS,EAAE,2BAA2B,GAAG,SAAS,EAClD,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,GACvB,OAAO,CAAC,CAAC,CAAC,CAYZ"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import { initConfig } from "@x12i/env";
|
|
3
|
+
import { createLogxer, legacyPackageLogLevelEnvKey, packageLogsLevelEnvKey, parsePackageLogsLevelString, resolvePackageLogsLevel, } from "@x12i/logxer";
|
|
4
|
+
import { graphComposerPackRoot } from "./packDir.js";
|
|
5
|
+
/** Canonical env prefix for graph-composer logs (`GRAPH_COMPOSER_LOGS_LEVEL`, …). */
|
|
6
|
+
export const GRAPH_COMPOSER_LOG_ENV_PREFIX = "GRAPH_COMPOSER";
|
|
7
|
+
// Load .env before Logxer reads MONGO_URI (and related vars) at construction.
|
|
8
|
+
initConfig({}, { dotenvPath: ".env", throwOnMissing: false });
|
|
9
|
+
const logger = createLogxer({
|
|
10
|
+
packageName: "graph-composer",
|
|
11
|
+
envPrefix: GRAPH_COMPOSER_LOG_ENV_PREFIX,
|
|
12
|
+
}, {
|
|
13
|
+
diagnostics: {
|
|
14
|
+
catalogPath: path.join(graphComposerPackRoot(), "metadata", "log-diagnostics.json"),
|
|
15
|
+
},
|
|
16
|
+
});
|
|
17
|
+
let processWideLogsLevel;
|
|
18
|
+
function logxerMutableConfig(logxer) {
|
|
19
|
+
return logxer.config;
|
|
20
|
+
}
|
|
21
|
+
function applyResolvedToLogger(resolved) {
|
|
22
|
+
const internal = logxerMutableConfig(logger);
|
|
23
|
+
const prev = {
|
|
24
|
+
logLevel: internal.logLevel,
|
|
25
|
+
packageLogsDisabled: internal.packageLogsDisabled,
|
|
26
|
+
};
|
|
27
|
+
internal.logLevel = resolved.logLevel;
|
|
28
|
+
internal.packageLogsDisabled = resolved.packageLogsDisabled;
|
|
29
|
+
return () => {
|
|
30
|
+
internal.logLevel = prev.logLevel;
|
|
31
|
+
internal.packageLogsDisabled = prev.packageLogsDisabled;
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const LOG_LEVELS = new Set([
|
|
35
|
+
"verbose",
|
|
36
|
+
"debug",
|
|
37
|
+
"info",
|
|
38
|
+
"warn",
|
|
39
|
+
"error",
|
|
40
|
+
]);
|
|
41
|
+
function isLogLevel(value) {
|
|
42
|
+
return LOG_LEVELS.has(value);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Parse a log-level string (case-insensitive). Unknown values disable logging (`off`).
|
|
46
|
+
* Accepts logxer synonyms: `off`, `none`, `silent`.
|
|
47
|
+
*/
|
|
48
|
+
export function parseGraphComposerLogsLevel(raw) {
|
|
49
|
+
const parsed = parsePackageLogsLevelString(raw);
|
|
50
|
+
if (parsed.packageLogsDisabled || parsed.logLevel === undefined) {
|
|
51
|
+
return { logsLevel: "off", logsDisabled: true };
|
|
52
|
+
}
|
|
53
|
+
return { logsLevel: parsed.logLevel, logsDisabled: false };
|
|
54
|
+
}
|
|
55
|
+
function resolveFromInput(input) {
|
|
56
|
+
if (input === "off" || input === "none" || input === "silent") {
|
|
57
|
+
return { packageLogsDisabled: true, logLevel: "error" };
|
|
58
|
+
}
|
|
59
|
+
if (typeof input === "string" && isLogLevel(input)) {
|
|
60
|
+
return { packageLogsDisabled: false, logLevel: input };
|
|
61
|
+
}
|
|
62
|
+
const parsed = parsePackageLogsLevelString(String(input));
|
|
63
|
+
if (parsed.packageLogsDisabled || parsed.logLevel === undefined) {
|
|
64
|
+
return { packageLogsDisabled: true, logLevel: "error" };
|
|
65
|
+
}
|
|
66
|
+
return { packageLogsDisabled: false, logLevel: parsed.logLevel };
|
|
67
|
+
}
|
|
68
|
+
function resolveGraphComposerLogsLevel(perCall) {
|
|
69
|
+
if (perCall !== undefined) {
|
|
70
|
+
return resolveFromInput(perCall);
|
|
71
|
+
}
|
|
72
|
+
if (processWideLogsLevel !== undefined) {
|
|
73
|
+
return resolveFromInput(processWideLogsLevel);
|
|
74
|
+
}
|
|
75
|
+
return resolvePackageLogsLevel({
|
|
76
|
+
envPrefix: GRAPH_COMPOSER_LOG_ENV_PREFIX,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
function syncLoggerToEffectiveLevel(perCall) {
|
|
80
|
+
applyResolvedToLogger(resolveGraphComposerLogsLevel(perCall));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Process-wide logging for graph-composer (downstream hosts, servers, CLIs).
|
|
84
|
+
*
|
|
85
|
+
* Precedence for each `runGraphComposer` / `runGraphComposerAgent` call:
|
|
86
|
+
* `options.logsLevel` → `configureGraphComposerLogging` → `GRAPH_COMPOSER_LOGS_LEVEL` env → default `warn`.
|
|
87
|
+
*/
|
|
88
|
+
export function configureGraphComposerLogging(options) {
|
|
89
|
+
if (options.logsLevel === undefined) {
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
processWideLogsLevel = options.logsLevel;
|
|
93
|
+
syncLoggerToEffectiveLevel();
|
|
94
|
+
}
|
|
95
|
+
/** Current effective logging configuration (after env + programmatic overrides). */
|
|
96
|
+
export function getGraphComposerLoggingConfig(perCall) {
|
|
97
|
+
const resolved = resolveGraphComposerLogsLevel(perCall);
|
|
98
|
+
const logsDisabled = resolved.packageLogsDisabled;
|
|
99
|
+
return {
|
|
100
|
+
logsLevel: logsDisabled ? "off" : resolved.logLevel,
|
|
101
|
+
logsDisabled,
|
|
102
|
+
debugEnabled: !logsDisabled && logger.isLevelEnabled("debug"),
|
|
103
|
+
envKeys: {
|
|
104
|
+
canonical: packageLogsLevelEnvKey(GRAPH_COMPOSER_LOG_ENV_PREFIX),
|
|
105
|
+
legacy: legacyPackageLogLevelEnvKey(GRAPH_COMPOSER_LOG_ENV_PREFIX),
|
|
106
|
+
},
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/** Shared @x12i/logxer instance for graph-composer (diagnostics catalog attached). */
|
|
110
|
+
export function getGraphComposerLogger() {
|
|
111
|
+
return logger;
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Run `fn` with a temporary log threshold (`options.logsLevel` on workers).
|
|
115
|
+
* Restores the previous threshold when `fn` completes.
|
|
116
|
+
*/
|
|
117
|
+
export async function withGraphComposerLogsLevel(logsLevel, fn) {
|
|
118
|
+
if (logsLevel === undefined) {
|
|
119
|
+
syncLoggerToEffectiveLevel();
|
|
120
|
+
return fn();
|
|
121
|
+
}
|
|
122
|
+
const restore = applyResolvedToLogger(resolveGraphComposerLogsLevel(logsLevel));
|
|
123
|
+
try {
|
|
124
|
+
return await fn();
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
restore();
|
|
128
|
+
syncLoggerToEffectiveLevel();
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
// Apply env / default level at module load (before first log line).
|
|
132
|
+
syncLoggerToEffectiveLevel();
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
* Re-exports from `@exellix/graph-engine` so hosts validate graphs with the same
|
|
3
3
|
* rules as runtime — do not fork gap codes or memory path allowlists here.
|
|
4
4
|
*/
|
|
5
|
-
export { assertCanonicalGraphDocument, getCanonicalGraphDocumentViolations, CANONICAL_GRAPH_TOP_LEVEL_KEYS, GRAPH_ENGINE_MEMORY_PATH_ROOTS, isAllowedGraphEngineMemoryPath, collectAiTasksNodeExtensionIssues, assertAiTasksNodeExtensionsValid, resolveGraphEngineMemoryPathValue, buildGraphEngineMemoryResolutionRootFromWorkingMemory, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, looksLikeConcreteModelId, isGraphAiProfileName, } from "@exellix/graph-engine";
|
|
5
|
+
export { assertCanonicalGraphDocument, getCanonicalGraphDocumentViolations, CANONICAL_GRAPH_TOP_LEVEL_KEYS, GRAPH_ENGINE_MEMORY_PATH_ROOTS, isAllowedGraphEngineMemoryPath, collectAiTasksNodeExtensionIssues, assertAiTasksNodeExtensionsValid, resolveGraphEngineMemoryPathValue, buildGraphEngineMemoryResolutionRootFromWorkingMemory, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, looksLikeConcreteModelId, isGraphAiProfileName, isGraphAiModelConfig, isModelConfigSelection, resolveGraphAiModelConfig, } from "@exellix/graph-engine";
|
|
6
6
|
export type { GraphEngineMemoryResolutionRoot } from "@exellix/graph-engine";
|
|
7
7
|
//# sourceMappingURL=graphEngineBridge.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"graphEngineBridge.d.ts","sourceRoot":"","sources":["../src/graphEngineBridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,4BAA4B,EAC5B,mCAAmC,EACnC,8BAA8B,EAC9B,8BAA8B,EAC9B,8BAA8B,EAC9B,iCAAiC,EACjC,gCAAgC,EAChC,iCAAiC,EACjC,qDAAqD,EACrD,qCAAqC,EACrC,wBAAwB,EACxB,oBAAoB,
|
|
1
|
+
{"version":3,"file":"graphEngineBridge.d.ts","sourceRoot":"","sources":["../src/graphEngineBridge.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,4BAA4B,EAC5B,mCAAmC,EACnC,8BAA8B,EAC9B,8BAA8B,EAC9B,8BAA8B,EAC9B,iCAAiC,EACjC,gCAAgC,EAChC,iCAAiC,EACjC,qDAAqD,EACrD,qCAAqC,EACrC,wBAAwB,EACxB,oBAAoB,EACpB,oBAAoB,EACpB,sBAAsB,EACtB,yBAAyB,GAC1B,MAAM,uBAAuB,CAAC;AAE/B,YAAY,EAAE,+BAA+B,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
* Re-exports from `@exellix/graph-engine` so hosts validate graphs with the same
|
|
3
3
|
* rules as runtime — do not fork gap codes or memory path allowlists here.
|
|
4
4
|
*/
|
|
5
|
-
export { assertCanonicalGraphDocument, getCanonicalGraphDocumentViolations, CANONICAL_GRAPH_TOP_LEVEL_KEYS, GRAPH_ENGINE_MEMORY_PATH_ROOTS, isAllowedGraphEngineMemoryPath, collectAiTasksNodeExtensionIssues, assertAiTasksNodeExtensionsValid, resolveGraphEngineMemoryPathValue, buildGraphEngineMemoryResolutionRootFromWorkingMemory, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, looksLikeConcreteModelId, isGraphAiProfileName, } from "@exellix/graph-engine";
|
|
5
|
+
export { assertCanonicalGraphDocument, getCanonicalGraphDocumentViolations, CANONICAL_GRAPH_TOP_LEVEL_KEYS, GRAPH_ENGINE_MEMORY_PATH_ROOTS, isAllowedGraphEngineMemoryPath, collectAiTasksNodeExtensionIssues, assertAiTasksNodeExtensionsValid, resolveGraphEngineMemoryPathValue, buildGraphEngineMemoryResolutionRootFromWorkingMemory, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, looksLikeConcreteModelId, isGraphAiProfileName, isGraphAiModelConfig, isModelConfigSelection, resolveGraphAiModelConfig, } from "@exellix/graph-engine";
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/** Precedence layer ids (lowest number = wins when present). Matches @exellix/graph-engine 7.2. */
|
|
2
|
+
export type GraphModelLayerSource = "runtime.nodes.modelConfig" | "node.taskConfiguration.modelConfig" | "runtime.modelConfig" | "graph.modelConfig" | "graph-engine.default";
|
|
3
|
+
export type GraphModelLayerPhase = "preActionModel" | "skillModel" | "postActionModel";
|
|
4
|
+
/** Same three slots as `GraphAiModelConfig` in @exellix/graph-engine (profile names or concrete ids). */
|
|
5
|
+
export type GraphModelProfilesTriple = {
|
|
6
|
+
preActionModel: string;
|
|
7
|
+
skillModel: string;
|
|
8
|
+
postActionModel: string;
|
|
9
|
+
};
|
|
10
|
+
export type GraphModelLayerStackEntry = {
|
|
11
|
+
/** Stable layer id for UI / explain output. */
|
|
12
|
+
source: GraphModelLayerSource;
|
|
13
|
+
/** Dot-path style location, e.g. `graph.modelConfig.cases[0]`. */
|
|
14
|
+
sourcePath: string;
|
|
15
|
+
/** Hex color for diagram overlays (stack order uses `layerOrder`). */
|
|
16
|
+
layerColor: string;
|
|
17
|
+
/** 1 = highest precedence (runtime node); 5 = engine default. */
|
|
18
|
+
layerOrder: number;
|
|
19
|
+
/** True when this layer is the effective winner for the node (model-only or with runtime). */
|
|
20
|
+
active: boolean;
|
|
21
|
+
profiles: GraphModelProfilesTriple;
|
|
22
|
+
/** Set when `profiles` were resolved through bundled @x12i/ai-profiles. */
|
|
23
|
+
providerIds?: GraphModelProfilesTriple;
|
|
24
|
+
/** Present when the tier uses conditional cases and no execution context was supplied. */
|
|
25
|
+
conditionalNote?: string;
|
|
26
|
+
};
|
|
27
|
+
export type NodeGraphModelLayers = {
|
|
28
|
+
nodeId: string;
|
|
29
|
+
skillKey: string;
|
|
30
|
+
winning: Pick<GraphModelLayerStackEntry, "source" | "sourcePath" | "layerColor" | "layerOrder" | "profiles" | "providerIds">;
|
|
31
|
+
/** All declared tiers on this graph/run (map layers), highest precedence first. */
|
|
32
|
+
stack: GraphModelLayerStackEntry[];
|
|
33
|
+
};
|
|
34
|
+
export type GraphModelLayersAnalysis = {
|
|
35
|
+
analyzedAt: string;
|
|
36
|
+
/** False when `runtime` was omitted — analysis reflects model JSON + engine default only. */
|
|
37
|
+
runtimeIncluded: boolean;
|
|
38
|
+
graphDefaultProfiles: GraphModelProfilesTriple;
|
|
39
|
+
graphDefaultProviderIds?: GraphModelProfilesTriple;
|
|
40
|
+
nodes: NodeGraphModelLayers[];
|
|
41
|
+
};
|
|
42
|
+
export type GraphModelLayersRuntimeOverlay = {
|
|
43
|
+
modelConfig?: unknown;
|
|
44
|
+
nodes?: Record<string, {
|
|
45
|
+
modelConfig?: unknown;
|
|
46
|
+
} | undefined>;
|
|
47
|
+
};
|
|
48
|
+
export type AnalyzeGraphModelLayersOptions = {
|
|
49
|
+
/**
|
|
50
|
+
* Optional runtime overlay. Omit to analyze **model-authored** config only (recommended).
|
|
51
|
+
* Do not inject `runtime.modelConfig` at execute time unless you intend to override the graph.
|
|
52
|
+
*/
|
|
53
|
+
runtime?: GraphModelLayersRuntimeOverlay;
|
|
54
|
+
utilitySkills?: Iterable<{
|
|
55
|
+
skillKey?: string;
|
|
56
|
+
}>;
|
|
57
|
+
extraLocalSkillKeys?: Iterable<string>;
|
|
58
|
+
};
|
|
59
|
+
/**
|
|
60
|
+
* Where runtime logs the resolved model (for operators debugging failed tasks):
|
|
61
|
+
* - `RunTaskRequest.modelConfig` (wire: `xynthesisModel` / `skillModel` per phase)
|
|
62
|
+
* - skill-executions / ai-actions / runTask diagnostics when level is not `basic`
|
|
63
|
+
* - `resolveCanonicalModelUsed(runTaskResponse)` after the call (authoritative provider id)
|
|
64
|
+
*
|
|
65
|
+
* This function answers the **authoring / planning** view from graph JSON (+ optional runtime overlay).
|
|
66
|
+
*/
|
|
67
|
+
export declare function analyzeGraphModelLayers(graph: object, options?: AnalyzeGraphModelLayersOptions): Promise<GraphModelLayersAnalysis>;
|
|
68
|
+
/** Profile accent color for UI badges (MAIN slot). */
|
|
69
|
+
export declare function graphModelProfileAccent(profileName: string): string;
|
|
70
|
+
/**
|
|
71
|
+
* Human-readable legend for diagram tools (source → color → meaning).
|
|
72
|
+
*/
|
|
73
|
+
export declare function graphModelLayerLegend(): Array<{
|
|
74
|
+
source: GraphModelLayerSource;
|
|
75
|
+
layerColor: string;
|
|
76
|
+
label: string;
|
|
77
|
+
layerOrder: number;
|
|
78
|
+
}>;
|
|
79
|
+
/**
|
|
80
|
+
* Stamp `metadata.graphModelLayers` on each AI task node (planning-only; not read by graph-engine).
|
|
81
|
+
* Does not mutate `runtime` and does not add runtime model overrides.
|
|
82
|
+
*/
|
|
83
|
+
export declare function stampGraphModelLayersOnGraph<T extends object>(graph: T, options?: AnalyzeGraphModelLayersOptions): Promise<T>;
|
|
84
|
+
/** Resolve a single profile name to provider/model id (for docs and explain text). */
|
|
85
|
+
export declare function resolveGraphModelProfileName(profileName: string): Promise<{
|
|
86
|
+
profile: string;
|
|
87
|
+
provider: string;
|
|
88
|
+
modelId: string;
|
|
89
|
+
formatted: string;
|
|
90
|
+
}>;
|
|
91
|
+
//# sourceMappingURL=graphModelLayers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"graphModelLayers.d.ts","sourceRoot":"","sources":["../src/graphModelLayers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model resolution map for worox graphs: which @x12i/ai-profiles names apply per AI node,
|
|
3
|
+
* which precedence layer wins, and resolved provider ids — without forcing runtime overrides.
|
|
4
|
+
*/
|
|
5
|
+
import { resolveAIProfile } from "@x12i/ai-profiles";
|
|
6
|
+
import { DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, isGraphAiModelConfig, isModelConfigSelection, resolveGraphAiModelConfig, } from "./graphEngineBridge.js";
|
|
7
|
+
import { DEFAULT_LOCAL_SKILL_KEYS } from "./aiTaskProfile.js";
|
|
8
|
+
const LAYER_META = {
|
|
9
|
+
"runtime.nodes.modelConfig": {
|
|
10
|
+
layerOrder: 1,
|
|
11
|
+
layerColor: "#dc2626",
|
|
12
|
+
label: "runtime node override",
|
|
13
|
+
},
|
|
14
|
+
"node.taskConfiguration.modelConfig": {
|
|
15
|
+
layerOrder: 2,
|
|
16
|
+
layerColor: "#ea580c",
|
|
17
|
+
label: "per-node model (graph)",
|
|
18
|
+
},
|
|
19
|
+
"runtime.modelConfig": {
|
|
20
|
+
layerOrder: 3,
|
|
21
|
+
layerColor: "#ca8a04",
|
|
22
|
+
label: "runtime graph override",
|
|
23
|
+
},
|
|
24
|
+
"graph.modelConfig": {
|
|
25
|
+
layerOrder: 4,
|
|
26
|
+
layerColor: "#2563eb",
|
|
27
|
+
label: "graph default model",
|
|
28
|
+
},
|
|
29
|
+
"graph-engine.default": {
|
|
30
|
+
layerOrder: 5,
|
|
31
|
+
layerColor: "#6b7280",
|
|
32
|
+
label: "engine default (@exellix/graph-engine)",
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
/** Distinct accent per profile name for MAIN slot badges in UIs. */
|
|
36
|
+
const PROFILE_ACCENT = {
|
|
37
|
+
cheap: "#16a34a",
|
|
38
|
+
balanced: "#2563eb",
|
|
39
|
+
deep: "#7c3aed",
|
|
40
|
+
strong: "#9333ea",
|
|
41
|
+
weak: "#84cc16",
|
|
42
|
+
};
|
|
43
|
+
function readRecord(v) {
|
|
44
|
+
if (v === null || v === undefined || typeof v !== "object" || Array.isArray(v)) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
return v;
|
|
48
|
+
}
|
|
49
|
+
function localSkillKeys(options) {
|
|
50
|
+
const s = new Set(DEFAULT_LOCAL_SKILL_KEYS);
|
|
51
|
+
for (const u of options?.utilitySkills ?? []) {
|
|
52
|
+
if (typeof u.skillKey === "string" && u.skillKey.trim() !== "") {
|
|
53
|
+
s.add(u.skillKey.trim());
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
for (const k of options?.extraLocalSkillKeys ?? []) {
|
|
57
|
+
if (typeof k === "string" && k.trim() !== "")
|
|
58
|
+
s.add(k.trim());
|
|
59
|
+
}
|
|
60
|
+
return s;
|
|
61
|
+
}
|
|
62
|
+
function describeModelConfigTier(value, basePath) {
|
|
63
|
+
if (isGraphAiModelConfig(value)) {
|
|
64
|
+
return { profiles: value, sourcePath: basePath };
|
|
65
|
+
}
|
|
66
|
+
if (!isModelConfigSelection(value)) {
|
|
67
|
+
return { sourcePath: basePath };
|
|
68
|
+
}
|
|
69
|
+
const cases = value.cases;
|
|
70
|
+
if (!Array.isArray(cases) || cases.length === 0) {
|
|
71
|
+
return { sourcePath: basePath, conditionalNote: "empty cases[]" };
|
|
72
|
+
}
|
|
73
|
+
const unconditional = cases.find((c) => c.when === undefined || c.when === null);
|
|
74
|
+
if (unconditional?.modelConfig && isGraphAiModelConfig(unconditional.modelConfig)) {
|
|
75
|
+
const idx = cases.indexOf(unconditional);
|
|
76
|
+
return {
|
|
77
|
+
profiles: unconditional.modelConfig,
|
|
78
|
+
sourcePath: `${basePath}.cases[${idx}]`,
|
|
79
|
+
conditionalNote: cases.length > 1
|
|
80
|
+
? "static analysis uses default case (no when); other cases need runtime gates"
|
|
81
|
+
: undefined,
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
const first = cases[0];
|
|
85
|
+
if (first?.modelConfig && isGraphAiModelConfig(first.modelConfig)) {
|
|
86
|
+
return {
|
|
87
|
+
profiles: first.modelConfig,
|
|
88
|
+
sourcePath: `${basePath}.cases[0]`,
|
|
89
|
+
conditionalNote: "no unconditional case — showing cases[0] only; runtime may pick another",
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
return { sourcePath: basePath, conditionalNote: "could not read modelConfig from cases" };
|
|
93
|
+
}
|
|
94
|
+
async function resolveProviderTriple(profiles, context) {
|
|
95
|
+
return resolveGraphAiModelConfig(profiles, context);
|
|
96
|
+
}
|
|
97
|
+
function buildStackEntry(source, sourcePath, profiles, active, conditionalNote, providerIds) {
|
|
98
|
+
if (profiles === undefined)
|
|
99
|
+
return undefined;
|
|
100
|
+
const meta = LAYER_META[source];
|
|
101
|
+
return {
|
|
102
|
+
source,
|
|
103
|
+
sourcePath,
|
|
104
|
+
layerColor: meta.layerColor,
|
|
105
|
+
layerOrder: meta.layerOrder,
|
|
106
|
+
active,
|
|
107
|
+
profiles,
|
|
108
|
+
...(providerIds !== undefined ? { providerIds } : {}),
|
|
109
|
+
...(conditionalNote !== undefined ? { conditionalNote } : {}),
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
async function resolveWinningTier(tiers) {
|
|
113
|
+
for (const tier of tiers) {
|
|
114
|
+
const described = describeModelConfigTier(tier.value, tier.basePath);
|
|
115
|
+
if (described.profiles !== undefined) {
|
|
116
|
+
return {
|
|
117
|
+
source: tier.source,
|
|
118
|
+
sourcePath: described.sourcePath,
|
|
119
|
+
profiles: described.profiles,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return {
|
|
124
|
+
source: "graph-engine.default",
|
|
125
|
+
sourcePath: "@exellix/graph-engine DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG",
|
|
126
|
+
profiles: { ...DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG },
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Where runtime logs the resolved model (for operators debugging failed tasks):
|
|
131
|
+
* - `RunTaskRequest.modelConfig` (wire: `xynthesisModel` / `skillModel` per phase)
|
|
132
|
+
* - skill-executions / ai-actions / runTask diagnostics when level is not `basic`
|
|
133
|
+
* - `resolveCanonicalModelUsed(runTaskResponse)` after the call (authoritative provider id)
|
|
134
|
+
*
|
|
135
|
+
* This function answers the **authoring / planning** view from graph JSON (+ optional runtime overlay).
|
|
136
|
+
*/
|
|
137
|
+
export async function analyzeGraphModelLayers(graph, options) {
|
|
138
|
+
const g = graph;
|
|
139
|
+
const graphId = typeof g.id === "string" ? g.id : undefined;
|
|
140
|
+
const runtime = options?.runtime;
|
|
141
|
+
const runtimeIncluded = runtime !== undefined;
|
|
142
|
+
const locals = localSkillKeys(options);
|
|
143
|
+
const graphTier = describeModelConfigTier(g.modelConfig, "graph.modelConfig");
|
|
144
|
+
const graphDefaultProfiles = graphTier.profiles ?? { ...DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG };
|
|
145
|
+
const graphDefaultProviderIds = await resolveProviderTriple(graphDefaultProfiles, {
|
|
146
|
+
graphId,
|
|
147
|
+
});
|
|
148
|
+
const nodes = [];
|
|
149
|
+
const nodeList = g.nodes;
|
|
150
|
+
if (!Array.isArray(nodeList)) {
|
|
151
|
+
return {
|
|
152
|
+
analyzedAt: new Date().toISOString(),
|
|
153
|
+
runtimeIncluded,
|
|
154
|
+
graphDefaultProfiles,
|
|
155
|
+
graphDefaultProviderIds,
|
|
156
|
+
nodes,
|
|
157
|
+
};
|
|
158
|
+
}
|
|
159
|
+
for (const n of nodeList) {
|
|
160
|
+
const node = readRecord(n);
|
|
161
|
+
if (node === undefined)
|
|
162
|
+
continue;
|
|
163
|
+
if (node.type !== undefined && node.type !== "task")
|
|
164
|
+
continue;
|
|
165
|
+
const nodeId = typeof node.id === "string" ? node.id : "";
|
|
166
|
+
const skillKey = typeof node.skillKey === "string" ? node.skillKey.trim() : "";
|
|
167
|
+
if (nodeId === "" || skillKey === "" || locals.has(skillKey))
|
|
168
|
+
continue;
|
|
169
|
+
const tc = readRecord(node.taskConfiguration);
|
|
170
|
+
const runtimeNode = runtime?.nodes?.[nodeId];
|
|
171
|
+
const runtimeNodeMc = readRecord(runtimeNode)?.modelConfig;
|
|
172
|
+
const tiers = [];
|
|
173
|
+
if (runtimeIncluded && runtimeNodeMc !== undefined) {
|
|
174
|
+
tiers.push({
|
|
175
|
+
source: "runtime.nodes.modelConfig",
|
|
176
|
+
basePath: `runtime.nodes["${nodeId}"].modelConfig`,
|
|
177
|
+
value: runtimeNodeMc,
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
if (tc?.modelConfig !== undefined) {
|
|
181
|
+
tiers.push({
|
|
182
|
+
source: "node.taskConfiguration.modelConfig",
|
|
183
|
+
basePath: `nodes["${nodeId}"].taskConfiguration.modelConfig`,
|
|
184
|
+
value: tc.modelConfig,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
if (runtimeIncluded && runtime?.modelConfig !== undefined) {
|
|
188
|
+
tiers.push({
|
|
189
|
+
source: "runtime.modelConfig",
|
|
190
|
+
basePath: "runtime.modelConfig",
|
|
191
|
+
value: runtime.modelConfig,
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
if (g.modelConfig !== undefined) {
|
|
195
|
+
tiers.push({
|
|
196
|
+
source: "graph.modelConfig",
|
|
197
|
+
basePath: "graph.modelConfig",
|
|
198
|
+
value: g.modelConfig,
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
const winning = await resolveWinningTier(tiers);
|
|
202
|
+
const winningProviderIds = await resolveProviderTriple(winning.profiles, {
|
|
203
|
+
graphId,
|
|
204
|
+
nodeId,
|
|
205
|
+
});
|
|
206
|
+
const stack = [];
|
|
207
|
+
const pushTier = async (tier) => {
|
|
208
|
+
const described = describeModelConfigTier(tier.value, tier.basePath);
|
|
209
|
+
if (described.profiles === undefined)
|
|
210
|
+
return;
|
|
211
|
+
const providerIds = await resolveProviderTriple(described.profiles, {
|
|
212
|
+
graphId,
|
|
213
|
+
nodeId,
|
|
214
|
+
});
|
|
215
|
+
const entry = buildStackEntry(tier.source, described.sourcePath, described.profiles, tier.source === winning.source && described.sourcePath === winning.sourcePath, described.conditionalNote, providerIds);
|
|
216
|
+
if (entry !== undefined)
|
|
217
|
+
stack.push(entry);
|
|
218
|
+
};
|
|
219
|
+
for (const tier of tiers) {
|
|
220
|
+
await pushTier(tier);
|
|
221
|
+
}
|
|
222
|
+
const defaultEntry = buildStackEntry("graph-engine.default", "@exellix/graph-engine DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG", { ...DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG }, winning.source === "graph-engine.default", tiers.length === 0
|
|
223
|
+
? "no modelConfig on graph or node — engine default applies"
|
|
224
|
+
: undefined, await resolveProviderTriple(DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, { graphId, nodeId }));
|
|
225
|
+
if (defaultEntry !== undefined) {
|
|
226
|
+
stack.push(defaultEntry);
|
|
227
|
+
}
|
|
228
|
+
stack.sort((a, b) => a.layerOrder - b.layerOrder);
|
|
229
|
+
nodes.push({
|
|
230
|
+
nodeId,
|
|
231
|
+
skillKey,
|
|
232
|
+
winning: {
|
|
233
|
+
source: winning.source,
|
|
234
|
+
sourcePath: winning.sourcePath,
|
|
235
|
+
layerColor: LAYER_META[winning.source].layerColor,
|
|
236
|
+
layerOrder: LAYER_META[winning.source].layerOrder,
|
|
237
|
+
profiles: winning.profiles,
|
|
238
|
+
providerIds: winningProviderIds,
|
|
239
|
+
},
|
|
240
|
+
stack,
|
|
241
|
+
});
|
|
242
|
+
}
|
|
243
|
+
return {
|
|
244
|
+
analyzedAt: new Date().toISOString(),
|
|
245
|
+
runtimeIncluded,
|
|
246
|
+
graphDefaultProfiles,
|
|
247
|
+
graphDefaultProviderIds,
|
|
248
|
+
nodes,
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
/** Profile accent color for UI badges (MAIN slot). */
|
|
252
|
+
export function graphModelProfileAccent(profileName) {
|
|
253
|
+
const key = profileName.trim().toLowerCase();
|
|
254
|
+
return PROFILE_ACCENT[key] ?? "#64748b";
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Human-readable legend for diagram tools (source → color → meaning).
|
|
258
|
+
*/
|
|
259
|
+
export function graphModelLayerLegend() {
|
|
260
|
+
return Object.keys(LAYER_META).map((source) => ({
|
|
261
|
+
source,
|
|
262
|
+
...LAYER_META[source],
|
|
263
|
+
}));
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Stamp `metadata.graphModelLayers` on each AI task node (planning-only; not read by graph-engine).
|
|
267
|
+
* Does not mutate `runtime` and does not add runtime model overrides.
|
|
268
|
+
*/
|
|
269
|
+
export async function stampGraphModelLayersOnGraph(graph, options) {
|
|
270
|
+
const analysis = await analyzeGraphModelLayers(graph, options);
|
|
271
|
+
const g = graph;
|
|
272
|
+
const byId = new Map(analysis.nodes.map((n) => [n.nodeId, n]));
|
|
273
|
+
const nodes = g.nodes;
|
|
274
|
+
if (!Array.isArray(nodes))
|
|
275
|
+
return graph;
|
|
276
|
+
for (const n of nodes) {
|
|
277
|
+
const node = readRecord(n);
|
|
278
|
+
if (node === undefined)
|
|
279
|
+
continue;
|
|
280
|
+
const nodeId = typeof node.id === "string" ? node.id : "";
|
|
281
|
+
const layer = byId.get(nodeId);
|
|
282
|
+
if (layer === undefined)
|
|
283
|
+
continue;
|
|
284
|
+
const meta = { ...readRecord(node.metadata) };
|
|
285
|
+
meta.graphModelLayers = {
|
|
286
|
+
...layer,
|
|
287
|
+
profileAccents: {
|
|
288
|
+
preActionModel: graphModelProfileAccent(layer.winning.profiles.preActionModel),
|
|
289
|
+
skillModel: graphModelProfileAccent(layer.winning.profiles.skillModel),
|
|
290
|
+
postActionModel: graphModelProfileAccent(layer.winning.profiles.postActionModel),
|
|
291
|
+
},
|
|
292
|
+
legend: graphModelLayerLegend(),
|
|
293
|
+
};
|
|
294
|
+
node.metadata = meta;
|
|
295
|
+
}
|
|
296
|
+
const rootMeta = { ...readRecord(g.metadata) };
|
|
297
|
+
rootMeta.graphModelLayersSummary = {
|
|
298
|
+
analyzedAt: analysis.analyzedAt,
|
|
299
|
+
runtimeIncluded: analysis.runtimeIncluded,
|
|
300
|
+
legend: graphModelLayerLegend(),
|
|
301
|
+
graphDefault: {
|
|
302
|
+
profiles: analysis.graphDefaultProfiles,
|
|
303
|
+
providerIds: analysis.graphDefaultProviderIds,
|
|
304
|
+
},
|
|
305
|
+
note: "Planning overlay only. At execute time @exellix/graph-engine resolves modelConfig (runtime.nodes → node → runtime → graph → default), then @x12i/ai-profiles maps profile names to provider ids. Omit runtime.modelConfig unless you intend to override the graph.",
|
|
306
|
+
};
|
|
307
|
+
g.metadata = rootMeta;
|
|
308
|
+
return graph;
|
|
309
|
+
}
|
|
310
|
+
/** Resolve a single profile name to provider/model id (for docs and explain text). */
|
|
311
|
+
export async function resolveGraphModelProfileName(profileName) {
|
|
312
|
+
const resolved = await resolveAIProfile(profileName.trim(), { source: "bundled" });
|
|
313
|
+
const formatted = resolved.modelId.includes("/")
|
|
314
|
+
? resolved.modelId
|
|
315
|
+
: `${resolved.provider}/${resolved.modelId}`;
|
|
316
|
+
return {
|
|
317
|
+
profile: resolved.profile,
|
|
318
|
+
provider: resolved.provider,
|
|
319
|
+
modelId: resolved.modelId,
|
|
320
|
+
formatted,
|
|
321
|
+
};
|
|
322
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,8 @@ export { GRAPH_COMPOSER_ACTION_REGISTRY, getActionDefinition, getActionDefinitio
|
|
|
3
3
|
export { graphComposerPackRoot, readGraphComposerPromptFile, } from "./packDir.js";
|
|
4
4
|
export { DEFAULT_UTILITY_SKILLS } from "./defaultUtilitySkills.js";
|
|
5
5
|
export { runGraphComposer, runGraphWorker, resolveGraphComposerClient, getGraphComposerLlmClient, getPackDir, normalizeGraphComposerExplainOutput, normalizeReviewConceptComposerOutput, redactSecretsForLog, type RunGraphComposerOptions, } from "./runGraphComposer.js";
|
|
6
|
+
export type { LogRuntimeContext, LogLevel } from "@x12i/logxer";
|
|
7
|
+
export { GRAPH_COMPOSER_LOG_ENV_PREFIX, configureGraphComposerLogging, getGraphComposerLogger, getGraphComposerLoggingConfig, parseGraphComposerLogsLevel, withGraphComposerLogsLevel, type GraphComposerLoggingConfig, type GraphComposerLogsLevelInput, } from "./graphComposerLogging.js";
|
|
6
8
|
export { applyGraphConceptPatchOnlyIfEmpty } from "./graphConceptPatchMerge.js";
|
|
7
9
|
export { runGraphComposerAgent, type GraphComposerAgentResult, type GraphComposerAgentOrchestrationStep, type RunGraphComposerAgentOptions, } from "./graphComposerAgent.js";
|
|
8
10
|
export type { GraphComposerInput, GraphComposerAgentInput, GraphComposerIntent, GraphComposerConstraints, SkillDescriptor, PrimaryIntentType, GraphConceptStatus, GraphConceptEntityBindings, GraphConceptPatch, GraphConceptPatchKey, GraphConceptRequirementsPatch, GraphConceptCoreTaskPatchItem, RequirementOptionCandidate, RequirementOptionEntry, CatalogCandidates, ScopingMapCandidate, NarrixTemplateCandidate, } from "./types.js";
|
|
@@ -17,6 +19,7 @@ export type { ParsedGraphConcept } from "./parseGraphConceptStory.js";
|
|
|
17
19
|
export { reportTaskNodeProtocolGaps, DEFAULT_LOCAL_SKILL_KEYS, type AiTaskProfileMetadata, type TaskNodeProtocolGap, type TaskNodeProtocolIssueCode, type WebScopingNodeConfig, type InputSynthesisNodeConfig, type InputSynthesisDestination, } from "./aiTaskProfile.js";
|
|
18
20
|
export { assertCanonicalGraphDocument, getCanonicalGraphDocumentViolations, CANONICAL_GRAPH_TOP_LEVEL_KEYS, GRAPH_ENGINE_MEMORY_PATH_ROOTS, isAllowedGraphEngineMemoryPath, collectAiTasksNodeExtensionIssues, assertAiTasksNodeExtensionsValid, resolveGraphEngineMemoryPathValue, buildGraphEngineMemoryResolutionRootFromWorkingMemory, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, looksLikeConcreteModelId, isGraphAiProfileName, type GraphEngineMemoryResolutionRoot, } from "./graphEngineBridge.js";
|
|
19
21
|
export { collectCanonicalGraphWarnings } from "./canonicalGraphWarnings.js";
|
|
22
|
+
export { analyzeGraphModelLayers, stampGraphModelLayersOnGraph, graphModelLayerLegend, graphModelProfileAccent, resolveGraphModelProfileName, type AnalyzeGraphModelLayersOptions, type GraphModelLayerPhase, type GraphModelLayerSource, type GraphModelLayerStackEntry, type GraphModelLayersAnalysis, type GraphModelLayersRuntimeOverlay, type GraphModelProfilesTriple, type NodeGraphModelLayers, } from "./graphModelLayers.js";
|
|
20
23
|
export { resolveTaskNodeInputs, resolveTaskNodeInputsConfig, resolveTaskNodeTaskVariable, canonicalizeGraphTaskNodeTaskVariable, canonicalizeGraphModel, reportTaskNodeInputsLayoutIssues, taskNodeInputsLayoutWarningMessage, isTaskVariablePathRef, isTaskNode, isFinalizerNode, type TaskNodeInputsLayoutIssue, type TaskNodeInputsLayoutIssueCode, } from "./taskNodeTaskVariable.js";
|
|
21
24
|
export { createCatalox, bindCataloxContext, Catalox, CataloxBound, } from "@x12i/catalox/embedder";
|
|
22
25
|
export type { CataloxContext, CataloxRuntimeConfig, } from "@x12i/catalox/embedder";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export { GRAPH_COMPOSER_ACTION_REGISTRY, getActionDefinition, getActionDefinitio
|
|
|
3
3
|
export { graphComposerPackRoot, readGraphComposerPromptFile, } from "./packDir.js";
|
|
4
4
|
export { DEFAULT_UTILITY_SKILLS } from "./defaultUtilitySkills.js";
|
|
5
5
|
export { runGraphComposer, runGraphWorker, resolveGraphComposerClient, getGraphComposerLlmClient, getPackDir, normalizeGraphComposerExplainOutput, normalizeReviewConceptComposerOutput, redactSecretsForLog, } from "./runGraphComposer.js";
|
|
6
|
+
export { GRAPH_COMPOSER_LOG_ENV_PREFIX, configureGraphComposerLogging, getGraphComposerLogger, getGraphComposerLoggingConfig, parseGraphComposerLogsLevel, withGraphComposerLogsLevel, } from "./graphComposerLogging.js";
|
|
6
7
|
export { applyGraphConceptPatchOnlyIfEmpty } from "./graphConceptPatchMerge.js";
|
|
7
8
|
export { runGraphComposerAgent, } from "./graphComposerAgent.js";
|
|
8
9
|
export { buildCatalogMatchHints, } from "./catalogMatchAssist.js";
|
|
@@ -14,6 +15,7 @@ export { parseGraphConceptStory, parseGraphConceptStoryBody, isGraphConceptStory
|
|
|
14
15
|
export { reportTaskNodeProtocolGaps, DEFAULT_LOCAL_SKILL_KEYS, } from "./aiTaskProfile.js";
|
|
15
16
|
export { assertCanonicalGraphDocument, getCanonicalGraphDocumentViolations, CANONICAL_GRAPH_TOP_LEVEL_KEYS, GRAPH_ENGINE_MEMORY_PATH_ROOTS, isAllowedGraphEngineMemoryPath, collectAiTasksNodeExtensionIssues, assertAiTasksNodeExtensionsValid, resolveGraphEngineMemoryPathValue, buildGraphEngineMemoryResolutionRootFromWorkingMemory, DEFAULT_GRAPH_AI_MODEL_PROFILE_CONFIG, looksLikeConcreteModelId, isGraphAiProfileName, } from "./graphEngineBridge.js";
|
|
16
17
|
export { collectCanonicalGraphWarnings } from "./canonicalGraphWarnings.js";
|
|
18
|
+
export { analyzeGraphModelLayers, stampGraphModelLayersOnGraph, graphModelLayerLegend, graphModelProfileAccent, resolveGraphModelProfileName, } from "./graphModelLayers.js";
|
|
17
19
|
export { resolveTaskNodeInputs, resolveTaskNodeInputsConfig, resolveTaskNodeTaskVariable, canonicalizeGraphTaskNodeTaskVariable, canonicalizeGraphModel, reportTaskNodeInputsLayoutIssues, taskNodeInputsLayoutWarningMessage, isTaskVariablePathRef, isTaskNode, isFinalizerNode, } from "./taskNodeTaskVariable.js";
|
|
18
20
|
export { createCatalox, bindCataloxContext, Catalox, CataloxBound, } from "@x12i/catalox/embedder";
|
|
19
21
|
export { loadCatalogCandidatesFromCatalox, unifiedCatalogItemToSkillDescriptor, unifiedCatalogItemToScopingMapCandidate, unifiedCatalogItemToNarrixTemplateCandidate, } from "./cataloxCatalogBridge.js";
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type LogRuntimeContext } from "@x12i/logxer";
|
|
2
|
+
import { type GraphComposerLogsLevelInput } from "./graphComposerLogging.js";
|
|
1
3
|
import type { Client } from "@x12i/funcx";
|
|
2
4
|
import { type LlmMode } from "@x12i/funcx/functions";
|
|
3
5
|
import type { GraphComposerInput } from "./types.js";
|
|
@@ -34,9 +36,19 @@ export type RunGraphComposerOptions = {
|
|
|
34
36
|
maxTokens?: number;
|
|
35
37
|
/**
|
|
36
38
|
* When true, `reviewConcept` logs redacted serialized request and raw LLM result at `info`.
|
|
37
|
-
* When false (default), the same traces use `debug` (enable via `
|
|
39
|
+
* When false (default), the same traces use `debug` (enable via `logsLevel: "debug"` or env).
|
|
38
40
|
*/
|
|
39
41
|
traceReviewConceptIo?: boolean;
|
|
42
|
+
/**
|
|
43
|
+
* Per-call log threshold. Wins over `configureGraphComposerLogging` and env for this run only.
|
|
44
|
+
* Use `off` / `none` / `silent` to silence graph-composer logs for one invocation.
|
|
45
|
+
*/
|
|
46
|
+
logsLevel?: GraphComposerLogsLevelInput;
|
|
47
|
+
/**
|
|
48
|
+
* Optional correlation ids merged into every log via @x12i/logxer `runWithLogContext`
|
|
49
|
+
* (jobId, runId, graphId, nodeId, taskId, sessionId, correlationId).
|
|
50
|
+
*/
|
|
51
|
+
logContext?: LogRuntimeContext;
|
|
40
52
|
};
|
|
41
53
|
export declare function resolveGraphComposerClient(options: RunGraphComposerOptions): Client | undefined;
|
|
42
54
|
/**
|
|
@@ -44,10 +56,6 @@ export declare function resolveGraphComposerClient(options: RunGraphComposerOpti
|
|
|
44
56
|
* Unlike `resolveGraphComposerClient`, this always returns a `Client` when OpenRouter is configured.
|
|
45
57
|
*/
|
|
46
58
|
export declare function getGraphComposerLlmClient(options?: RunGraphComposerOptions): Client;
|
|
47
|
-
/**
|
|
48
|
-
* Run a single graph-composer worker (`intent.action`) with the per-action system prompt.
|
|
49
|
-
* Shared by `runGraphComposer` and `runGraphComposerAgent`.
|
|
50
|
-
*/
|
|
51
59
|
export declare function runGraphWorker(input: GraphComposerInput, options?: RunGraphComposerOptions): Promise<unknown>;
|
|
52
60
|
export declare function runGraphComposer(input: GraphComposerInput, options?: RunGraphComposerOptions): Promise<unknown>;
|
|
53
61
|
export declare function getPackDir(): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runGraphComposer.d.ts","sourceRoot":"","sources":["../src/runGraphComposer.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"runGraphComposer.d.ts","sourceRoot":"","sources":["../src/runGraphComposer.ts"],"names":[],"mappings":"AAEA,OAAO,EAKL,KAAK,iBAAiB,EACvB,MAAM,cAAc,CAAC;AACtB,OAAO,EAGL,KAAK,2BAA2B,EACjC,MAAM,2BAA2B,CAAC;AAEnC,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAC1C,OAAO,EAIL,KAAK,OAAO,EACb,MAAM,uBAAuB,CAAC;AAc/B,OAAO,KAAK,EAAE,kBAAkB,EAAmB,MAAM,YAAY,CAAC;AAEtE,OAAO,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAGxD,OAAO,EAAE,mBAAmB,EAAE,CAAC;AAC/B,OAAO,EAAE,iCAAiC,EAAE,MAAM,6BAA6B,CAAC;AAgHhF;;;GAGG;AACH,wBAAgB,oCAAoC,CAClD,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC3B,IAAI,CASN;AAuDD;;GAEG;AACH,wBAAgB,mCAAmC,CACjD,MAAM,EAAE,OAAO,GACd,OAAO,CAKT;AA0ED,MAAM,MAAM,uBAAuB,GAAG;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;OAGG;IACH,uBAAuB,CAAC,EAAE,OAAO,CAAC;IAClC,2FAA2F;IAC3F,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B;;;OAGG;IACH,SAAS,CAAC,EAAE,2BAA2B,CAAC;IACxC;;;OAGG;IACH,UAAU,CAAC,EAAE,iBAAiB,CAAC;CAChC,CAAC;AAmDF,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,uBAAuB,GAC/B,MAAM,GAAG,SAAS,CA4BpB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,GAAE,uBAA4B,GACpC,MAAM,CAYR;AAqLD,wBAAsB,cAAc,CAClC,KAAK,EAAE,kBAAkB,EACzB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,OAAO,CAAC,CAQlB;AAED,wBAAsB,gBAAgB,CACpC,KAAK,EAAE,kBAAkB,EACzB,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,OAAO,CAAC,CAElB;AAED,wBAAgB,UAAU,IAAI,MAAM,CAEnC"}
|
package/dist/runGraphComposer.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { readFileSync, existsSync } from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { DebugLogAbstract, exceptionEvidence, fieldEvidence, runWithLogContext, } from "@x12i/logxer";
|
|
4
|
+
import { getGraphComposerLogger, withGraphComposerLogsLevel, } from "./graphComposerLogging.js";
|
|
5
5
|
import { createClient } from "@x12i/funcx";
|
|
6
6
|
import { buildRequestPrompt, executeFuncx as invokeFuncxPack, } from "@x12i/funcx/functions";
|
|
7
7
|
import { composeWorkerInstructions } from "./composeInstructions.js";
|
|
@@ -33,12 +33,7 @@ function processSuggestConceptObjectiveOutput(shaped, intent, existingGraph) {
|
|
|
33
33
|
typeof r === "string" && r.trim().length > 0 ? `${prefix} ${r}` : prefix;
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
-
|
|
37
|
-
initConfig({}, { dotenvPath: ".env", throwOnMissing: false });
|
|
38
|
-
const logger = createLogxer({
|
|
39
|
-
packageName: "graph-composer",
|
|
40
|
-
envPrefix: "GRAPH_COMPOSER",
|
|
41
|
-
});
|
|
36
|
+
const logger = getGraphComposerLogger();
|
|
42
37
|
let cachedRules = null;
|
|
43
38
|
function loadRules() {
|
|
44
39
|
if (cachedRules !== null)
|
|
@@ -253,6 +248,9 @@ function logReviewConceptIo(phase, data, traceReviewConceptIo) {
|
|
|
253
248
|
const payload = safeJsonStringifyForLog(redacted);
|
|
254
249
|
const msg = `graph-composer reviewConcept ${phase}`;
|
|
255
250
|
const meta = {
|
|
251
|
+
phase,
|
|
252
|
+
debugKind: DebugLogAbstract.STATE,
|
|
253
|
+
evidence: [fieldEvidence("payloadCharLength", payload.length)],
|
|
256
254
|
payloadCharLength: payload.length,
|
|
257
255
|
payload,
|
|
258
256
|
};
|
|
@@ -324,7 +322,7 @@ function buildGraphComposerPrompt(request) {
|
|
|
324
322
|
* Run a single graph-composer worker (`intent.action`) with the per-action system prompt.
|
|
325
323
|
* Shared by `runGraphComposer` and `runGraphComposerAgent`.
|
|
326
324
|
*/
|
|
327
|
-
|
|
325
|
+
async function runGraphWorkerInner(input, options) {
|
|
328
326
|
assertInputShape(input);
|
|
329
327
|
const normalized = normalizeInput(input);
|
|
330
328
|
const action = normalized.intent.action;
|
|
@@ -391,6 +389,7 @@ export async function runGraphWorker(input, options = {}) {
|
|
|
391
389
|
aiSkillCount: normalized.aiSkills.length,
|
|
392
390
|
utilitySkillCount: normalized.utilitySkills.length,
|
|
393
391
|
composedInstructionChars: system.length,
|
|
392
|
+
debugKind: DebugLogAbstract.EVENT,
|
|
394
393
|
});
|
|
395
394
|
const mode = options.mode ?? "strong";
|
|
396
395
|
try {
|
|
@@ -425,17 +424,43 @@ export async function runGraphWorker(input, options = {}) {
|
|
|
425
424
|
});
|
|
426
425
|
}
|
|
427
426
|
}
|
|
428
|
-
logger.info("graph-composer worker complete", {
|
|
427
|
+
logger.info("graph-composer worker complete", {
|
|
428
|
+
action,
|
|
429
|
+
debugKind: DebugLogAbstract.EVENT,
|
|
430
|
+
});
|
|
429
431
|
return shaped;
|
|
430
432
|
}
|
|
431
433
|
catch (e) {
|
|
432
|
-
|
|
434
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
435
|
+
logger.errorCode("GRAPH_COMPOSER_WORKER_FAILED", {
|
|
433
436
|
action,
|
|
434
|
-
|
|
437
|
+
error: e,
|
|
438
|
+
debugKind: DebugLogAbstract.ANOMALY,
|
|
439
|
+
evidence: [
|
|
440
|
+
exceptionEvidence(e),
|
|
441
|
+
fieldEvidence("intent.action", action),
|
|
442
|
+
],
|
|
443
|
+
diagnostics: {
|
|
444
|
+
expected: "The graph-composer worker should complete and return validated output.",
|
|
445
|
+
actual: message,
|
|
446
|
+
impact: "The requested graph-composer action did not complete; callers receive no result.",
|
|
447
|
+
retryable: true,
|
|
448
|
+
userActionRequired: false,
|
|
449
|
+
confidence: "medium",
|
|
450
|
+
},
|
|
435
451
|
});
|
|
436
452
|
throw e;
|
|
437
453
|
}
|
|
438
454
|
}
|
|
455
|
+
export async function runGraphWorker(input, options = {}) {
|
|
456
|
+
return withGraphComposerLogsLevel(options.logsLevel, async () => {
|
|
457
|
+
const ctx = options.logContext;
|
|
458
|
+
if (ctx !== undefined && Object.keys(ctx).length > 0) {
|
|
459
|
+
return runWithLogContext(ctx, () => runGraphWorkerInner(input, options));
|
|
460
|
+
}
|
|
461
|
+
return runGraphWorkerInner(input, options);
|
|
462
|
+
});
|
|
463
|
+
}
|
|
439
464
|
export async function runGraphComposer(input, options = {}) {
|
|
440
465
|
return runGraphWorker(input, options);
|
|
441
466
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"GRAPH_COMPOSER_WORKER_FAILED": {
|
|
3
|
+
"defaultLevel": "error",
|
|
4
|
+
"title": "Graph composer worker failed",
|
|
5
|
+
"impact": "The requested graph-composer action did not complete; callers receive no result.",
|
|
6
|
+
"possibleCauses": [
|
|
7
|
+
"OpenRouter or @x12i/funcx returned an error or timed out.",
|
|
8
|
+
"Model output failed action-specific validation.",
|
|
9
|
+
"Missing or invalid input (existingGraph, catalogCandidates, etc.)."
|
|
10
|
+
],
|
|
11
|
+
"remediation": [
|
|
12
|
+
"Set GRAPH_COMPOSER_LOGS_LEVEL=debug (or traceReviewConceptIo for reviewConcept).",
|
|
13
|
+
"Inspect the exception message and validation errors in logs.",
|
|
14
|
+
"Verify OPENROUTER_API_KEY and LLM model slugs."
|
|
15
|
+
],
|
|
16
|
+
"retryable": true,
|
|
17
|
+
"userActionRequired": false,
|
|
18
|
+
"confidence": "medium"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -8,6 +8,7 @@ You are a graph architect for the **worox-graph** DAG execution format. Your out
|
|
|
8
8
|
- **`summary`**: 2–6 sentences: what the graph achieves end-to-end, main phases (ingest → transform → branch → infer → finalize), and where the canonical result appears.
|
|
9
9
|
- **`executionOrder`**: A topologically sensible sequence of **node ids**. For branches, you may use short inline notes in string elements (e.g. `"nodeB (when tier=high)"`) or group logically—clarity beats perfect formatting.
|
|
10
10
|
- **`nodeDescriptions`**: Array of objects with at least `nodeId`, `role` (one line), `reads` (memory paths, `inputs`, and `taskVariable` used), `writes` (output path or effect). Cover every task node; include the finalizer. If `focusNodeIds` is set, expand those nodes and keep others shorter.
|
|
11
|
+
- **`modelLayers`** (required when `metadata.graphModelLayers` / `graphModelLayersSummary` exist on the graph): For each **AI** task node, state the **winning** PRE/MAIN/POST profile names, resolved provider ids if stamped, **`sourcePath`** (where that triple was set — e.g. `graph-engine.default`, `graph.modelConfig`, `nodes["iq-…"].taskConfiguration.modelConfig`), and note that **runtime** overrides (`runtime.nodes[id].modelConfig`, `runtime.modelConfig`) are **not** in the graph JSON unless the host injected them at execute time. Use the stamped `stack` colors/legend when present. If no `graphModelLayers` metadata, say explicitly that the graph has **no** authored `modelConfig` and runs on **engine default** (`cheap` / `balanced` / `cheap` → bundled `@x12i/ai-profiles` provider ids).
|
|
11
12
|
- **`dataFlow`**: Prose: how data enters (`input.*`), which nodes write which execution-memory paths, and how the finalizer builds the output.
|
|
12
13
|
- **`conditionalPaths`**: List conditional edges: `fromNodeId`, branches with `toNodeId` and human-readable `condition`. Use `[]` if none.
|
|
13
14
|
3. Use **node ids** and **paths** here as needed—they belong in technical explanation, not in product-facing `suggestConceptObjective` fields.
|
|
@@ -19,7 +20,7 @@ Respond with a **single JSON object**. **No markdown fences, no preamble, no tra
|
|
|
19
20
|
|
|
20
21
|
The object **MUST** include top-level `"action": "explain"` (must match the request).
|
|
21
22
|
|
|
22
|
-
**Required:** `action`, `explanation` (object with `summary`, `executionOrder`, `nodeDescriptions`, `dataFlow`, `conditionalPaths
|
|
23
|
+
**Required:** `action`, `explanation` (object with `summary`, `executionOrder`, `nodeDescriptions`, `dataFlow`, `conditionalPaths`; include **`modelLayers`** when graph model metadata exists or when inferring defaults); `warnings` optional.
|
|
23
24
|
|
|
24
25
|
Do **not** place `summary`, `executionOrder`, etc. at the top level—they must live under `explanation`.
|
|
25
26
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@exellix/graph-composer",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.1.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -36,7 +36,7 @@
|
|
|
36
36
|
"verify:local": "tsx src/verify-local.ts",
|
|
37
37
|
"verify:catalog-live": "x12i-env run --env-file .env -- tsx scripts/verify-catalog-live.ts",
|
|
38
38
|
"test": "npm run test:unit && npm run test:live",
|
|
39
|
-
"test:unit": "node --import tsx/esm --test --test-force-exit test/unit/explain-shape.test.ts test/unit/graph-concept-patch.test.ts test/unit/graph-concept-story-parse.test.ts test/unit/review-concept-output-validation.test.ts test/unit/review-concept-catalog-alias.test.ts test/unit/redact-for-log.test.ts test/unit/worker-instructions.test.ts test/unit/catalog-output-validation.test.ts test/unit/catalox-catalog-bridge.test.ts test/unit/ai-task-profile.test.ts test/unit/create-modify-output-validation.test.ts test/unit/task-node-task-variable.test.ts test/unit/canonical-graph-document.test.ts test/unit/graph-engine-bridge.test.ts test/unit/example-generation.test.ts",
|
|
39
|
+
"test:unit": "node --import tsx/esm --test --test-force-exit test/unit/explain-shape.test.ts test/unit/graph-concept-patch.test.ts test/unit/graph-concept-story-parse.test.ts test/unit/review-concept-output-validation.test.ts test/unit/review-concept-catalog-alias.test.ts test/unit/redact-for-log.test.ts test/unit/graph-composer-logging.test.ts test/unit/worker-instructions.test.ts test/unit/catalog-output-validation.test.ts test/unit/catalox-catalog-bridge.test.ts test/unit/ai-task-profile.test.ts test/unit/create-modify-output-validation.test.ts test/unit/task-node-task-variable.test.ts test/unit/canonical-graph-document.test.ts test/unit/graph-engine-bridge.test.ts test/unit/graph-model-layers.test.ts test/unit/example-generation.test.ts",
|
|
40
40
|
"test:live": "x12i-env run --env-file .env -- node --import tsx/esm --test test/live/all.ts",
|
|
41
41
|
"pack:check": "npm pack --dry-run",
|
|
42
42
|
"suggest-smoke": "x12i-env run --env-file .env -- tsx scripts/run-suggest-concept-smoke.ts"
|
|
@@ -71,11 +71,11 @@
|
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
73
|
"dependencies": {
|
|
74
|
-
"@x12i/ai-profiles": "^1.
|
|
75
|
-
"@x12i/catalox": "^5.1.
|
|
74
|
+
"@x12i/ai-profiles": "^1.7.0",
|
|
75
|
+
"@x12i/catalox": "^5.1.3",
|
|
76
76
|
"@x12i/env": "^4.0.1",
|
|
77
|
-
"@x12i/funcx": "^4.2.
|
|
78
|
-
"@x12i/logxer": "^4.
|
|
77
|
+
"@x12i/funcx": "^4.2.4",
|
|
78
|
+
"@x12i/logxer": "^4.6.0"
|
|
79
79
|
},
|
|
80
80
|
"devDependencies": {
|
|
81
81
|
"@exellix/graph-engine": "^7.2.0",
|