@x12i/ai-gateway 9.1.5 → 9.1.6
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/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/memory-path-resolution.d.ts +33 -0
- package/dist/memory-path-resolution.js +172 -0
- package/dist/template-parser.js +5 -3
- package/dist/types.d.ts +4 -0
- package/dist-cjs/index.cjs +11 -1
- package/dist-cjs/index.d.ts +2 -0
- package/dist-cjs/memory-path-resolution.cjs +182 -0
- package/dist-cjs/memory-path-resolution.d.ts +33 -0
- package/dist-cjs/template-parser.cjs +5 -3
- package/dist-cjs/types.d.ts +4 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export type { GatewayConfig, ProviderModelRef, ModelConfig, RetryConfig, ChatReq
|
|
|
20
20
|
export { attachGatewayInvokeRejectionMetadata, buildInvokeRejectionMetadata, tryExtractRouterLikePayloadFromErrorChain, pickRequestIdsFromRouterLike } from './gateway-utils.js';
|
|
21
21
|
export { mergeGatewayAndRequestTemplateRenderOptions, mergeTemplateRenderOptions } from './template-render-merge.js';
|
|
22
22
|
export type { GatewayTemplateRenderRequestSlice } from './template-render-merge.js';
|
|
23
|
+
export { GATEWAY_DUAL_MEMORY_ROOTS, buildMemoryResolutionRootFromWorkingMemory, coalesceMergedInputBucket, extractCallerInputsBag, mapSmartInputPathsInputsToInput, parseLooseJsonObject, prepareWorkingMemoryForTemplateRender, resolveGatewayMemoryPathValue } from './memory-path-resolution.js';
|
|
24
|
+
export type { GatewayDualMemoryRoot } from './memory-path-resolution.js';
|
|
23
25
|
export type { UsageTier } from './types.js';
|
|
24
26
|
export { Activix } from '@x12i/activix';
|
|
25
27
|
export type { ActivixRunContext, FindByRunContextCriteria, GetJobActivitiesInput, GetJobActivitiesResult } from '@x12i/activix';
|
package/dist/index.js
CHANGED
|
@@ -19,6 +19,7 @@ export { InstructionNotFoundError, InstructionBackendError } from './instruction
|
|
|
19
19
|
export { autoRegisterProviders } from './gateway-provider-auto-register.js';
|
|
20
20
|
export { attachGatewayInvokeRejectionMetadata, buildInvokeRejectionMetadata, tryExtractRouterLikePayloadFromErrorChain, pickRequestIdsFromRouterLike } from './gateway-utils.js';
|
|
21
21
|
export { mergeGatewayAndRequestTemplateRenderOptions, mergeTemplateRenderOptions } from './template-render-merge.js';
|
|
22
|
+
export { GATEWAY_DUAL_MEMORY_ROOTS, buildMemoryResolutionRootFromWorkingMemory, coalesceMergedInputBucket, extractCallerInputsBag, mapSmartInputPathsInputsToInput, parseLooseJsonObject, prepareWorkingMemoryForTemplateRender, resolveGatewayMemoryPathValue } from './memory-path-resolution.js';
|
|
22
23
|
// Usage tracking: UsageTracker class methods are available but consumption calculation is disabled
|
|
23
24
|
// (x-models was previously used for RPM/TPM tracking but is no longer integrated)
|
|
24
25
|
// Re-export activity tracking primitives (Activix)
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dual memory roots `input` (merged MAIN payload) and `inputs` (caller / graph-entry bag).
|
|
3
|
+
* Aligned with @exellix/graph-engine ≥ 5.5.0 resolution rules for template / smart-input paths.
|
|
4
|
+
*/
|
|
5
|
+
export declare const GATEWAY_DUAL_MEMORY_ROOTS: readonly ["input", "inputs"];
|
|
6
|
+
export type GatewayDualMemoryRoot = (typeof GATEWAY_DUAL_MEMORY_ROOTS)[number];
|
|
7
|
+
/**
|
|
8
|
+
* Parse JSON object shapes from strings (matches graph-engine `parseLooseJsonObject`).
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseLooseJsonObject(value: unknown): Record<string, unknown> | undefined;
|
|
11
|
+
/** Caller / graph-entry bag from `workingMemory.inputs`. */
|
|
12
|
+
export declare function extractCallerInputsBag(workingMemory: unknown): Record<string, unknown> | undefined;
|
|
13
|
+
/** Merged MAIN bucket from `workingMemory.input` (object or parsed JSON string). */
|
|
14
|
+
export declare function coalesceMergedInputBucket(workingMemory: unknown): unknown;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a dotted path against working memory with dual-root rules:
|
|
17
|
+
* - `inputs` / `inputs.*` → caller bag first, then merged `input`
|
|
18
|
+
* - `input` / `input.*` → merged `input` first, then caller `inputs`
|
|
19
|
+
* - other paths → direct lookup on working memory
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveGatewayMemoryPathValue(workingMemory: unknown, path: string): unknown;
|
|
22
|
+
/**
|
|
23
|
+
* Working-memory view for Rendrix / smart-input: preserves all keys but overlays
|
|
24
|
+
* `input` and `inputs` with dual-root merge views (does not rewrite authored paths).
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildMemoryResolutionRootFromWorkingMemory(workingMemory: unknown): Record<string, unknown>;
|
|
27
|
+
/**
|
|
28
|
+
* When WM carries `input` and/or `inputs`, return a resolution root for template rendering.
|
|
29
|
+
* Otherwise returns the original reference unchanged.
|
|
30
|
+
*/
|
|
31
|
+
export declare function prepareWorkingMemoryForTemplateRender(workingMemory: unknown): unknown;
|
|
32
|
+
/** Optional migration: rewrite `inputs.*` smart-input / memory paths to `input.*`. */
|
|
33
|
+
export declare function mapSmartInputPathsInputsToInput(paths: string[]): string[];
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dual memory roots `input` (merged MAIN payload) and `inputs` (caller / graph-entry bag).
|
|
3
|
+
* Aligned with @exellix/graph-engine ≥ 5.5.0 resolution rules for template / smart-input paths.
|
|
4
|
+
*/
|
|
5
|
+
export const GATEWAY_DUAL_MEMORY_ROOTS = ['input', 'inputs'];
|
|
6
|
+
function isPlainObject(value) {
|
|
7
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Parse JSON object shapes from strings (matches graph-engine `parseLooseJsonObject`).
|
|
11
|
+
*/
|
|
12
|
+
export function parseLooseJsonObject(value) {
|
|
13
|
+
if (isPlainObject(value))
|
|
14
|
+
return value;
|
|
15
|
+
if (typeof value !== 'string')
|
|
16
|
+
return undefined;
|
|
17
|
+
const trimmed = value.trim();
|
|
18
|
+
if (!trimmed.startsWith('{'))
|
|
19
|
+
return undefined;
|
|
20
|
+
try {
|
|
21
|
+
const parsed = JSON.parse(trimmed);
|
|
22
|
+
return isPlainObject(parsed) ? parsed : undefined;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return undefined;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Caller / graph-entry bag from `workingMemory.inputs`. */
|
|
29
|
+
export function extractCallerInputsBag(workingMemory) {
|
|
30
|
+
if (!isPlainObject(workingMemory))
|
|
31
|
+
return undefined;
|
|
32
|
+
const inputs = workingMemory.inputs;
|
|
33
|
+
return isPlainObject(inputs) ? inputs : undefined;
|
|
34
|
+
}
|
|
35
|
+
/** Merged MAIN bucket from `workingMemory.input` (object or parsed JSON string). */
|
|
36
|
+
export function coalesceMergedInputBucket(workingMemory) {
|
|
37
|
+
if (!isPlainObject(workingMemory))
|
|
38
|
+
return undefined;
|
|
39
|
+
const raw = workingMemory.input;
|
|
40
|
+
if (raw === undefined || raw === null)
|
|
41
|
+
return undefined;
|
|
42
|
+
const parsed = parseLooseJsonObject(raw);
|
|
43
|
+
return parsed !== undefined ? parsed : raw;
|
|
44
|
+
}
|
|
45
|
+
function getValueAtPath(obj, path) {
|
|
46
|
+
if (obj == null)
|
|
47
|
+
return undefined;
|
|
48
|
+
if (path === '' || path === 'this' || path === '.')
|
|
49
|
+
return obj;
|
|
50
|
+
const parts = path.split('.');
|
|
51
|
+
let cur = obj;
|
|
52
|
+
for (const part of parts) {
|
|
53
|
+
if (cur == null || typeof cur !== 'object')
|
|
54
|
+
return undefined;
|
|
55
|
+
cur = cur[part];
|
|
56
|
+
}
|
|
57
|
+
return cur;
|
|
58
|
+
}
|
|
59
|
+
function asObjectBucket(value) {
|
|
60
|
+
const parsed = parseLooseJsonObject(value);
|
|
61
|
+
if (parsed)
|
|
62
|
+
return parsed;
|
|
63
|
+
return isPlainObject(value) ? value : undefined;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Shallow-deep merge for template lookup: primary wins per key; nested plain objects merge recursively.
|
|
67
|
+
*/
|
|
68
|
+
function mergeBucketViews(primary, fallback) {
|
|
69
|
+
const pObj = asObjectBucket(primary);
|
|
70
|
+
const fObj = asObjectBucket(fallback);
|
|
71
|
+
if (!pObj && !fObj) {
|
|
72
|
+
if (primary !== undefined && primary !== null)
|
|
73
|
+
return primary;
|
|
74
|
+
return fallback;
|
|
75
|
+
}
|
|
76
|
+
if (!pObj)
|
|
77
|
+
return { ...fObj };
|
|
78
|
+
if (!fObj)
|
|
79
|
+
return { ...pObj };
|
|
80
|
+
const keys = new Set([...Object.keys(pObj), ...Object.keys(fObj)]);
|
|
81
|
+
const view = {};
|
|
82
|
+
for (const key of keys) {
|
|
83
|
+
const pv = pObj[key];
|
|
84
|
+
const fv = fObj[key];
|
|
85
|
+
if (isPlainObject(pv) && isPlainObject(fv)) {
|
|
86
|
+
view[key] = mergeBucketViews(pv, fv);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
view[key] = pv !== undefined ? pv : fv;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return view;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Resolve a dotted path against working memory with dual-root rules:
|
|
96
|
+
* - `inputs` / `inputs.*` → caller bag first, then merged `input`
|
|
97
|
+
* - `input` / `input.*` → merged `input` first, then caller `inputs`
|
|
98
|
+
* - other paths → direct lookup on working memory
|
|
99
|
+
*/
|
|
100
|
+
export function resolveGatewayMemoryPathValue(workingMemory, path) {
|
|
101
|
+
const trimmed = path.trim();
|
|
102
|
+
if (!trimmed)
|
|
103
|
+
return undefined;
|
|
104
|
+
const dot = trimmed.indexOf('.');
|
|
105
|
+
const root = dot >= 0 ? trimmed.slice(0, dot) : trimmed;
|
|
106
|
+
const tail = dot >= 0 ? trimmed.slice(dot + 1) : '';
|
|
107
|
+
if (root === 'inputs') {
|
|
108
|
+
const primary = extractCallerInputsBag(workingMemory);
|
|
109
|
+
const fallback = coalesceMergedInputBucket(workingMemory);
|
|
110
|
+
if (!tail) {
|
|
111
|
+
if (primary && Object.keys(primary).length > 0)
|
|
112
|
+
return primary;
|
|
113
|
+
return fallback;
|
|
114
|
+
}
|
|
115
|
+
const fromPrimary = primary ? getValueAtPath(primary, tail) : undefined;
|
|
116
|
+
if (fromPrimary !== undefined)
|
|
117
|
+
return fromPrimary;
|
|
118
|
+
return fallback !== undefined ? getValueAtPath(fallback, tail) : undefined;
|
|
119
|
+
}
|
|
120
|
+
if (root === 'input') {
|
|
121
|
+
const primary = coalesceMergedInputBucket(workingMemory);
|
|
122
|
+
const fallback = extractCallerInputsBag(workingMemory);
|
|
123
|
+
if (!tail) {
|
|
124
|
+
if (primary !== undefined && primary !== null)
|
|
125
|
+
return primary;
|
|
126
|
+
return fallback;
|
|
127
|
+
}
|
|
128
|
+
const fromPrimary = primary !== undefined ? getValueAtPath(primary, tail) : undefined;
|
|
129
|
+
if (fromPrimary !== undefined)
|
|
130
|
+
return fromPrimary;
|
|
131
|
+
return fallback ? getValueAtPath(fallback, tail) : undefined;
|
|
132
|
+
}
|
|
133
|
+
return getValueAtPath(workingMemory, trimmed);
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Working-memory view for Rendrix / smart-input: preserves all keys but overlays
|
|
137
|
+
* `input` and `inputs` with dual-root merge views (does not rewrite authored paths).
|
|
138
|
+
*/
|
|
139
|
+
export function buildMemoryResolutionRootFromWorkingMemory(workingMemory) {
|
|
140
|
+
if (!isPlainObject(workingMemory))
|
|
141
|
+
return {};
|
|
142
|
+
const inputsBag = extractCallerInputsBag(workingMemory);
|
|
143
|
+
const mergedInput = coalesceMergedInputBucket(workingMemory);
|
|
144
|
+
return {
|
|
145
|
+
...workingMemory,
|
|
146
|
+
input: mergeBucketViews(mergedInput, inputsBag),
|
|
147
|
+
inputs: mergeBucketViews(inputsBag, mergedInput)
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* When WM carries `input` and/or `inputs`, return a resolution root for template rendering.
|
|
152
|
+
* Otherwise returns the original reference unchanged.
|
|
153
|
+
*/
|
|
154
|
+
export function prepareWorkingMemoryForTemplateRender(workingMemory) {
|
|
155
|
+
if (!isPlainObject(workingMemory))
|
|
156
|
+
return workingMemory;
|
|
157
|
+
if (workingMemory.input === undefined && workingMemory.inputs === undefined) {
|
|
158
|
+
return workingMemory;
|
|
159
|
+
}
|
|
160
|
+
return buildMemoryResolutionRootFromWorkingMemory(workingMemory);
|
|
161
|
+
}
|
|
162
|
+
/** Optional migration: rewrite `inputs.*` smart-input / memory paths to `input.*`. */
|
|
163
|
+
export function mapSmartInputPathsInputsToInput(paths) {
|
|
164
|
+
return paths.map((p) => {
|
|
165
|
+
const t = p.trim();
|
|
166
|
+
if (t === 'inputs')
|
|
167
|
+
return 'input';
|
|
168
|
+
if (t.startsWith('inputs.'))
|
|
169
|
+
return `input.${t.slice('inputs.'.length)}`;
|
|
170
|
+
return p;
|
|
171
|
+
});
|
|
172
|
+
}
|
package/dist/template-parser.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Uses @x12i/rendrix (v4+) to parse templates with workingMemory.
|
|
5
5
|
* TemplateResolutionError from the parser is rethrown; other errors fall back to the raw template.
|
|
6
6
|
*/
|
|
7
|
+
import { prepareWorkingMemoryForTemplateRender } from './memory-path-resolution.js';
|
|
7
8
|
let rendrixModule = null;
|
|
8
9
|
let parserLoadPromise = null;
|
|
9
10
|
async function loadRendrix() {
|
|
@@ -48,6 +49,7 @@ export async function parseTemplate(template, workingMemory, taskConfig, shortTe
|
|
|
48
49
|
if (!workingMemory) {
|
|
49
50
|
return template;
|
|
50
51
|
}
|
|
52
|
+
const wmForRender = prepareWorkingMemoryForTemplateRender(workingMemory);
|
|
51
53
|
await loadRendrix();
|
|
52
54
|
if (!rendrixModule) {
|
|
53
55
|
return template;
|
|
@@ -57,18 +59,18 @@ export async function parseTemplate(template, workingMemory, taskConfig, shortTe
|
|
|
57
59
|
? rendrixModule
|
|
58
60
|
: rendrixModule.default || rendrixModule;
|
|
59
61
|
if (typeof api.render === 'function') {
|
|
60
|
-
return await api.render(template,
|
|
62
|
+
return await api.render(template, wmForRender, shortTermMemory, experienceMemory, knowledgeMemory, undefined, // functionsMap
|
|
61
63
|
undefined, // choiceOptions
|
|
62
64
|
undefined, // filesContent
|
|
63
65
|
templateRenderOptions);
|
|
64
66
|
}
|
|
65
67
|
if (typeof api.parse === 'function') {
|
|
66
|
-
return await api.parse(template,
|
|
68
|
+
return await api.parse(template, wmForRender);
|
|
67
69
|
}
|
|
68
70
|
else if (typeof api === 'function') {
|
|
69
71
|
const parser = new api();
|
|
70
72
|
if (typeof parser.parse === 'function') {
|
|
71
|
-
return await parser.parse(template,
|
|
73
|
+
return await parser.parse(template, wmForRender);
|
|
72
74
|
}
|
|
73
75
|
}
|
|
74
76
|
return template;
|
package/dist/types.d.ts
CHANGED
|
@@ -626,6 +626,10 @@ interface BaseLLMRequest extends Omit<LLMRequest, 'messages' | 'input' | 'reques
|
|
|
626
626
|
* Working memory (optional) - Affects all template parsing
|
|
627
627
|
* Passed to Rendrix (v4+) for template variable substitution.
|
|
628
628
|
* Plain {{path}} tokens are MUST paths: undefined after merge throws TemplateResolutionError (rethrown by the gateway).
|
|
629
|
+
*
|
|
630
|
+
* Dual roots (graph-engine / ai-tasks contract): `inputs` is the caller / graph-entry bag;
|
|
631
|
+
* `input` is the merged MAIN payload (object or JSON string). Smart-input and `input.*` / `inputs.*`
|
|
632
|
+
* paths resolve with cross-root fallback before render (see `resolveGatewayMemoryPathValue`).
|
|
629
633
|
*/
|
|
630
634
|
workingMemory?: unknown;
|
|
631
635
|
/**
|
package/dist-cjs/index.cjs
CHANGED
|
@@ -21,7 +21,8 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
21
21
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
22
22
|
};
|
|
23
23
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
24
|
-
exports.
|
|
24
|
+
exports.getObjectTypesForAgent = exports.getObjectType = exports.OBJECT_TYPES_LIBRARY = exports.assertValidAIRequest = exports.formatDiagnostic = exports.runValidationTests = exports.createValidationTestCases = exports.createTestAIRequest = exports.supportsJSONMode = exports.diagnoseResponse = exports.diagnoseRequest = exports.validateResponse = exports.extractJSON = exports.validateJSON = exports.validateAIRequest = exports.DEFAULT_RATE_LIMIT_ENABLED = exports.DEFAULT_RATE_LIMIT_MIN_INTERVAL_MS = exports.GatewayRateLimiter = exports.runtimeObjects = exports.DebugLogAbstract = exports.createLogxer = exports.gatewayLogDebug = exports.withActivityIdentity = exports.activityIdentityToLogMeta = exports.ensureGatewayRequestIdentity = exports.ActivityManager = exports.Activix = exports.resolveGatewayMemoryPathValue = exports.prepareWorkingMemoryForTemplateRender = exports.parseLooseJsonObject = exports.mapSmartInputPathsInputsToInput = exports.extractCallerInputsBag = exports.coalesceMergedInputBucket = exports.buildMemoryResolutionRootFromWorkingMemory = exports.GATEWAY_DUAL_MEMORY_ROOTS = exports.mergeTemplateRenderOptions = exports.mergeGatewayAndRequestTemplateRenderOptions = exports.pickRequestIdsFromRouterLike = exports.tryExtractRouterLikePayloadFromErrorChain = exports.buildInvokeRejectionMetadata = exports.attachGatewayInvokeRejectionMetadata = exports.autoRegisterProviders = exports.InstructionBackendError = exports.InstructionNotFoundError = exports.AIGateway = exports.FallbackExhaustedError = exports.ProviderNotFoundError = exports.createRouterFromConfig = exports.createRouter = exports.LLMProviderRouter = void 0;
|
|
25
|
+
exports.resetObjectTypesLibrary = exports.getObjectTypesLibrary = exports.initializeObjectTypesLibrary = void 0;
|
|
25
26
|
// Re-export router class and types (base functionality)
|
|
26
27
|
var ai_providers_router_1 = require("@x12i/ai-providers-router");
|
|
27
28
|
Object.defineProperty(exports, "LLMProviderRouter", { enumerable: true, get: function () { return ai_providers_router_1.LLMProviderRouter; } });
|
|
@@ -51,6 +52,15 @@ Object.defineProperty(exports, "pickRequestIdsFromRouterLike", { enumerable: tru
|
|
|
51
52
|
var template_render_merge_js_1 = require("./template-render-merge.cjs");
|
|
52
53
|
Object.defineProperty(exports, "mergeGatewayAndRequestTemplateRenderOptions", { enumerable: true, get: function () { return template_render_merge_js_1.mergeGatewayAndRequestTemplateRenderOptions; } });
|
|
53
54
|
Object.defineProperty(exports, "mergeTemplateRenderOptions", { enumerable: true, get: function () { return template_render_merge_js_1.mergeTemplateRenderOptions; } });
|
|
55
|
+
var memory_path_resolution_js_1 = require("./memory-path-resolution.cjs");
|
|
56
|
+
Object.defineProperty(exports, "GATEWAY_DUAL_MEMORY_ROOTS", { enumerable: true, get: function () { return memory_path_resolution_js_1.GATEWAY_DUAL_MEMORY_ROOTS; } });
|
|
57
|
+
Object.defineProperty(exports, "buildMemoryResolutionRootFromWorkingMemory", { enumerable: true, get: function () { return memory_path_resolution_js_1.buildMemoryResolutionRootFromWorkingMemory; } });
|
|
58
|
+
Object.defineProperty(exports, "coalesceMergedInputBucket", { enumerable: true, get: function () { return memory_path_resolution_js_1.coalesceMergedInputBucket; } });
|
|
59
|
+
Object.defineProperty(exports, "extractCallerInputsBag", { enumerable: true, get: function () { return memory_path_resolution_js_1.extractCallerInputsBag; } });
|
|
60
|
+
Object.defineProperty(exports, "mapSmartInputPathsInputsToInput", { enumerable: true, get: function () { return memory_path_resolution_js_1.mapSmartInputPathsInputsToInput; } });
|
|
61
|
+
Object.defineProperty(exports, "parseLooseJsonObject", { enumerable: true, get: function () { return memory_path_resolution_js_1.parseLooseJsonObject; } });
|
|
62
|
+
Object.defineProperty(exports, "prepareWorkingMemoryForTemplateRender", { enumerable: true, get: function () { return memory_path_resolution_js_1.prepareWorkingMemoryForTemplateRender; } });
|
|
63
|
+
Object.defineProperty(exports, "resolveGatewayMemoryPathValue", { enumerable: true, get: function () { return memory_path_resolution_js_1.resolveGatewayMemoryPathValue; } });
|
|
54
64
|
// Usage tracking: UsageTracker class methods are available but consumption calculation is disabled
|
|
55
65
|
// (x-models was previously used for RPM/TPM tracking but is no longer integrated)
|
|
56
66
|
// Re-export activity tracking primitives (Activix)
|
package/dist-cjs/index.d.ts
CHANGED
|
@@ -20,6 +20,8 @@ export type { GatewayConfig, ProviderModelRef, ModelConfig, RetryConfig, ChatReq
|
|
|
20
20
|
export { attachGatewayInvokeRejectionMetadata, buildInvokeRejectionMetadata, tryExtractRouterLikePayloadFromErrorChain, pickRequestIdsFromRouterLike } from './gateway-utils.js';
|
|
21
21
|
export { mergeGatewayAndRequestTemplateRenderOptions, mergeTemplateRenderOptions } from './template-render-merge.js';
|
|
22
22
|
export type { GatewayTemplateRenderRequestSlice } from './template-render-merge.js';
|
|
23
|
+
export { GATEWAY_DUAL_MEMORY_ROOTS, buildMemoryResolutionRootFromWorkingMemory, coalesceMergedInputBucket, extractCallerInputsBag, mapSmartInputPathsInputsToInput, parseLooseJsonObject, prepareWorkingMemoryForTemplateRender, resolveGatewayMemoryPathValue } from './memory-path-resolution.js';
|
|
24
|
+
export type { GatewayDualMemoryRoot } from './memory-path-resolution.js';
|
|
23
25
|
export type { UsageTier } from './types.js';
|
|
24
26
|
export { Activix } from '@x12i/activix';
|
|
25
27
|
export type { ActivixRunContext, FindByRunContextCriteria, GetJobActivitiesInput, GetJobActivitiesResult } from '@x12i/activix';
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Dual memory roots `input` (merged MAIN payload) and `inputs` (caller / graph-entry bag).
|
|
4
|
+
* Aligned with @exellix/graph-engine ≥ 5.5.0 resolution rules for template / smart-input paths.
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.GATEWAY_DUAL_MEMORY_ROOTS = void 0;
|
|
8
|
+
exports.parseLooseJsonObject = parseLooseJsonObject;
|
|
9
|
+
exports.extractCallerInputsBag = extractCallerInputsBag;
|
|
10
|
+
exports.coalesceMergedInputBucket = coalesceMergedInputBucket;
|
|
11
|
+
exports.resolveGatewayMemoryPathValue = resolveGatewayMemoryPathValue;
|
|
12
|
+
exports.buildMemoryResolutionRootFromWorkingMemory = buildMemoryResolutionRootFromWorkingMemory;
|
|
13
|
+
exports.prepareWorkingMemoryForTemplateRender = prepareWorkingMemoryForTemplateRender;
|
|
14
|
+
exports.mapSmartInputPathsInputsToInput = mapSmartInputPathsInputsToInput;
|
|
15
|
+
exports.GATEWAY_DUAL_MEMORY_ROOTS = ['input', 'inputs'];
|
|
16
|
+
function isPlainObject(value) {
|
|
17
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Parse JSON object shapes from strings (matches graph-engine `parseLooseJsonObject`).
|
|
21
|
+
*/
|
|
22
|
+
function parseLooseJsonObject(value) {
|
|
23
|
+
if (isPlainObject(value))
|
|
24
|
+
return value;
|
|
25
|
+
if (typeof value !== 'string')
|
|
26
|
+
return undefined;
|
|
27
|
+
const trimmed = value.trim();
|
|
28
|
+
if (!trimmed.startsWith('{'))
|
|
29
|
+
return undefined;
|
|
30
|
+
try {
|
|
31
|
+
const parsed = JSON.parse(trimmed);
|
|
32
|
+
return isPlainObject(parsed) ? parsed : undefined;
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return undefined;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/** Caller / graph-entry bag from `workingMemory.inputs`. */
|
|
39
|
+
function extractCallerInputsBag(workingMemory) {
|
|
40
|
+
if (!isPlainObject(workingMemory))
|
|
41
|
+
return undefined;
|
|
42
|
+
const inputs = workingMemory.inputs;
|
|
43
|
+
return isPlainObject(inputs) ? inputs : undefined;
|
|
44
|
+
}
|
|
45
|
+
/** Merged MAIN bucket from `workingMemory.input` (object or parsed JSON string). */
|
|
46
|
+
function coalesceMergedInputBucket(workingMemory) {
|
|
47
|
+
if (!isPlainObject(workingMemory))
|
|
48
|
+
return undefined;
|
|
49
|
+
const raw = workingMemory.input;
|
|
50
|
+
if (raw === undefined || raw === null)
|
|
51
|
+
return undefined;
|
|
52
|
+
const parsed = parseLooseJsonObject(raw);
|
|
53
|
+
return parsed !== undefined ? parsed : raw;
|
|
54
|
+
}
|
|
55
|
+
function getValueAtPath(obj, path) {
|
|
56
|
+
if (obj == null)
|
|
57
|
+
return undefined;
|
|
58
|
+
if (path === '' || path === 'this' || path === '.')
|
|
59
|
+
return obj;
|
|
60
|
+
const parts = path.split('.');
|
|
61
|
+
let cur = obj;
|
|
62
|
+
for (const part of parts) {
|
|
63
|
+
if (cur == null || typeof cur !== 'object')
|
|
64
|
+
return undefined;
|
|
65
|
+
cur = cur[part];
|
|
66
|
+
}
|
|
67
|
+
return cur;
|
|
68
|
+
}
|
|
69
|
+
function asObjectBucket(value) {
|
|
70
|
+
const parsed = parseLooseJsonObject(value);
|
|
71
|
+
if (parsed)
|
|
72
|
+
return parsed;
|
|
73
|
+
return isPlainObject(value) ? value : undefined;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Shallow-deep merge for template lookup: primary wins per key; nested plain objects merge recursively.
|
|
77
|
+
*/
|
|
78
|
+
function mergeBucketViews(primary, fallback) {
|
|
79
|
+
const pObj = asObjectBucket(primary);
|
|
80
|
+
const fObj = asObjectBucket(fallback);
|
|
81
|
+
if (!pObj && !fObj) {
|
|
82
|
+
if (primary !== undefined && primary !== null)
|
|
83
|
+
return primary;
|
|
84
|
+
return fallback;
|
|
85
|
+
}
|
|
86
|
+
if (!pObj)
|
|
87
|
+
return { ...fObj };
|
|
88
|
+
if (!fObj)
|
|
89
|
+
return { ...pObj };
|
|
90
|
+
const keys = new Set([...Object.keys(pObj), ...Object.keys(fObj)]);
|
|
91
|
+
const view = {};
|
|
92
|
+
for (const key of keys) {
|
|
93
|
+
const pv = pObj[key];
|
|
94
|
+
const fv = fObj[key];
|
|
95
|
+
if (isPlainObject(pv) && isPlainObject(fv)) {
|
|
96
|
+
view[key] = mergeBucketViews(pv, fv);
|
|
97
|
+
}
|
|
98
|
+
else {
|
|
99
|
+
view[key] = pv !== undefined ? pv : fv;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
return view;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Resolve a dotted path against working memory with dual-root rules:
|
|
106
|
+
* - `inputs` / `inputs.*` → caller bag first, then merged `input`
|
|
107
|
+
* - `input` / `input.*` → merged `input` first, then caller `inputs`
|
|
108
|
+
* - other paths → direct lookup on working memory
|
|
109
|
+
*/
|
|
110
|
+
function resolveGatewayMemoryPathValue(workingMemory, path) {
|
|
111
|
+
const trimmed = path.trim();
|
|
112
|
+
if (!trimmed)
|
|
113
|
+
return undefined;
|
|
114
|
+
const dot = trimmed.indexOf('.');
|
|
115
|
+
const root = dot >= 0 ? trimmed.slice(0, dot) : trimmed;
|
|
116
|
+
const tail = dot >= 0 ? trimmed.slice(dot + 1) : '';
|
|
117
|
+
if (root === 'inputs') {
|
|
118
|
+
const primary = extractCallerInputsBag(workingMemory);
|
|
119
|
+
const fallback = coalesceMergedInputBucket(workingMemory);
|
|
120
|
+
if (!tail) {
|
|
121
|
+
if (primary && Object.keys(primary).length > 0)
|
|
122
|
+
return primary;
|
|
123
|
+
return fallback;
|
|
124
|
+
}
|
|
125
|
+
const fromPrimary = primary ? getValueAtPath(primary, tail) : undefined;
|
|
126
|
+
if (fromPrimary !== undefined)
|
|
127
|
+
return fromPrimary;
|
|
128
|
+
return fallback !== undefined ? getValueAtPath(fallback, tail) : undefined;
|
|
129
|
+
}
|
|
130
|
+
if (root === 'input') {
|
|
131
|
+
const primary = coalesceMergedInputBucket(workingMemory);
|
|
132
|
+
const fallback = extractCallerInputsBag(workingMemory);
|
|
133
|
+
if (!tail) {
|
|
134
|
+
if (primary !== undefined && primary !== null)
|
|
135
|
+
return primary;
|
|
136
|
+
return fallback;
|
|
137
|
+
}
|
|
138
|
+
const fromPrimary = primary !== undefined ? getValueAtPath(primary, tail) : undefined;
|
|
139
|
+
if (fromPrimary !== undefined)
|
|
140
|
+
return fromPrimary;
|
|
141
|
+
return fallback ? getValueAtPath(fallback, tail) : undefined;
|
|
142
|
+
}
|
|
143
|
+
return getValueAtPath(workingMemory, trimmed);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Working-memory view for Rendrix / smart-input: preserves all keys but overlays
|
|
147
|
+
* `input` and `inputs` with dual-root merge views (does not rewrite authored paths).
|
|
148
|
+
*/
|
|
149
|
+
function buildMemoryResolutionRootFromWorkingMemory(workingMemory) {
|
|
150
|
+
if (!isPlainObject(workingMemory))
|
|
151
|
+
return {};
|
|
152
|
+
const inputsBag = extractCallerInputsBag(workingMemory);
|
|
153
|
+
const mergedInput = coalesceMergedInputBucket(workingMemory);
|
|
154
|
+
return {
|
|
155
|
+
...workingMemory,
|
|
156
|
+
input: mergeBucketViews(mergedInput, inputsBag),
|
|
157
|
+
inputs: mergeBucketViews(inputsBag, mergedInput)
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* When WM carries `input` and/or `inputs`, return a resolution root for template rendering.
|
|
162
|
+
* Otherwise returns the original reference unchanged.
|
|
163
|
+
*/
|
|
164
|
+
function prepareWorkingMemoryForTemplateRender(workingMemory) {
|
|
165
|
+
if (!isPlainObject(workingMemory))
|
|
166
|
+
return workingMemory;
|
|
167
|
+
if (workingMemory.input === undefined && workingMemory.inputs === undefined) {
|
|
168
|
+
return workingMemory;
|
|
169
|
+
}
|
|
170
|
+
return buildMemoryResolutionRootFromWorkingMemory(workingMemory);
|
|
171
|
+
}
|
|
172
|
+
/** Optional migration: rewrite `inputs.*` smart-input / memory paths to `input.*`. */
|
|
173
|
+
function mapSmartInputPathsInputsToInput(paths) {
|
|
174
|
+
return paths.map((p) => {
|
|
175
|
+
const t = p.trim();
|
|
176
|
+
if (t === 'inputs')
|
|
177
|
+
return 'input';
|
|
178
|
+
if (t.startsWith('inputs.'))
|
|
179
|
+
return `input.${t.slice('inputs.'.length)}`;
|
|
180
|
+
return p;
|
|
181
|
+
});
|
|
182
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dual memory roots `input` (merged MAIN payload) and `inputs` (caller / graph-entry bag).
|
|
3
|
+
* Aligned with @exellix/graph-engine ≥ 5.5.0 resolution rules for template / smart-input paths.
|
|
4
|
+
*/
|
|
5
|
+
export declare const GATEWAY_DUAL_MEMORY_ROOTS: readonly ["input", "inputs"];
|
|
6
|
+
export type GatewayDualMemoryRoot = (typeof GATEWAY_DUAL_MEMORY_ROOTS)[number];
|
|
7
|
+
/**
|
|
8
|
+
* Parse JSON object shapes from strings (matches graph-engine `parseLooseJsonObject`).
|
|
9
|
+
*/
|
|
10
|
+
export declare function parseLooseJsonObject(value: unknown): Record<string, unknown> | undefined;
|
|
11
|
+
/** Caller / graph-entry bag from `workingMemory.inputs`. */
|
|
12
|
+
export declare function extractCallerInputsBag(workingMemory: unknown): Record<string, unknown> | undefined;
|
|
13
|
+
/** Merged MAIN bucket from `workingMemory.input` (object or parsed JSON string). */
|
|
14
|
+
export declare function coalesceMergedInputBucket(workingMemory: unknown): unknown;
|
|
15
|
+
/**
|
|
16
|
+
* Resolve a dotted path against working memory with dual-root rules:
|
|
17
|
+
* - `inputs` / `inputs.*` → caller bag first, then merged `input`
|
|
18
|
+
* - `input` / `input.*` → merged `input` first, then caller `inputs`
|
|
19
|
+
* - other paths → direct lookup on working memory
|
|
20
|
+
*/
|
|
21
|
+
export declare function resolveGatewayMemoryPathValue(workingMemory: unknown, path: string): unknown;
|
|
22
|
+
/**
|
|
23
|
+
* Working-memory view for Rendrix / smart-input: preserves all keys but overlays
|
|
24
|
+
* `input` and `inputs` with dual-root merge views (does not rewrite authored paths).
|
|
25
|
+
*/
|
|
26
|
+
export declare function buildMemoryResolutionRootFromWorkingMemory(workingMemory: unknown): Record<string, unknown>;
|
|
27
|
+
/**
|
|
28
|
+
* When WM carries `input` and/or `inputs`, return a resolution root for template rendering.
|
|
29
|
+
* Otherwise returns the original reference unchanged.
|
|
30
|
+
*/
|
|
31
|
+
export declare function prepareWorkingMemoryForTemplateRender(workingMemory: unknown): unknown;
|
|
32
|
+
/** Optional migration: rewrite `inputs.*` smart-input / memory paths to `input.*`. */
|
|
33
|
+
export declare function mapSmartInputPathsInputsToInput(paths: string[]): string[];
|
|
@@ -41,6 +41,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
41
41
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
42
|
exports.parseTemplate = parseTemplate;
|
|
43
43
|
exports.isParserAvailable = isParserAvailable;
|
|
44
|
+
const memory_path_resolution_js_1 = require("./memory-path-resolution.cjs");
|
|
44
45
|
let rendrixModule = null;
|
|
45
46
|
let parserLoadPromise = null;
|
|
46
47
|
async function loadRendrix() {
|
|
@@ -85,6 +86,7 @@ async function parseTemplate(template, workingMemory, taskConfig, shortTermMemor
|
|
|
85
86
|
if (!workingMemory) {
|
|
86
87
|
return template;
|
|
87
88
|
}
|
|
89
|
+
const wmForRender = (0, memory_path_resolution_js_1.prepareWorkingMemoryForTemplateRender)(workingMemory);
|
|
88
90
|
await loadRendrix();
|
|
89
91
|
if (!rendrixModule) {
|
|
90
92
|
return template;
|
|
@@ -94,18 +96,18 @@ async function parseTemplate(template, workingMemory, taskConfig, shortTermMemor
|
|
|
94
96
|
? rendrixModule
|
|
95
97
|
: rendrixModule.default || rendrixModule;
|
|
96
98
|
if (typeof api.render === 'function') {
|
|
97
|
-
return await api.render(template,
|
|
99
|
+
return await api.render(template, wmForRender, shortTermMemory, experienceMemory, knowledgeMemory, undefined, // functionsMap
|
|
98
100
|
undefined, // choiceOptions
|
|
99
101
|
undefined, // filesContent
|
|
100
102
|
templateRenderOptions);
|
|
101
103
|
}
|
|
102
104
|
if (typeof api.parse === 'function') {
|
|
103
|
-
return await api.parse(template,
|
|
105
|
+
return await api.parse(template, wmForRender);
|
|
104
106
|
}
|
|
105
107
|
else if (typeof api === 'function') {
|
|
106
108
|
const parser = new api();
|
|
107
109
|
if (typeof parser.parse === 'function') {
|
|
108
|
-
return await parser.parse(template,
|
|
110
|
+
return await parser.parse(template, wmForRender);
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
113
|
return template;
|
package/dist-cjs/types.d.ts
CHANGED
|
@@ -626,6 +626,10 @@ interface BaseLLMRequest extends Omit<LLMRequest, 'messages' | 'input' | 'reques
|
|
|
626
626
|
* Working memory (optional) - Affects all template parsing
|
|
627
627
|
* Passed to Rendrix (v4+) for template variable substitution.
|
|
628
628
|
* Plain {{path}} tokens are MUST paths: undefined after merge throws TemplateResolutionError (rethrown by the gateway).
|
|
629
|
+
*
|
|
630
|
+
* Dual roots (graph-engine / ai-tasks contract): `inputs` is the caller / graph-entry bag;
|
|
631
|
+
* `input` is the merged MAIN payload (object or JSON string). Smart-input and `input.*` / `inputs.*`
|
|
632
|
+
* paths resolve with cross-root fallback before render (see `resolveGatewayMemoryPathValue`).
|
|
629
633
|
*/
|
|
630
634
|
workingMemory?: unknown;
|
|
631
635
|
/**
|