@gobing-ai/ts-ai-decision 0.5.22 → 0.5.24
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 +6 -0
- package/dist/hub.d.ts.map +1 -1
- package/dist/hub.js +5 -1
- package/dist/registry.d.ts +7 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +21 -0
- package/package.json +5 -5
- package/src/hub.ts +5 -0
- package/src/registry.ts +21 -0
package/README.md
CHANGED
|
@@ -124,6 +124,12 @@ throw `DecisionRegistryError`; unknown names throw `UnknownDecisionMakerError {
|
|
|
124
124
|
errors propagate unchanged. Pass `builtins: { makerOptions, driverOptions }` to tune the built-ins
|
|
125
125
|
(env/keys/timeouts, or executor/client injection for the local drivers).
|
|
126
126
|
|
|
127
|
+
`dispose(name?)` releases the resources of already-`resolve`d makers — a `laya-local` maker holds a
|
|
128
|
+
warm Python worker whose open pipes keep the calling process alive until it is closed (reachable from
|
|
129
|
+
a hub as `hub.registry.dispose()`). It never runs an unresolved factory just to close it, ignores
|
|
130
|
+
unknown names, and returns each entry to its unresolved state, so a later `resolve` builds a fresh
|
|
131
|
+
maker instead of handing back a closed one.
|
|
132
|
+
|
|
127
133
|
The hub picks a maker purely by name — no new driver code per routing:
|
|
128
134
|
per-call `options.maker` → the decision's `maker` → the catalog's `defaults.maker` → the hub's
|
|
129
135
|
`defaultMaker` (default `typesafe`). Catalog names are checked at `load`; a misspelled per-call
|
package/dist/hub.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"hub.d.ts","sourceRoot":"","sources":["../src/hub.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,KAAK,IAAI,
|
|
1
|
+
{"version":3,"file":"hub.d.ts","sourceRoot":"","sources":["../src/hub.ts"],"names":[],"mappings":"AAAA,OAAO,EAKH,KAAK,IAAI,EAIZ,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,kBAAkB,EAAuB,MAAM,WAAW,CAAC;AAGzE,OAAO,EAAE,KAAK,mBAAmB,EAAE,qBAAqB,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC/F,OAAO,KAAK,EAER,eAAe,EACf,gBAAgB,EAEhB,aAAa,EACb,YAAY,EAGf,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;GASG;AAEH,uFAAuF;AACvF,eAAO,MAAM,sBAAsB,MAAM,CAAC;AAE1C,iGAAiG;AACjG,eAAO,MAAM,aAAa,aAAa,CAAC;AAExC,+DAA+D;AAC/D,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,kEAAkE;IAClE,QAAQ,CAAC,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,UAAU,GAAG,gBAAgB,GAAG,YAAY,GAAG,SAAS,GAAG,OAAO,CAAC;IACpF,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC/B;AAED,wFAAwF;AACxF,MAAM,MAAM,cAAc,GACpB,CAAC,kBAAkB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GAC1E,CAAC,kBAAkB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,GACzE,CAAC,kBAAkB,GAAG;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAAC;AAErH,oEAAoE;AACpE,MAAM,WAAW,eAAe;IAC5B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CAC3B;AAED,mGAAmG;AACnG,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,mFAAmF;IACnF,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;IAC7D,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC;IACpC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAC7C,oEAAoE;IACpE,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;IAC/B,sDAAsD;IACtD,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,qEAAqE;IACrE,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,gDAAgD;AAChD,MAAM,WAAW,kBAAkB;IAC/B,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IAC1C,wFAAwF;IACxF,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,CAAC;IAC/B,yFAAyF;IACzF,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CAC/B;AAED,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC1B,wFAAwF;IACxF,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CAC3B;AAiDD;;;;;;GAMG;AACH,qBAAa,WAAW;IACpB,QAAQ,CAAC,QAAQ,EAAE,qBAAqB,CAAC;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyC;IACnE,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAS;IACtC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;gBAEvB,OAAO,GAAE,kBAAuB;IAa5C;;;;;OAKG;IACH,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI;IAsCpC,sFAAsF;IAChF,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,kBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7E,+EAA+E;IAC/E,IAAI,IAAI,eAAe,EAAE;IASzB,kGAAkG;IAClG,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB;IAiBxC;;;;;;;OAOG;IACG,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,GAAE,MAAM,CAAC,MAAM,EAAE,IAAI,CAAM,EAAE,OAAO,GAAE,aAAkB,GAAG,OAAO,CAAC,cAAc,CAAC;IAkFhH,8FAA8F;IAC9F,OAAO,CAAC,kBAAkB;IAI1B,OAAO,CAAC,OAAO;IAYf;;;;OAIG;IACH,OAAO,CAAC,cAAc;CA8BzB;AAED,mFAAmF;AACnF,MAAM,WAAW,wBAAyB,SAAQ,kBAAkB;IAChE,+EAA+E;IAC/E,QAAQ,CAAC,QAAQ,CAAC,EAAE,mBAAmB,GAAG,KAAK,CAAC;IAChD,qFAAqF;IACrF,QAAQ,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC;IACxD,0FAA0F;IAC1F,QAAQ,CAAC,QAAQ,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,0CAA0C;IAC1C,QAAQ,CAAC,cAAc,CAAC,EAAE,kBAAkB,CAAC;CAChD;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CAAC,OAAO,GAAE,wBAA6B,GAAG,OAAO,CAAC,WAAW,CAAC,CAUpG"}
|
package/dist/hub.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DecisionConfigError, DecisionTimeoutError, q, } from '@gobing-ai/ts-ai-runner';
|
|
1
|
+
import { DecisionConfigError, DecisionTimeoutError, q, validateAnswers, } from '@gobing-ai/ts-ai-runner';
|
|
2
2
|
import { loadDecisionCatalog } from './catalog.js';
|
|
3
3
|
import { DecisionCatalogError, UnknownDecisionError, UnknownDecisionMakerError } from './errors.js';
|
|
4
4
|
import { buildState, renderQuestion, resolveDecisionInput } from './params.js';
|
|
@@ -165,6 +165,10 @@ export class DecisionHub {
|
|
|
165
165
|
const maker = await this.registry.resolve(makerName);
|
|
166
166
|
inAsk = true;
|
|
167
167
|
const answers = await maker.ask(request);
|
|
168
|
+
// Every resolved maker crosses the shared validator — a directly registered maker would
|
|
169
|
+
// otherwise skip the check createDecisionMaker applies. Inside the try: its
|
|
170
|
+
// DecisionBackendError is an answer failure, never a caller error.
|
|
171
|
+
validateAnswers(request.questions, answers);
|
|
168
172
|
const answer = answers[definition.id];
|
|
169
173
|
if (answer === undefined || answer.kind !== definition.type) {
|
|
170
174
|
return this.fallbackResult(definition, makerName, 'error', null, start);
|
package/dist/registry.d.ts
CHANGED
|
@@ -38,5 +38,12 @@ export declare class DecisionMakerRegistry {
|
|
|
38
38
|
* so every caller gets the same instance; a rejected run is cleared so a later resolve retries.
|
|
39
39
|
*/
|
|
40
40
|
resolve(name: string): Promise<DecisionMaker>;
|
|
41
|
+
/**
|
|
42
|
+
* Release the resources of already-resolved makers — a `laya-local` maker holds a warm Python
|
|
43
|
+
* worker whose open pipes keep the calling process alive until it is closed. An unresolved
|
|
44
|
+
* factory is never run to be disposed, and every entry returns to its unresolved state so a
|
|
45
|
+
* later `resolve` rebuilds a working maker instead of handing back a closed one.
|
|
46
|
+
*/
|
|
47
|
+
dispose(name?: string): Promise<void>;
|
|
41
48
|
}
|
|
42
49
|
//# sourceMappingURL=registry.d.ts.map
|
package/dist/registry.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC7G,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGlF,wHAAwH;AACxH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;AAEzF,4GAA4G;AAC5G,MAAM,WAAW,mBAAmB;IAChC,oGAAoG;IACpG,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;IACnF,mHAAmH;IACnH,QAAQ,CAAC,aAAa,CAAC,EAAE;QAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;QAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAA;KAAE,CAAC;CACjH;AAID;;;;;;;;GAQG;AACH,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAGpB;IAEJ,sFAAsF;gBAC1E,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,KAAK,CAAA;KAAE;IAqBhE,oGAAoG;IACpG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;IAWjD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,KAAK,IAAI,MAAM,EAAE;IAIjB;;;;OAIG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,KAAK,aAAa,EAAE,KAAK,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC7G,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjF,OAAO,EAAoB,KAAK,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGlF,wHAAwH;AACxH,MAAM,MAAM,WAAW,GAAG,aAAa,GAAG,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC;AAEzF,4GAA4G;AAC5G,MAAM,WAAW,mBAAmB;IAChC,oGAAoG;IACpG,QAAQ,CAAC,YAAY,CAAC,EAAE,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC,CAAC;IACnF,mHAAmH;IACnH,QAAQ,CAAC,aAAa,CAAC,EAAE;QAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,eAAe,CAAC;QAAC,QAAQ,CAAC,YAAY,CAAC,EAAE,iBAAiB,CAAA;KAAE,CAAC;CACjH;AAID;;;;;;;;GAQG;AACH,qBAAa,qBAAqB;IAC9B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAGpB;IAEJ,sFAAsF;gBAC1E,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,KAAK,CAAA;KAAE;IAqBhE,oGAAoG;IACpG,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;IAWjD,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO;IAI1B,KAAK,IAAI,MAAM,EAAE;IAIjB;;;;OAIG;IACG,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC;IA4BnD;;;;;OAKG;IACG,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAc9C"}
|
package/dist/registry.js
CHANGED
|
@@ -82,4 +82,25 @@ export class DecisionMakerRegistry {
|
|
|
82
82
|
}
|
|
83
83
|
return await entry.pending;
|
|
84
84
|
}
|
|
85
|
+
/**
|
|
86
|
+
* Release the resources of already-resolved makers — a `laya-local` maker holds a warm Python
|
|
87
|
+
* worker whose open pipes keep the calling process alive until it is closed. An unresolved
|
|
88
|
+
* factory is never run to be disposed, and every entry returns to its unresolved state so a
|
|
89
|
+
* later `resolve` rebuilds a working maker instead of handing back a closed one.
|
|
90
|
+
*/
|
|
91
|
+
async dispose(name) {
|
|
92
|
+
const names = name === undefined ? this.names() : [name];
|
|
93
|
+
for (const key of names) {
|
|
94
|
+
const entry = this.entries.get(key);
|
|
95
|
+
if (entry === undefined)
|
|
96
|
+
continue;
|
|
97
|
+
// Wait out an in-flight factory rather than releasing around it: it may complete after
|
|
98
|
+
// this loop and leave a live worker with nobody holding a reference. A failed run has
|
|
99
|
+
// nothing to release.
|
|
100
|
+
const maker = entry.maker ?? (await entry.pending?.catch(() => undefined));
|
|
101
|
+
entry.maker = undefined;
|
|
102
|
+
entry.pending = undefined;
|
|
103
|
+
await maker?.dispose?.();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
85
106
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gobing-ai/ts-ai-decision",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.24",
|
|
4
4
|
"description": "@gobing-ai/ts-ai-decision — Declarative YAML decision catalog over the ts-ai-runner DecisionMaker surface.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"typescript",
|
|
@@ -51,10 +51,10 @@
|
|
|
51
51
|
"release": "echo 'Manual publish is disabled. Releases go through GitHub Actions via Trusted Publishing — push a tag: git tag @gobing-ai/ts-ai-decision-v<version> && git push --tags' && exit 1"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@gobing-ai/ts-ai-runner": "^0.5.
|
|
55
|
-
"@gobing-ai/ts-decision-fm": "^0.5.
|
|
56
|
-
"@gobing-ai/ts-laya-mlx": "^0.5.
|
|
57
|
-
"@gobing-ai/ts-runtime": "^0.5.
|
|
54
|
+
"@gobing-ai/ts-ai-runner": "^0.5.24",
|
|
55
|
+
"@gobing-ai/ts-decision-fm": "^0.5.24",
|
|
56
|
+
"@gobing-ai/ts-laya-mlx": "^0.5.24",
|
|
57
|
+
"@gobing-ai/ts-runtime": "^0.5.24",
|
|
58
58
|
"zod": "^4.1.0"
|
|
59
59
|
},
|
|
60
60
|
"devDependencies": {
|
package/src/hub.ts
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
type Json,
|
|
7
7
|
type Question,
|
|
8
8
|
q,
|
|
9
|
+
validateAnswers,
|
|
9
10
|
} from '@gobing-ai/ts-ai-runner';
|
|
10
11
|
import { type CatalogLoadOptions, loadDecisionCatalog } from './catalog';
|
|
11
12
|
import { DecisionCatalogError, UnknownDecisionError, UnknownDecisionMakerError } from './errors';
|
|
@@ -289,6 +290,10 @@ export class DecisionHub {
|
|
|
289
290
|
const maker = await this.registry.resolve(makerName);
|
|
290
291
|
inAsk = true;
|
|
291
292
|
const answers = await maker.ask(request);
|
|
293
|
+
// Every resolved maker crosses the shared validator — a directly registered maker would
|
|
294
|
+
// otherwise skip the check createDecisionMaker applies. Inside the try: its
|
|
295
|
+
// DecisionBackendError is an answer failure, never a caller error.
|
|
296
|
+
validateAnswers(request.questions, answers);
|
|
292
297
|
const answer: Answer | undefined = answers[definition.id];
|
|
293
298
|
if (answer === undefined || answer.kind !== definition.type) {
|
|
294
299
|
return this.fallbackResult(definition, makerName, 'error', null, start);
|
package/src/registry.ts
CHANGED
|
@@ -105,4 +105,25 @@ export class DecisionMakerRegistry {
|
|
|
105
105
|
}
|
|
106
106
|
return await entry.pending;
|
|
107
107
|
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Release the resources of already-resolved makers — a `laya-local` maker holds a warm Python
|
|
111
|
+
* worker whose open pipes keep the calling process alive until it is closed. An unresolved
|
|
112
|
+
* factory is never run to be disposed, and every entry returns to its unresolved state so a
|
|
113
|
+
* later `resolve` rebuilds a working maker instead of handing back a closed one.
|
|
114
|
+
*/
|
|
115
|
+
async dispose(name?: string): Promise<void> {
|
|
116
|
+
const names = name === undefined ? this.names() : [name];
|
|
117
|
+
for (const key of names) {
|
|
118
|
+
const entry = this.entries.get(key);
|
|
119
|
+
if (entry === undefined) continue;
|
|
120
|
+
// Wait out an in-flight factory rather than releasing around it: it may complete after
|
|
121
|
+
// this loop and leave a live worker with nobody holding a reference. A failed run has
|
|
122
|
+
// nothing to release.
|
|
123
|
+
const maker = entry.maker ?? (await entry.pending?.catch(() => undefined));
|
|
124
|
+
entry.maker = undefined;
|
|
125
|
+
entry.pending = undefined;
|
|
126
|
+
await maker?.dispose?.();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
108
129
|
}
|