@plumbus/ai-decision-laya 0.2.1 → 0.2.3
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 +9 -1
- package/README.md +166 -18
- package/dist/.tsbuildinfo +1 -1
- package/instructions/README.md +8 -3
- package/instructions/framework.md +13 -1
- package/instructions/testing.md +5 -0
- package/package.json +3 -3
- package/service/test_audit_round_two.py +8 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.2.
|
|
3
|
+
## 0.2.3 — 2026-10-08
|
|
4
|
+
|
|
5
|
+
- The README now uses the standard Plumbus package format (badges, Why?, What you get, When to use this vs alternatives, Status, Pricing, Configuration, Key gotchas, Links), keeping all of its earlier content. Runtime behavior, the Python reference service, and the core peer range are unchanged from 0.2.2.
|
|
6
|
+
- The published dependency on `@plumbus/ai-decision` is now `~0.2.3` (was `~0.2.2`), following the shared package's current version. Shared 0.2.3 validates Laya answers exactly as 0.2.2 did.
|
|
7
|
+
- The packaged offline service test `service/test_audit_round_two.py` checks connection capacity by reading the 503 response without sending a request body, so it no longer races the server closing the rejected connection. `service/server.py` is unchanged.
|
|
8
|
+
|
|
9
|
+
## 0.2.2 — 2026-09-23
|
|
10
|
+
|
|
11
|
+
- Document core 0.7.4+ classification with per-call provider/model and probability threshold. Link the packaged classification recipe from agent instructions and correct stale package-only guidance. Core peer compatibility remains `0.7.x`.
|
|
4
12
|
|
|
5
13
|
- Run offline Laya tests with one worker and serial files. One-off smoke runs now stop servers they start on both success and failure; explicit persistent servers and the model cache are preserved.
|
|
6
14
|
|
package/README.md
CHANGED
|
@@ -1,25 +1,124 @@
|
|
|
1
1
|
# @plumbus/ai-decision-laya
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> **Self-hosted Laya decisions for [Plumbus](https://github.com/plumbus-framework/plumbus) AI.** Laya provider for self-hosted typed decision inference, with a persistent Python reference service, called through `ctx.ai.decide()` / `ctx.ai.classify()`.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@plumbus/ai-decision-laya)
|
|
6
|
+
[](https://github.com/plumbus-framework/plumbus/blob/main/LICENSE)
|
|
7
|
+
[](https://www.npmjs.com/package/@plumbus/core)
|
|
8
|
+
|
|
9
|
+
## What is this?
|
|
10
|
+
|
|
11
|
+
[Plumbus](https://github.com/plumbus-framework/plumbus) is an **AI-native, contract-driven TypeScript application framework**. Apps call `ctx.ai.decide()` (core 0.7.3+) and `ctx.ai.classify()` (core 0.7.4+) against decision adapters registered under `decisions.providers`, separately from text-generation providers.
|
|
12
|
+
|
|
13
|
+
`@plumbus/ai-decision-laya` is the **self-hosted Laya adapter**. It sends the shared [`@plumbus/ai-decision`](../ai-decision/) contract over the System One HTTP protocol to a Laya server you run, and checks the answers with the shared validator. The package ships that server: a persistent Python reference service in `service/` (`server.py`, `requirements.txt`, a CPU `Dockerfile`, offline service contract tests) that loads pinned `laya==0.3.5` and keeps the selected checkpoints resident. Python inference stays outside Node.js; any service that implements the same protocol works too.
|
|
14
|
+
|
|
15
|
+
## Why?
|
|
16
|
+
|
|
17
|
+
Typed decision models answer bounded questions (one option from a list, a level on an ordered scale, a probability) instead of generating text, so Plumbus registers them apart from text-generation providers. Each vendor ships as its own optional package:
|
|
18
|
+
|
|
19
|
+
- Apps install only the provider they use; no provider depends on another.
|
|
20
|
+
- The contract, validation, and transport live in `@plumbus/ai-decision`, so every provider takes the same request and core checks every result the same way.
|
|
21
|
+
|
|
22
|
+
This package gives apps that keep inference on their own infrastructure a registered decision provider with no hosted API.
|
|
23
|
+
|
|
24
|
+
## What you get
|
|
25
|
+
|
|
26
|
+
| Surface | What it does |
|
|
27
|
+
|---|---|
|
|
28
|
+
| `createLayaDecisionAdapter()` | `DecisionProviderAdapter` (provider name `laya`) for `decisions.providers` in `app/server.ts`. |
|
|
29
|
+
| System One mapping | Shared questions to the System One wire format (`probability` maps to `noul`); answers validated by `@plumbus/ai-decision`. |
|
|
30
|
+
| Checkpoint routing | `model: 'auto'` routes by language; an explicit `model` selects a configured checkpoint. Every response must name the checkpoint that answered. |
|
|
31
|
+
| Cost estimate | Optional `costPerRequestUsd`, an operator estimate of infrastructure cost; otherwise cost is `null`. |
|
|
32
|
+
| Python reference service | `service/`: `GET /healthz` and bearer-authenticated `POST /v1/systemone`, with bounded requests, connection capacity, and one inference at a time. |
|
|
33
|
+
| Re-exports | `DecisionProviderError` and the protocol types `DecisionProviderAdapter`, `DecisionQuestions`, `DecisionRequest`, `DecisionResult`. |
|
|
34
|
+
|
|
35
|
+
## When to use this vs alternatives
|
|
36
|
+
|
|
37
|
+
| You want | Reach for |
|
|
38
|
+
|---|---|
|
|
39
|
+
| Text responses, structured generation, or embeddings | Built-in text providers in `@plumbus/core` |
|
|
40
|
+
| Labels from a generative model | `ctx.ai.classify()` with a text provider (the default) |
|
|
41
|
+
| Hosted typed decisions from TypeSafe/Jev | [`@plumbus/ai-decision-typesafe`](../ai-decision-typesafe/) |
|
|
42
|
+
| Typed decisions on your own servers, no hosted API | **`@plumbus/ai-decision-laya`** (this package) |
|
|
43
|
+
| Hosted typed decisions from OpenAI (public beta) | [`@plumbus/ai-decision-openai`](../ai-decision-openai/) |
|
|
44
|
+
| Named contracts, answer types, or your own adapter | [`@plumbus/ai-decision`](../ai-decision/) |
|
|
45
|
+
|
|
46
|
+
## Status
|
|
47
|
+
|
|
48
|
+
Optional decision provider, version `0.2.3` (version-locked **`0.2.x`**); required peer `@plumbus/core` exactly **`0.7.x`**; Node.js 20.6+. **Runtime floor:** `ctx.ai.decide()` needs `@plumbus/core` **≥ 0.7.3** and `ctx.ai.classify({ provider })` needs **≥ 0.7.4**; agent wiring **v17** (core 0.7.4+) links these instructions. Depends on `@plumbus/ai-decision` `~0.2.3`. Install alone is not enough until the adapter is registered under `decisions.providers` and a Laya server is running. Python/model dependencies are installed separately from pnpm.
|
|
49
|
+
|
|
50
|
+
Not included: vendor model catalogs, automatic environment provider discovery, and dedicated decision CLI commands.
|
|
51
|
+
|
|
52
|
+
Release notes: [changelog](./CHANGELOG.md) and [version/upgrade guide](../../docs/upgrading-classification.md).
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
pnpm add @plumbus/ai-decision-laya
|
|
58
|
+
```
|
|
6
59
|
|
|
7
|
-
Version `0.2.1`; required peer `@plumbus/core` exactly `0.7.x`; Node.js 20.6+.
|
|
8
60
|
Install explicitly with `pnpm add @plumbus/ai-decision-laya`. Provider packages install
|
|
9
|
-
`@plumbus/ai-decision` transitively. There is no dependency on the other
|
|
61
|
+
`@plumbus/ai-decision` transitively. There is no dependency on the other decision providers.
|
|
62
|
+
|
|
63
|
+
Peer (copy literally): `@plumbus/core` `0.7.x`. See `node_modules/@plumbus/core/instructions/peer-dependencies.md`.
|
|
64
|
+
|
|
65
|
+
If agent wiring predates the decision provider instructions, refresh:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
plumbus init --patch --agent all
|
|
69
|
+
plumbus doctor
|
|
70
|
+
```
|
|
10
71
|
|
|
11
|
-
|
|
72
|
+
Then start a Laya server. The [Laya service](../../docs/ai/decision-providers.md#laya-service) and [live test environment](../../docs/ai/decision-providers.md#providing-a-live-test-environment) sections cover the CPU container, a plain Python environment, checkpoints, and GPUs.
|
|
73
|
+
|
|
74
|
+
## Quick start
|
|
12
75
|
|
|
13
76
|
Core `0.7.3+` provides `ctx.ai.decide()` with shared validation, security, budgets,
|
|
14
77
|
and per-call cost recording. Define named contracts with `defineDecision` from
|
|
15
78
|
`@plumbus/ai-decision`, and export explicit provider registration as `decisions`
|
|
16
79
|
from `app/server.ts` for API and worker processes. See the
|
|
17
80
|
[decision integration guide](../../docs/ai/decision-providers.md#application-integration-and-cost-recording).
|
|
81
|
+
|
|
82
|
+
```ts
|
|
83
|
+
// app/server.ts
|
|
84
|
+
import { createLayaDecisionAdapter } from '@plumbus/ai-decision-laya';
|
|
85
|
+
|
|
86
|
+
export const decisions = {
|
|
87
|
+
providers: {
|
|
88
|
+
laya: createLayaDecisionAdapter({
|
|
89
|
+
baseUrl: process.env.LAYA_BASE_URL ?? 'http://127.0.0.1:8080/v1',
|
|
90
|
+
apiKey: process.env.LAYA_API_KEY,
|
|
91
|
+
// costPerRequestUsd: optional operator estimate in USD; omit to report unknown cost
|
|
92
|
+
}),
|
|
93
|
+
},
|
|
94
|
+
defaultProvider: 'laya',
|
|
95
|
+
};
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Then, inside a capability handler:
|
|
99
|
+
|
|
100
|
+
```ts
|
|
101
|
+
const result = await ctx.ai.decide({
|
|
102
|
+
state: { message: input.message },
|
|
103
|
+
questions: {
|
|
104
|
+
refund: { type: 'probability', instructions: 'Does the customer request a refund?' },
|
|
105
|
+
},
|
|
106
|
+
signal: ctx.signal,
|
|
107
|
+
});
|
|
108
|
+
result.answers.refund.probability; // P(true), not a boolean
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Core **0.7.4+** also supports `ctx.ai.classify({ text, labels, provider, model, threshold })`
|
|
112
|
+
for generative or decision models. Start with
|
|
113
|
+
`node_modules/@plumbus/core/instructions/ai-classification.md` for registration,
|
|
114
|
+
model defaults, multi-label semantics, and cost recording. For Laya automatic language
|
|
115
|
+
routing, use `provider: 'laya', model: 'auto'`.
|
|
116
|
+
|
|
117
|
+
### Infrastructure / smoke testing
|
|
118
|
+
|
|
18
119
|
Direct adapter calls remain useful for infrastructure tests and do not record costs
|
|
19
120
|
in core. Keep these adapters separate from the text-generation provider registry.
|
|
20
121
|
|
|
21
|
-
## Quick start (infrastructure / smoke testing)
|
|
22
|
-
|
|
23
122
|
```ts
|
|
24
123
|
import { createLayaDecisionAdapter } from '@plumbus/ai-decision-laya';
|
|
25
124
|
|
|
@@ -31,22 +130,71 @@ const result = await adapter.decide({
|
|
|
31
130
|
console.log(result.answers.refund.probability);
|
|
32
131
|
```
|
|
33
132
|
|
|
34
|
-
|
|
35
133
|
Business logic belongs in Plumbus capabilities/flows and `ctx.*`. These examples
|
|
36
134
|
exercise the provider protocol only; they do not provide the core execution lifecycle.
|
|
37
135
|
|
|
38
|
-
##
|
|
136
|
+
## Pricing (important)
|
|
137
|
+
|
|
138
|
+
Laya runs on your infrastructure, so there is no provider price list. The adapter reports `cost: null` unless you set `costPerRequestUsd`, an explicit operator estimate for infrastructure usage; zero is accepted only when deliberately configured.
|
|
139
|
+
|
|
140
|
+
Unknown cost is not free. Core records such calls as unpriced, and when a dollar budget is configured, unpriced prior calls block further calls.
|
|
141
|
+
|
|
142
|
+
## Configuration
|
|
143
|
+
|
|
144
|
+
| Option | Default | Notes |
|
|
145
|
+
| --- | --- | --- |
|
|
146
|
+
| `baseUrl` | required | Service API prefix such as `http://127.0.0.1:8080/v1`; the adapter appends `/systemone` |
|
|
147
|
+
| `apiKey` | none | Bearer key; must match the service's `LAYA_API_KEY` |
|
|
148
|
+
| `model` | `auto` | `auto` omits the model override so the service routes by language; otherwise a checkpoint the server preloads |
|
|
149
|
+
| `language` | none | Sent as the service's optional `lang` field |
|
|
150
|
+
| `costPerRequestUsd` | none (cost `null`) | Operator estimate of infrastructure cost per request |
|
|
151
|
+
| `timeoutMs` | `30000` | Whole-call deadline, at most five minutes |
|
|
152
|
+
| `maxRetries` | `2` | Retries HTTP 429 and transient 5xx only (0–5) |
|
|
153
|
+
| `fetch` | `globalThis.fetch` | Injected HTTP implementation for tests |
|
|
154
|
+
|
|
155
|
+
The reference service reads `LAYA_API_KEY` (required), `LAYA_MODELS` (`english`, `multilingual`, and/or `typed-decisions`; default `english`), `LAYA_DEVICE` (`cpu` or `cuda`), `LAYA_MAX_CONNECTIONS` (1–128, default 32), `LAYA_HOST`, and `LAYA_PORT` (default `127.0.0.1:8080`; the Dockerfile binds `0.0.0.0`). Use `LAYA_MODELS=english,multilingual` for automatic routing across those languages, or a single checkpoint for dedicated workloads.
|
|
156
|
+
|
|
157
|
+
## Key gotchas
|
|
158
|
+
|
|
159
|
+
- **Register under `decisions`, not as a text provider.** Export `decisions = { providers, defaultProvider }` from `app/server.ts`; API and workers share it. Provider names must be distinct across the text and decision registries.
|
|
160
|
+
- **Direct adapter calls skip core.** They do not enforce core's PII checks, budgets, identity attribution, action confirmation, or ledger hooks. Use `ctx.ai.decide()` / `ctx.ai.classify()` in capabilities and flows.
|
|
161
|
+
- **Unknown cost is `null`, not free.** Set `costPerRequestUsd` if budgets should count Laya calls.
|
|
162
|
+
- **Failed calls are recorded.** Core records one row per dispatched call, including failed and cancelled calls; answer-validation failures keep the known model, usage, and configured cost.
|
|
163
|
+
- **Probabilities are not permissions.** A probability is P(true), not a boolean, and a high confidence value is not authorization or proof of correctness. Validate thresholds on the actual task, model, and language.
|
|
164
|
+
- **Retries can repeat work.** The transport retries HTTP 429, 500, 502, 503, 504, and 529 (two retries by default, honoring `Retry-After`); repeated requests can still incur work, with no exactly-once guarantee.
|
|
165
|
+
- **Python is not installed by pnpm.** Model dependencies and weights are substantial; the first run downloads a checkpoint.
|
|
166
|
+
- **One inference per service process.** A busy device returns 503 with `Retry-After`; deploy replicas for concurrency. An HTTP cancellation cannot interrupt a GPU kernel already running in the Python process.
|
|
167
|
+
- **Routing identity is required.** A response without the answering checkpoint fails as `invalid_response`; custom compatible services must return `routing: { model, repo, reason }`.
|
|
168
|
+
- **Checkpoints are fixed per server.** A request cannot load a checkpoint outside `LAYA_MODELS`; explicit model selection takes precedence over language routing.
|
|
169
|
+
- **Long input is rejected, not truncated.** The service returns HTTP 422 when the tokenizer budget would truncate a question, option, or state. The check is tied to Laya 0.3.5; treat a Laya upgrade as requiring boundary tests.
|
|
170
|
+
- **Weights are not pinned.** Package pinning does not pin Hugging Face weight revisions; keep a tested model cache (`HF_HUB_OFFLINE=1` can reuse it).
|
|
171
|
+
- **Keep the service private.** Default binding is loopback; put the service behind your deployment's private networking/TLS proxy if accessed remotely.
|
|
172
|
+
|
|
173
|
+
## Documentation / Agent recipes
|
|
174
|
+
|
|
175
|
+
- **Concept docs:** read the [decision providers guide](https://github.com/plumbus-framework/plumbus/blob/main/docs/ai/decision-providers.md)
|
|
176
|
+
for the complete contract, failure behavior, pricing, deployment, and live test environment.
|
|
177
|
+
Local monorepo copy: [docs/ai/decision-providers.md](../../docs/ai/decision-providers.md).
|
|
178
|
+
- **Classification recipe** (after install): `node_modules/@plumbus/core/instructions/ai-classification.md`
|
|
179
|
+
- **Live smoke (monorepo):** [`examples/ai-decision-smoke`](../../examples/ai-decision-smoke) starts a CPU Laya server and runs this adapter and TypeSafe against it with real inference; `scripts/smoke.mjs` sends one live request to `LAYA_BASE_URL` (default `http://127.0.0.1:8080/v1`) when `PLUMBUS_LIVE_DECISION_TESTS=1` and `LAYA_API_KEY` are set (a repository tool, not in the npm package).
|
|
180
|
+
- **Agent recipes** (ship in this package, readable from `node_modules/@plumbus/ai-decision-laya/instructions/`):
|
|
181
|
+
- [Instructions index](instructions/README.md)
|
|
182
|
+
- [Framework boundary and usage](instructions/framework.md)
|
|
183
|
+
- [Testing](instructions/testing.md)
|
|
39
184
|
|
|
40
|
-
|
|
41
|
-
for the complete contract, failure behavior, pricing, deployment, and live test environment.
|
|
42
|
-
Local monorepo copy: [docs/ai/decision-providers.md](../../docs/ai/decision-providers.md).
|
|
185
|
+
## The Plumbus ecosystem
|
|
43
186
|
|
|
44
|
-
|
|
187
|
+
`@plumbus/ai-decision-laya` is one package in the Plumbus framework. For the full list of packages and when to use each, see the [Plumbus monorepo README](https://github.com/plumbus-framework/plumbus#packages).
|
|
45
188
|
|
|
46
|
-
|
|
47
|
-
- [Framework boundary and usage](instructions/framework.md)
|
|
48
|
-
- [Testing](instructions/testing.md)
|
|
189
|
+
## Links
|
|
49
190
|
|
|
50
|
-
|
|
191
|
+
- **Plumbus framework** — [github.com/plumbus-framework/plumbus](https://github.com/plumbus-framework/plumbus)
|
|
192
|
+
- **Parent / peer** — [`@plumbus/core`](../plumbus-core/)
|
|
193
|
+
- **Shared contracts** — [`@plumbus/ai-decision`](../ai-decision/)
|
|
194
|
+
- **Full documentation** — [docs/](../../docs/) in the monorepo
|
|
195
|
+
- **Top-level README** — [`../../README.md`](../../README.md)
|
|
196
|
+
- **Issues** — [github.com/plumbus-framework/plumbus/issues](https://github.com/plumbus-framework/plumbus/issues)
|
|
51
197
|
|
|
52
|
-
|
|
198
|
+
## License
|
|
199
|
+
|
|
200
|
+
MIT
|