@mlola/decision-jev 0.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/LICENSE +21 -0
- package/README.md +18 -0
- package/dist/client.d.ts +39 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +119 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/llm-providers.d.ts +57 -0
- package/dist/llm-providers.d.ts.map +1 -0
- package/dist/llm-providers.js +279 -0
- package/dist/llm-providers.js.map +1 -0
- package/dist/provider.d.ts +26 -0
- package/dist/provider.d.ts.map +1 -0
- package/dist/provider.js +79 -0
- package/dist/provider.js.map +1 -0
- package/dist/questions.d.ts +26 -0
- package/dist/questions.d.ts.map +1 -0
- package/dist/questions.js +79 -0
- package/dist/questions.js.map +1 -0
- package/dist/state.d.ts +14 -0
- package/dist/state.d.ts.map +1 -0
- package/dist/state.js +112 -0
- package/dist/state.js.map +1 -0
- package/dist/testing/index.d.ts +45 -0
- package/dist/testing/index.d.ts.map +1 -0
- package/dist/testing/index.js +263 -0
- package/dist/testing/index.js.map +1 -0
- package/package.json +57 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 MLola
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# @mlola/decision-jev
|
|
2
|
+
|
|
3
|
+
The TypeSafe Jev fast path for the
|
|
4
|
+
[MLola Browser Runtime](https://mlola.com/browser-runtime): one request per
|
|
5
|
+
decision cycle carrying the operation head plus speculative target heads, with
|
|
6
|
+
response validation before anything can execute.
|
|
7
|
+
|
|
8
|
+
Also ships the planner/text adapters for any OpenAI-compatible endpoint, and the
|
|
9
|
+
deterministic offline baselines used by tests and demos (`/testing`).
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { JevDecisionProvider, buildQuestions, renderDecisionState } from "@mlola/decision-jev";
|
|
13
|
+
import { ScriptedDecisionProvider } from "@mlola/decision-jev/testing";
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
export TYPESAFE_API_KEY=… # https://typesafe.ai
|
|
18
|
+
```
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeSafe System One (Jev) client.
|
|
3
|
+
*
|
|
4
|
+
* Contract: POST {base}/v1/systemone with {model, state, questions}; the reply
|
|
5
|
+
* carries `answers` keyed by question name. Both `state` and the questions are
|
|
6
|
+
* built by the runtime — nothing here parses model prose.
|
|
7
|
+
*/
|
|
8
|
+
import { type JevResponse } from "@mlola/browser-protocol";
|
|
9
|
+
import type { JevQuestion } from "./questions.ts";
|
|
10
|
+
export interface JevClientOptions {
|
|
11
|
+
apiKey?: string;
|
|
12
|
+
apiKeyEnv?: string;
|
|
13
|
+
baseUrl?: string;
|
|
14
|
+
path?: string;
|
|
15
|
+
model?: string;
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
/** Bounded retries for transient network/5xx failures. */
|
|
18
|
+
maxRetries?: number;
|
|
19
|
+
}
|
|
20
|
+
export interface JevCallResult {
|
|
21
|
+
response: JevResponse;
|
|
22
|
+
latencyMs: number;
|
|
23
|
+
}
|
|
24
|
+
export declare class JevClient {
|
|
25
|
+
#private;
|
|
26
|
+
readonly model: string;
|
|
27
|
+
constructor(options?: JevClientOptions);
|
|
28
|
+
get baseUrl(): string;
|
|
29
|
+
/**
|
|
30
|
+
* Opens DNS/TCP/TLS before a run is timed. The first request of a session
|
|
31
|
+
* otherwise pays a handshake premium that has nothing to do with the model.
|
|
32
|
+
*/
|
|
33
|
+
warmup(): Promise<void>;
|
|
34
|
+
decide(input: {
|
|
35
|
+
state: string;
|
|
36
|
+
questions: Record<string, JevQuestion>;
|
|
37
|
+
}): Promise<JevCallResult>;
|
|
38
|
+
}
|
|
39
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAmC,KAAK,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAC5F,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAElD,MAAM,WAAW,gBAAgB;IAC/B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,WAAW,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAMD,qBAAa,SAAS;;IACpB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAQX,OAAO,GAAE,gBAAqB;IAkB1C,IAAI,OAAO,IAAI,MAAM,CAEpB;IAED;;;OAGG;IACG,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAUvB,MAAM,CAAC,KAAK,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;KACxC,GAAG,OAAO,CAAC,aAAa,CAAC;CAuE3B"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeSafe System One (Jev) client.
|
|
3
|
+
*
|
|
4
|
+
* Contract: POST {base}/v1/systemone with {model, state, questions}; the reply
|
|
5
|
+
* carries `answers` keyed by question name. Both `state` and the questions are
|
|
6
|
+
* built by the runtime — nothing here parses model prose.
|
|
7
|
+
*/
|
|
8
|
+
import { RuntimeError, jevResponseSchema } from "@mlola/browser-protocol";
|
|
9
|
+
const DEFAULT_BASE = "https://api.typesafe.ai";
|
|
10
|
+
const DEFAULT_PATH = "/v1/systemone";
|
|
11
|
+
const DEFAULT_MODEL = "jev-latest";
|
|
12
|
+
export class JevClient {
|
|
13
|
+
model;
|
|
14
|
+
#baseUrl;
|
|
15
|
+
#path;
|
|
16
|
+
#apiKey;
|
|
17
|
+
#timeoutMs;
|
|
18
|
+
#maxRetries;
|
|
19
|
+
#warmed = false;
|
|
20
|
+
constructor(options = {}) {
|
|
21
|
+
const envKey = process.env[options.apiKeyEnv ?? "TYPESAFE_API_KEY"];
|
|
22
|
+
const apiKey = options.apiKey ?? envKey;
|
|
23
|
+
if (!apiKey || apiKey.trim().length === 0) {
|
|
24
|
+
throw new RuntimeError("PROVIDER_FAILURE", `missing Jev API key: set ${options.apiKeyEnv ?? "TYPESAFE_API_KEY"} (or pass apiKey)`, { retryable: false });
|
|
25
|
+
}
|
|
26
|
+
this.#apiKey = apiKey.trim();
|
|
27
|
+
this.#baseUrl = (options.baseUrl ?? process.env["MLOLA_JEV_BASE_URL"] ?? DEFAULT_BASE).replace(/\/+$/, "");
|
|
28
|
+
this.#path = options.path ?? DEFAULT_PATH;
|
|
29
|
+
this.model = options.model ?? process.env["MLOLA_JEV_MODEL"] ?? DEFAULT_MODEL;
|
|
30
|
+
this.#timeoutMs = options.timeoutMs ?? Number(process.env["MLOLA_JEV_TIMEOUT_MS"] ?? 20_000);
|
|
31
|
+
this.#maxRetries = options.maxRetries ?? 1;
|
|
32
|
+
}
|
|
33
|
+
get baseUrl() {
|
|
34
|
+
return this.#baseUrl;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Opens DNS/TCP/TLS before a run is timed. The first request of a session
|
|
38
|
+
* otherwise pays a handshake premium that has nothing to do with the model.
|
|
39
|
+
*/
|
|
40
|
+
async warmup() {
|
|
41
|
+
if (this.#warmed)
|
|
42
|
+
return;
|
|
43
|
+
this.#warmed = true;
|
|
44
|
+
try {
|
|
45
|
+
await this.#fetch(`${this.#baseUrl}/v1/models`, { method: "GET" }, 5000);
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
/* a cold first decision is better than refusing to run */
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
async decide(input) {
|
|
52
|
+
const started = Date.now();
|
|
53
|
+
const body = JSON.stringify({ model: this.model, state: input.state, questions: input.questions });
|
|
54
|
+
let lastError;
|
|
55
|
+
for (let attempt = 0; attempt <= this.#maxRetries; attempt += 1) {
|
|
56
|
+
try {
|
|
57
|
+
const response = await this.#fetch(`${this.#baseUrl}${this.#path}`, {
|
|
58
|
+
method: "POST",
|
|
59
|
+
headers: { "content-type": "application/json" },
|
|
60
|
+
body,
|
|
61
|
+
}, this.#timeoutMs);
|
|
62
|
+
if (response.status >= 500) {
|
|
63
|
+
lastError = new Error(`Jev returned ${response.status}`);
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
if (!response.ok) {
|
|
67
|
+
const text = await response.text().catch(() => "");
|
|
68
|
+
throw new RuntimeError("PROVIDER_FAILURE", `Jev request failed with ${response.status}`, {
|
|
69
|
+
detail: text.slice(0, 400),
|
|
70
|
+
retryable: response.status === 429,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
const json = await response.json();
|
|
74
|
+
const parsed = jevResponseSchema.safeParse(json);
|
|
75
|
+
if (!parsed.success) {
|
|
76
|
+
throw new RuntimeError("PROVIDER_FAILURE", "Jev response did not match the expected shape", {
|
|
77
|
+
detail: parsed.error.issues.map((i) => `${i.path.join(".")}: ${i.message}`).join("; "),
|
|
78
|
+
evidence: { received: Object.keys(json ?? {}).slice(0, 8) },
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
return { response: parsed.data, latencyMs: Date.now() - started };
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
if (err instanceof RuntimeError && err.code === "PROVIDER_FAILURE" && !err.retryable)
|
|
85
|
+
throw err;
|
|
86
|
+
lastError = err;
|
|
87
|
+
if (attempt < this.#maxRetries)
|
|
88
|
+
await new Promise((r) => setTimeout(r, 150 * (attempt + 1)));
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
throw new RuntimeError("PROVIDER_FAILURE", `Jev request failed: ${String(lastError)}`, {
|
|
92
|
+
cause: lastError,
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
async #fetch(url, init, timeoutMs) {
|
|
96
|
+
const controller = new AbortController();
|
|
97
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
98
|
+
timer.unref?.();
|
|
99
|
+
try {
|
|
100
|
+
return await fetch(url, {
|
|
101
|
+
...init,
|
|
102
|
+
headers: { ...(init.headers ?? {}), authorization: `Bearer ${this.#apiKey}` },
|
|
103
|
+
signal: controller.signal,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
108
|
+
throw new RuntimeError("PROVIDER_FAILURE", `Jev request timed out after ${timeoutMs}ms`, {
|
|
109
|
+
cause: err,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
throw err;
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
clearTimeout(timer);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-compatible provider adapters (PRD §17.2, §32, §44).
|
|
3
|
+
*
|
|
4
|
+
* Used for the text helper (what text to type) and the planner role (what to
|
|
5
|
+
* do next / which action to fall back to). Both are optional: the runtime works
|
|
6
|
+
* without them, escalating to the person instead, and every response is parsed
|
|
7
|
+
* against a schema before it is trusted.
|
|
8
|
+
*/
|
|
9
|
+
import { type FallbackDecisionInput, type FallbackDecisionOutput, type PlannerInput, type PlannerOutput, type PlannerProvider, type TextGenerationInput, type TextGenerationOutput, type TextProvider, type Usage } from "@mlola/browser-protocol";
|
|
10
|
+
export interface OpenAICompatibleOptions {
|
|
11
|
+
baseUrl?: string;
|
|
12
|
+
apiKey?: string;
|
|
13
|
+
apiKeyEnv?: string;
|
|
14
|
+
model?: string;
|
|
15
|
+
timeoutMs?: number;
|
|
16
|
+
temperature?: number;
|
|
17
|
+
}
|
|
18
|
+
interface ChatOptions extends OpenAICompatibleOptions {
|
|
19
|
+
system: string;
|
|
20
|
+
user: string;
|
|
21
|
+
maxTokens?: number;
|
|
22
|
+
}
|
|
23
|
+
export declare class OpenAICompatibleClient {
|
|
24
|
+
#private;
|
|
25
|
+
readonly model: string;
|
|
26
|
+
constructor(options?: OpenAICompatibleOptions);
|
|
27
|
+
chatJson(options: ChatOptions, envFallbacks?: {
|
|
28
|
+
baseUrl?: string;
|
|
29
|
+
apiKey?: string;
|
|
30
|
+
model?: string;
|
|
31
|
+
}): Promise<{
|
|
32
|
+
json: unknown;
|
|
33
|
+
usage?: Usage;
|
|
34
|
+
latencyMs: number;
|
|
35
|
+
}>;
|
|
36
|
+
}
|
|
37
|
+
export interface OpenAITextProviderOptions extends OpenAICompatibleOptions {
|
|
38
|
+
name?: string;
|
|
39
|
+
}
|
|
40
|
+
export declare class OpenAITextProvider implements TextProvider {
|
|
41
|
+
#private;
|
|
42
|
+
readonly name: string;
|
|
43
|
+
constructor(options?: OpenAITextProviderOptions);
|
|
44
|
+
generate(input: TextGenerationInput): Promise<TextGenerationOutput>;
|
|
45
|
+
}
|
|
46
|
+
export interface OpenAIPlannerProviderOptions extends OpenAICompatibleOptions {
|
|
47
|
+
name?: string;
|
|
48
|
+
}
|
|
49
|
+
export declare class OpenAIPlannerProvider implements PlannerProvider {
|
|
50
|
+
#private;
|
|
51
|
+
readonly name: string;
|
|
52
|
+
constructor(options?: OpenAIPlannerProviderOptions);
|
|
53
|
+
plan(input: PlannerInput): Promise<PlannerOutput>;
|
|
54
|
+
chooseAction(input: FallbackDecisionInput): Promise<FallbackDecisionOutput>;
|
|
55
|
+
}
|
|
56
|
+
export {};
|
|
57
|
+
//# sourceMappingURL=llm-providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-providers.d.ts","sourceRoot":"","sources":["../src/llm-providers.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAKL,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC3B,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,KAAK,eAAe,EACpB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,YAAY,EACjB,KAAK,KAAK,EACX,MAAM,yBAAyB,CAAC;AAGjC,MAAM,WAAW,uBAAuB;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,UAAU,WAAY,SAAQ,uBAAuB;IACnD,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,sBAAsB;;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAMX,OAAO,GAAE,uBAA4B;IAkB3C,QAAQ,CAAC,OAAO,EAAE,WAAW,EAAE,YAAY,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAO,GAAG,OAAO,CAAC;QACtH,IAAI,EAAE,OAAO,CAAC;QACd,KAAK,CAAC,EAAE,KAAK,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CAmEH;AAID,MAAM,WAAW,yBAA0B,SAAQ,uBAAuB;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAWD,qBAAa,kBAAmB,YAAW,YAAY;;IACrD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAMV,OAAO,GAAE,yBAA8B;IAgB7C,QAAQ,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,oBAAoB,CAAC;CAkC1E;AAID,MAAM,WAAW,4BAA6B,SAAQ,uBAAuB;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAmBD,qBAAa,qBAAsB,YAAW,eAAe;;IAC3D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;gBAMV,OAAO,GAAE,4BAAiC;IAiBhD,IAAI,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAAC,aAAa,CAAC;IA8CjD,YAAY,CAAC,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;CAiDlF"}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI-compatible provider adapters (PRD §17.2, §32, §44).
|
|
3
|
+
*
|
|
4
|
+
* Used for the text helper (what text to type) and the planner role (what to
|
|
5
|
+
* do next / which action to fall back to). Both are optional: the runtime works
|
|
6
|
+
* without them, escalating to the person instead, and every response is parsed
|
|
7
|
+
* against a schema before it is trusted.
|
|
8
|
+
*/
|
|
9
|
+
import { RuntimeError, plannerModelResponseSchema, textModelResponseSchema, } from "@mlola/browser-protocol";
|
|
10
|
+
import { renderElement } from "./state.js";
|
|
11
|
+
export class OpenAICompatibleClient {
|
|
12
|
+
model;
|
|
13
|
+
#baseUrl;
|
|
14
|
+
#apiKey;
|
|
15
|
+
#timeoutMs;
|
|
16
|
+
#temperature;
|
|
17
|
+
constructor(options = {}) {
|
|
18
|
+
const apiKey = options.apiKey ??
|
|
19
|
+
process.env[options.apiKeyEnv ?? "MLOLA_PLANNER_API_KEY"] ??
|
|
20
|
+
process.env["OPENAI_API_KEY"];
|
|
21
|
+
if (!apiKey) {
|
|
22
|
+
throw new RuntimeError("PROVIDER_FAILURE", "missing API key for the OpenAI-compatible provider", {
|
|
23
|
+
retryable: false,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
this.#apiKey = apiKey;
|
|
27
|
+
const base = options.baseUrl ?? process.env["MLOLA_PLANNER_BASE_URL"] ?? "https://api.openai.com/v1";
|
|
28
|
+
this.#baseUrl = base.replace(/\/+$/, "");
|
|
29
|
+
this.model = options.model ?? process.env["MLOLA_PLANNER_MODEL"] ?? "gpt-4o-mini";
|
|
30
|
+
this.#timeoutMs = options.timeoutMs ?? 30_000;
|
|
31
|
+
this.#temperature = options.temperature ?? 0;
|
|
32
|
+
}
|
|
33
|
+
async chatJson(options, envFallbacks = {}) {
|
|
34
|
+
const started = Date.now();
|
|
35
|
+
const base = (options.baseUrl ?? envFallbacks.baseUrl ?? this.#baseUrl).replace(/\/+$/, "");
|
|
36
|
+
const apiKey = options.apiKey ?? envFallbacks.apiKey ?? this.#apiKey;
|
|
37
|
+
const model = options.model ?? envFallbacks.model ?? this.model;
|
|
38
|
+
const controller = new AbortController();
|
|
39
|
+
const timer = setTimeout(() => controller.abort(), options.timeoutMs ?? this.#timeoutMs);
|
|
40
|
+
timer.unref?.();
|
|
41
|
+
try {
|
|
42
|
+
const response = await fetch(`${base}/chat/completions`, {
|
|
43
|
+
method: "POST",
|
|
44
|
+
headers: { "content-type": "application/json", authorization: `Bearer ${apiKey}` },
|
|
45
|
+
body: JSON.stringify({
|
|
46
|
+
model,
|
|
47
|
+
temperature: options.temperature ?? this.#temperature,
|
|
48
|
+
max_tokens: options.maxTokens ?? 700,
|
|
49
|
+
response_format: { type: "json_object" },
|
|
50
|
+
messages: [
|
|
51
|
+
{ role: "system", content: options.system },
|
|
52
|
+
{ role: "user", content: options.user },
|
|
53
|
+
],
|
|
54
|
+
}),
|
|
55
|
+
signal: controller.signal,
|
|
56
|
+
});
|
|
57
|
+
if (!response.ok) {
|
|
58
|
+
const text = await response.text().catch(() => "");
|
|
59
|
+
throw new RuntimeError("PROVIDER_FAILURE", `model request failed with ${response.status}`, {
|
|
60
|
+
detail: text.slice(0, 300),
|
|
61
|
+
retryable: response.status >= 500 || response.status === 429,
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
const payload = (await response.json());
|
|
65
|
+
const content = payload.choices?.[0]?.message?.content;
|
|
66
|
+
if (!content) {
|
|
67
|
+
throw new RuntimeError("PROVIDER_FAILURE", "model returned an empty response");
|
|
68
|
+
}
|
|
69
|
+
let json;
|
|
70
|
+
try {
|
|
71
|
+
json = JSON.parse(content);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
throw new RuntimeError("PROVIDER_FAILURE", "model response was not valid JSON", {
|
|
75
|
+
detail: content.slice(0, 300),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
const usage = {
|
|
79
|
+
provider: "openai-compatible",
|
|
80
|
+
model,
|
|
81
|
+
calls: 1,
|
|
82
|
+
...(payload.usage?.prompt_tokens !== undefined ? { inputTokens: payload.usage.prompt_tokens } : {}),
|
|
83
|
+
...(payload.usage?.completion_tokens !== undefined ? { outputTokens: payload.usage.completion_tokens } : {}),
|
|
84
|
+
};
|
|
85
|
+
return { json, usage, latencyMs: Date.now() - started };
|
|
86
|
+
}
|
|
87
|
+
catch (err) {
|
|
88
|
+
if (err instanceof Error && err.name === "AbortError") {
|
|
89
|
+
throw new RuntimeError("PROVIDER_FAILURE", "model request timed out", { cause: err });
|
|
90
|
+
}
|
|
91
|
+
throw err;
|
|
92
|
+
}
|
|
93
|
+
finally {
|
|
94
|
+
clearTimeout(timer);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
const TEXT_SYSTEM = [
|
|
99
|
+
"You produce the exact literal text that a browser agent should type into a web form field.",
|
|
100
|
+
"Reply with JSON only: {\"text\": \"...\"}.",
|
|
101
|
+
"Rules: output a single plain string; no explanations, no formatting, no URLs unless the task requires one;",
|
|
102
|
+
"never output credentials, API keys, passwords or one-time codes;",
|
|
103
|
+
"if the value cannot be determined from the task, output an empty string.",
|
|
104
|
+
"Reuse the task's own wording when it already contains the value.",
|
|
105
|
+
].join(" ");
|
|
106
|
+
export class OpenAITextProvider {
|
|
107
|
+
name;
|
|
108
|
+
#client;
|
|
109
|
+
#baseUrl;
|
|
110
|
+
#apiKey;
|
|
111
|
+
#model;
|
|
112
|
+
constructor(options = {}) {
|
|
113
|
+
this.name = options.name ?? "openai-compatible:text";
|
|
114
|
+
const apiKey = options.apiKey ?? process.env["MLOLA_TEXT_API_KEY"] ?? process.env["OPENAI_API_KEY"];
|
|
115
|
+
const baseUrl = options.baseUrl ?? process.env["MLOLA_TEXT_BASE_URL"] ?? process.env["MLOLA_PLANNER_BASE_URL"];
|
|
116
|
+
const model = options.model ?? process.env["MLOLA_TEXT_MODEL"] ?? "gpt-4o-mini";
|
|
117
|
+
if (!apiKey) {
|
|
118
|
+
throw new RuntimeError("PROVIDER_FAILURE", "missing text provider API key (MLOLA_TEXT_API_KEY)", {
|
|
119
|
+
retryable: false,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
this.#apiKey = apiKey;
|
|
123
|
+
this.#baseUrl = baseUrl;
|
|
124
|
+
this.#model = model;
|
|
125
|
+
this.#client = new OpenAICompatibleClient({ ...options, apiKey, ...(baseUrl ? { baseUrl } : {}), model });
|
|
126
|
+
}
|
|
127
|
+
async generate(input) {
|
|
128
|
+
const user = [
|
|
129
|
+
`Task: ${input.goal}`,
|
|
130
|
+
input.subgoal ? `Current step: ${input.subgoal}` : undefined,
|
|
131
|
+
`Field: ${input.targetRole} ${JSON.stringify(input.targetLabel)}`,
|
|
132
|
+
input.literals.length > 0 ? `Values mentioned in the task: ${JSON.stringify(input.literals)}` : undefined,
|
|
133
|
+
input.context ? `Page context: ${input.context}` : undefined,
|
|
134
|
+
`Maximum length: ${input.maxLength ?? 200} characters.`,
|
|
135
|
+
]
|
|
136
|
+
.filter((line) => line !== undefined)
|
|
137
|
+
.join("\n");
|
|
138
|
+
const { json, usage, latencyMs } = await this.#client.chatJson({ system: TEXT_SYSTEM, user, maxTokens: 120 }, {
|
|
139
|
+
...(this.#baseUrl ? { baseUrl: this.#baseUrl } : {}),
|
|
140
|
+
...(this.#apiKey ? { apiKey: this.#apiKey } : {}),
|
|
141
|
+
...(this.#model ? { model: this.#model } : {}),
|
|
142
|
+
});
|
|
143
|
+
const parsed = textModelResponseSchema.safeParse(json);
|
|
144
|
+
if (!parsed.success) {
|
|
145
|
+
throw new RuntimeError("DECISION_INVALID", "text provider returned an invalid payload", {
|
|
146
|
+
detail: parsed.error.issues.map((i) => i.message).join("; "),
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
text: parsed.data.text,
|
|
151
|
+
source: "model",
|
|
152
|
+
provider: this.name,
|
|
153
|
+
latencyMs,
|
|
154
|
+
...(usage ? { usage } : {}),
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
const PLANNER_SYSTEM = [
|
|
159
|
+
"You are the planner for a browser automation runtime.",
|
|
160
|
+
"Plan the shortest deterministic sequence of subgoals that completes the user's task in the browser.",
|
|
161
|
+
"Reply with JSON only: {\"subgoals\": [{\"description\": \"...\", \"hints\": [\"...\"]}], \"notes\": \"...\"}.",
|
|
162
|
+
"Each subgoal must be a single verifiable browser step (open a page, sign in, download a file, upload a file, stop before submitting).",
|
|
163
|
+
"Never include destructive or financial actions unless the task explicitly asks for them.",
|
|
164
|
+
"Keep the plan under 8 subgoals.",
|
|
165
|
+
].join(" ");
|
|
166
|
+
const CHOOSE_SYSTEM = [
|
|
167
|
+
"You choose one action for a browser agent from a fixed, runtime-provided action space.",
|
|
168
|
+
"Reply with JSON only: {\"operation\": \"<OP>\", \"target\": \"<key>\"}.",
|
|
169
|
+
"The operation must be one of the offered operations; the target must be one of the offered keys for the matching head.",
|
|
170
|
+
"Never invent selectors, coordinates, URLs, JavaScript or element ids that were not offered.",
|
|
171
|
+
"Prefer the action that most directly advances the stated goal; avoid repeating actions that failed before.",
|
|
172
|
+
].join(" ");
|
|
173
|
+
export class OpenAIPlannerProvider {
|
|
174
|
+
name;
|
|
175
|
+
#client;
|
|
176
|
+
#baseUrl;
|
|
177
|
+
#apiKey;
|
|
178
|
+
#model;
|
|
179
|
+
constructor(options = {}) {
|
|
180
|
+
this.name = options.name ?? "openai-compatible:planner";
|
|
181
|
+
const apiKey = options.apiKey ?? process.env["MLOLA_PLANNER_API_KEY"] ?? process.env["OPENAI_API_KEY"];
|
|
182
|
+
if (!apiKey) {
|
|
183
|
+
throw new RuntimeError("PROVIDER_FAILURE", "missing planner API key (MLOLA_PLANNER_API_KEY)", {
|
|
184
|
+
retryable: false,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
const baseUrl = options.baseUrl ?? process.env["MLOLA_PLANNER_BASE_URL"];
|
|
188
|
+
const model = options.model ?? process.env["MLOLA_PLANNER_MODEL"] ?? "gpt-4o-mini";
|
|
189
|
+
this.#apiKey = apiKey;
|
|
190
|
+
this.#baseUrl = baseUrl;
|
|
191
|
+
this.#model = model;
|
|
192
|
+
this.#client = new OpenAICompatibleClient({ ...options, apiKey, ...(baseUrl ? { baseUrl } : {}), model });
|
|
193
|
+
}
|
|
194
|
+
async plan(input) {
|
|
195
|
+
const user = [
|
|
196
|
+
`Task: ${input.goal}`,
|
|
197
|
+
`Reason for planning: ${input.reason}`,
|
|
198
|
+
input.memory.facts.length > 0
|
|
199
|
+
? `Known facts:\n${input.memory.facts.map((f) => `- ${f.text}`).join("\n")}`
|
|
200
|
+
: undefined,
|
|
201
|
+
input.history.length > 0
|
|
202
|
+
? `Steps already taken:\n${input.history.slice(-10).map((h) => `${h.step}. ${h.action} -> ${h.outcome}`).join("\n")}`
|
|
203
|
+
: undefined,
|
|
204
|
+
input.artifacts.length > 0
|
|
205
|
+
? `Files already obtained:\n${input.artifacts.map((a) => `- ${a.id} ${a.name}`).join("\n")}`
|
|
206
|
+
: undefined,
|
|
207
|
+
`Current page state:\n${input.snapshotSummary}`,
|
|
208
|
+
]
|
|
209
|
+
.filter((line) => line !== undefined)
|
|
210
|
+
.join("\n\n");
|
|
211
|
+
const { json, usage, latencyMs } = await this.#client.chatJson({ system: PLANNER_SYSTEM, user, maxTokens: 700 }, {
|
|
212
|
+
...(this.#baseUrl ? { baseUrl: this.#baseUrl } : {}),
|
|
213
|
+
...(this.#apiKey ? { apiKey: this.#apiKey } : {}),
|
|
214
|
+
...(this.#model ? { model: this.#model } : {}),
|
|
215
|
+
});
|
|
216
|
+
const parsed = plannerModelResponseSchema.safeParse(json);
|
|
217
|
+
if (!parsed.success) {
|
|
218
|
+
throw new RuntimeError("PROVIDER_FAILURE", "planner returned an invalid plan", {
|
|
219
|
+
detail: parsed.error.issues.map((i) => i.message).join("; "),
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
return {
|
|
223
|
+
subgoals: parsed.data.subgoals.map((s, i) => ({
|
|
224
|
+
id: `g${i + 1}`,
|
|
225
|
+
description: s.description,
|
|
226
|
+
...(s.hints ? { hints: s.hints } : {}),
|
|
227
|
+
})),
|
|
228
|
+
...(parsed.data.notes !== undefined ? { notes: parsed.data.notes } : {}),
|
|
229
|
+
provider: this.name,
|
|
230
|
+
model: this.#model,
|
|
231
|
+
latencyMs,
|
|
232
|
+
usage,
|
|
233
|
+
};
|
|
234
|
+
}
|
|
235
|
+
async chooseAction(input) {
|
|
236
|
+
const space = input.actionSpace;
|
|
237
|
+
const operations = space.operations.map((op) => {
|
|
238
|
+
const head = space.headForOperation[op];
|
|
239
|
+
const targets = head ? (space.heads[head] ?? []) : [];
|
|
240
|
+
const targetList = targets.length > 0 ? ` targets: ${targets.map((t) => `${t.key} = ${t.label}`).join(" | ")}` : "";
|
|
241
|
+
return `- ${op}${targetList}`;
|
|
242
|
+
});
|
|
243
|
+
const user = [
|
|
244
|
+
`Task: ${input.goal}`,
|
|
245
|
+
input.subgoal ? `Current step: ${input.subgoal}` : undefined,
|
|
246
|
+
input.failure ? `Previous attempt failed: ${input.failure}` : undefined,
|
|
247
|
+
`Page: ${input.snapshot.url} — ${input.snapshot.title}`,
|
|
248
|
+
"",
|
|
249
|
+
"Visible elements:",
|
|
250
|
+
input.snapshot.nodes.slice(0, 60).map((n) => `~${renderElement(n)}`).join("\n"),
|
|
251
|
+
"",
|
|
252
|
+
"Offered operations and targets:",
|
|
253
|
+
operations.join("\n"),
|
|
254
|
+
"",
|
|
255
|
+
`Crash context: ${input.reason}`,
|
|
256
|
+
]
|
|
257
|
+
.filter((line) => line !== undefined)
|
|
258
|
+
.join("\n");
|
|
259
|
+
const { json, usage, latencyMs } = await this.#client.chatJson({ system: CHOOSE_SYSTEM, user, maxTokens: 120, temperature: 0 }, {
|
|
260
|
+
...(this.#baseUrl ? { baseUrl: this.#baseUrl } : {}),
|
|
261
|
+
...(this.#apiKey ? { apiKey: this.#apiKey } : {}),
|
|
262
|
+
...(this.#model ? { model: this.#model } : {}),
|
|
263
|
+
});
|
|
264
|
+
const candidate = json;
|
|
265
|
+
if (typeof candidate.operation !== "string") {
|
|
266
|
+
throw new RuntimeError("PROVIDER_FAILURE", "fallback provider did not return an operation");
|
|
267
|
+
}
|
|
268
|
+
return {
|
|
269
|
+
operation: candidate.operation,
|
|
270
|
+
...(typeof candidate.target === "string" ? { target: candidate.target } : {}),
|
|
271
|
+
latencyMs,
|
|
272
|
+
provider: this.name,
|
|
273
|
+
...(this.#model ? { model: this.#model } : {}),
|
|
274
|
+
...(usage ? { usage } : {}),
|
|
275
|
+
raw: json,
|
|
276
|
+
};
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=llm-providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"llm-providers.js","sourceRoot":"","sources":["../src/llm-providers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Jev fast-path decision provider (PRD §15, §44).
|
|
3
|
+
*
|
|
4
|
+
* One request per normal decision cycle: operation head + speculative target
|
|
5
|
+
* heads built from the runtime's own action space.
|
|
6
|
+
*/
|
|
7
|
+
import { type DecisionInput, type DecisionOutput, type DecisionProvider } from "@mlola/browser-protocol";
|
|
8
|
+
import { JevClient, type JevClientOptions } from "./client.ts";
|
|
9
|
+
export interface JevDecisionProviderOptions extends JevClientOptions {
|
|
10
|
+
/** Provider name recorded in traces (default "typesafe"). */
|
|
11
|
+
name?: string;
|
|
12
|
+
/** Cost rates for usage accounting. */
|
|
13
|
+
cost?: {
|
|
14
|
+
inputPerMTok?: number;
|
|
15
|
+
outputPerMTok?: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
export declare class JevDecisionProvider implements DecisionProvider {
|
|
19
|
+
readonly name: string;
|
|
20
|
+
readonly client: JevClient;
|
|
21
|
+
constructor(options?: JevDecisionProviderOptions);
|
|
22
|
+
get model(): string;
|
|
23
|
+
warmup(): Promise<void>;
|
|
24
|
+
decide(input: DecisionInput): Promise<DecisionOutput>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=provider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAGL,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,KAAK,gBAAgB,EAGtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,SAAS,EAAE,KAAK,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAI/D,MAAM,WAAW,0BAA2B,SAAQ,gBAAgB;IAClE,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,IAAI,CAAC,EAAE;QAAE,YAAY,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC1D;AAED,qBAAa,mBAAoB,YAAW,gBAAgB;IAC1D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;gBAEf,OAAO,GAAE,0BAA+B;IAKpD,IAAI,KAAK,IAAI,MAAM,CAElB;IAEK,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAIvB,MAAM,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC;CA6C5D"}
|