@plumbus/ai-decision-laya 0.2.0 → 0.2.1
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/CHANGELOG.md +8 -0
- package/README.md +8 -4
- package/dist/.tsbuildinfo +1 -1
- package/dist/laya-adapter.d.ts.map +1 -1
- package/dist/laya-adapter.js +19 -2
- package/dist/laya-adapter.js.map +1 -1
- package/instructions/framework.md +4 -3
- package/instructions/testing.md +5 -0
- package/package.json +3 -3
- package/service/test_audit_round_two.py +10 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"laya-adapter.d.ts","sourceRoot":"","sources":["../src/laya-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC7B,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wFAAwF;AACxF,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,yBAAyB,GAChC,uBAAuB,
|
|
1
|
+
{"version":3,"file":"laya-adapter.d.ts","sourceRoot":"","sources":["../src/laya-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,kBAAkB,EACvB,KAAK,uBAAuB,EAC7B,MAAM,sBAAsB,CAAC;AAG9B,MAAM,WAAW,yBAA0B,SAAQ,kBAAkB;IACnE,0EAA0E;IAC1E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8EAA8E;IAC9E,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B;AAED,wFAAwF;AACxF,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,yBAAyB,GAChC,uBAAuB,CAgEzB"}
|
package/dist/laya-adapter.js
CHANGED
|
@@ -24,9 +24,26 @@ export function createLayaDecisionAdapter(config) {
|
|
|
24
24
|
...(model === 'auto' ? {} : { model }),
|
|
25
25
|
...(settings.data.language ? { lang: settings.data.language } : {}),
|
|
26
26
|
}, input);
|
|
27
|
-
|
|
27
|
+
let result;
|
|
28
|
+
try {
|
|
29
|
+
result = parseDecisionResponse(wire, input.questions, 'laya');
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (error instanceof DecisionProviderError && error.usage && error.model) {
|
|
33
|
+
throw new DecisionProviderError('laya', error.kind, error.message, {
|
|
34
|
+
model: error.model,
|
|
35
|
+
usage: error.usage,
|
|
36
|
+
cost: settings.data.costPerRequestUsd ?? null,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
throw error;
|
|
40
|
+
}
|
|
28
41
|
if (!z.object({ routing: z.object({}) }).safeParse(result).success) {
|
|
29
|
-
throw new DecisionProviderError('laya', 'invalid_response', 'Laya response is missing checkpoint routing identity', {
|
|
42
|
+
throw new DecisionProviderError('laya', 'invalid_response', 'Laya response is missing checkpoint routing identity', {
|
|
43
|
+
model: result.model,
|
|
44
|
+
usage: result.usage,
|
|
45
|
+
cost: settings.data.costPerRequestUsd ?? null,
|
|
46
|
+
});
|
|
30
47
|
}
|
|
31
48
|
const cost = settings.data.costPerRequestUsd ?? null;
|
|
32
49
|
return {
|
package/dist/laya-adapter.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"laya-adapter.js","sourceRoot":"","sources":["../src/laya-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,2BAA2B,EAC3B,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,GAGxB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,CAAC,EAAE,MAAM,mBAAmB,CAAC;AAUtC,wFAAwF;AACxF,MAAM,UAAU,yBAAyB,CACvC,MAAiC;IAEjC,MAAM,QAAQ,GAAG,CAAC;SACf,MAAM,CAAC;QACN,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC;QACxD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,QAAQ,EAAE;QACrD,iBAAiB,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE,CAAC,QAAQ,EAAE;KAChE,CAAC;SACD,SAAS,CAAC,MAAM,CAAC,CAAC;IACrB,IAAI,CAAC,QAAQ,CAAC,OAAO;QACnB,MAAM,IAAI,qBAAqB,CAC7B,MAAM,EACN,eAAe,EACf,qDAAqD,CACtD,CAAC;IACJ,MAAM,IAAI,GAAG,2BAA2B,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzD,OAAO;QACL,IAAI,EAAE,MAAM;QACZ,KAAK,CAAC,MAAM,CAAC,OAAO;YAClB,MAAM,KAAK,GAAG,uBAAuB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;YACvD,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;YAChC,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC;YACjD,MAAM,IAAI,GAAG,MAAM,IAAI,CACrB;gBACE,KAAK,EAAE,KAAK,CAAC,KAAK;gBAClB,SAAS,EAAE,oBAAoB,CAAC,KAAK,CAAC,SAAS,CAAC;gBAChD,GAAG,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC;gBACtC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACpE,EACD,KAAK,CACN,CAAC;YACF,
|
|
1
|
+
{"version":3,"file":"laya-adapter.js","sourceRoot":"","sources":["../src/laya-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -33,12 +33,13 @@ console.log(result.answers.refund.probability);
|
|
|
33
33
|
1. Keep capabilities, flows, access policy and `ctx.*` as the application implementation path.
|
|
34
34
|
2. Construct adapters at a server-owned infrastructure boundary and inject them. Keep keys on the server.
|
|
35
35
|
3. Treat direct adapter usage as protocol integration, not a replacement for core's security/budget/audit lifecycle.
|
|
36
|
-
4.
|
|
36
|
+
4. With core 0.7.3+, use `ctx.ai.decide()` in capabilities/flows. Export `decisions = { providers, defaultProvider }` from `app/server.ts`; API and workers share it. Do not register decision adapters as completion providers.
|
|
37
37
|
5. Preserve distributions and provider confidence separately. A high confidence value is not authorization or proof of correctness.
|
|
38
38
|
6. Validate thresholds on the actual task/model/language. Unknown cost is `null`, not free.
|
|
39
|
-
7. Pass
|
|
39
|
+
7. Pass `signal: ctx.signal` and `timeoutMs` where needed. Flow steps supply their signal by default.
|
|
40
40
|
8. Keep Python inference outside Node.js. Use the packaged Laya service or implement its documented HTTP protocol.
|
|
41
|
-
9.
|
|
41
|
+
9. Define contracts using `defineDecision` from `@plumbus/ai-decision`; CLI startup discovers `app/decisions/`. No automatic environment provider discovery or dedicated decision CLI commands are provided.
|
|
42
|
+
10. Core records one `operation: decide` row per dispatched logical call, including failed/cancelled calls, with tenant/actor and `costContext`. Persist it in the existing `onAICostRecorded` hook. Unknown cost is null; never convert it to free usage.
|
|
42
43
|
|
|
43
44
|
Chat, voice and MCP still consume Plumbus capabilities; this package does not
|
|
44
45
|
introduce a parallel runtime or transport for those surfaces.
|
package/instructions/testing.md
CHANGED
|
@@ -17,3 +17,8 @@ after building. Scripts are repository tools, not installed core CLI commands.
|
|
|
17
17
|
Validate choices, scores, probabilities, actual model/routing, usage and unknown
|
|
18
18
|
cost handling. Measure live accuracy and calibration separately from connection
|
|
19
19
|
success. Do not assert a universal confidence cutoff or guaranteed live label.
|
|
20
|
+
|
|
21
|
+
For core 0.7.3+ integration tests, configure `mockAI({ decide: result })` or a real
|
|
22
|
+
`createAIService({ decisions, costTracker, onAICostRecorded })` with injected
|
|
23
|
+
provider fetch. Assert exactly one cost row, identity, actual model/usage, unknown
|
|
24
|
+
cost handling, billed validation failures, and budget rejection before dispatch.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plumbus/ai-decision-laya",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Self-hosted Laya typed decision adapter and Python reference service for Plumbus.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
"@types/node": "^25.4.0",
|
|
44
44
|
"typescript": "^5.7.0",
|
|
45
45
|
"vitest": "^3.2.4",
|
|
46
|
-
"@plumbus/core": "0.7.
|
|
46
|
+
"@plumbus/core": "0.7.3"
|
|
47
47
|
},
|
|
48
48
|
"dependencies": {
|
|
49
|
-
"@plumbus/ai-decision": "~0.2.
|
|
49
|
+
"@plumbus/ai-decision": "~0.2.1"
|
|
50
50
|
},
|
|
51
51
|
"scripts": {
|
|
52
52
|
"build": "tsc -b",
|
|
@@ -93,6 +93,14 @@ class ServiceRoundTwo(unittest.TestCase):
|
|
|
93
93
|
return original(body)
|
|
94
94
|
backend.predict = wait
|
|
95
95
|
server = create_server(("127.0.0.1", 0), backend, "test-key", max_connections=1)
|
|
96
|
+
released = threading.Event()
|
|
97
|
+
process_request_thread = server.process_request_thread
|
|
98
|
+
def observe_handler_exit(*args):
|
|
99
|
+
try:
|
|
100
|
+
process_request_thread(*args)
|
|
101
|
+
finally:
|
|
102
|
+
released.set()
|
|
103
|
+
server.process_request_thread = observe_handler_exit
|
|
96
104
|
thread = threading.Thread(target=lambda: server.serve_forever(poll_interval=0.01), daemon=True)
|
|
97
105
|
results = []
|
|
98
106
|
first = threading.Thread(target=lambda: results.append(self.send(address=server.server_address)[0]))
|
|
@@ -104,6 +112,8 @@ class ServiceRoundTwo(unittest.TestCase):
|
|
|
104
112
|
finish.set()
|
|
105
113
|
first.join(2)
|
|
106
114
|
self.assertEqual(results, [200])
|
|
115
|
+
# Receiving the body can precede the server thread's semaphore release.
|
|
116
|
+
self.assertTrue(released.wait(2))
|
|
107
117
|
self.assertEqual(self.send(address=server.server_address)[0], 200)
|
|
108
118
|
finally:
|
|
109
119
|
finish.set()
|