@actor0/harness 0.0.0-stage → 0.5.2
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/answer-filter.d.ts +36 -0
- package/dist/answer-filter.d.ts.map +1 -0
- package/dist/answer-filter.js +308 -0
- package/dist/harness.d.ts +154 -0
- package/dist/harness.d.ts.map +1 -0
- package/dist/harness.js +750 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +9 -0
- package/dist/model-client.d.ts +165 -0
- package/dist/model-client.d.ts.map +1 -0
- package/dist/model-client.js +654 -0
- package/dist/plan-prefix.d.ts +8 -0
- package/dist/plan-prefix.d.ts.map +1 -0
- package/dist/plan-prefix.js +59 -0
- package/dist/protocol.d.ts +21 -0
- package/dist/protocol.d.ts.map +1 -0
- package/dist/protocol.js +70 -0
- package/dist/reasoning-summary.d.ts +15 -0
- package/dist/reasoning-summary.d.ts.map +1 -0
- package/dist/reasoning-summary.js +48 -0
- package/dist/tool-call-block.d.ts +141 -0
- package/dist/tool-call-block.d.ts.map +1 -0
- package/dist/tool-call-block.js +377 -0
- package/dist/tool-host.d.ts +31 -0
- package/dist/tool-host.d.ts.map +1 -0
- package/dist/tool-host.js +57 -0
- package/dist/types.d.ts +241 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/package.json +30 -6
- package/README.md +0 -3
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from "./answer-filter.js";
|
|
2
|
+
export * from "./tool-call-block.js";
|
|
3
|
+
export * from "./harness.js";
|
|
4
|
+
export * from "./model-client.js";
|
|
5
|
+
export * from "./plan-prefix.js";
|
|
6
|
+
export * from "./protocol.js";
|
|
7
|
+
export * from "./reasoning-summary.js";
|
|
8
|
+
export * from "./tool-host.js";
|
|
9
|
+
export * from "./types.js";
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,cAAc,CAAC;AAC7B,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,cAAc,wBAAwB,CAAC;AACvC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from "./answer-filter.js";
|
|
2
|
+
export * from "./tool-call-block.js";
|
|
3
|
+
export * from "./harness.js";
|
|
4
|
+
export * from "./model-client.js";
|
|
5
|
+
export * from "./plan-prefix.js";
|
|
6
|
+
export * from "./protocol.js";
|
|
7
|
+
export * from "./reasoning-summary.js";
|
|
8
|
+
export * from "./tool-host.js";
|
|
9
|
+
export * from "./types.js";
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import type { ChatMessage, ModelClient, ModelEvent, ToolDefinition } from "./types.js";
|
|
2
|
+
export declare class ModelTransportError extends Error {
|
|
3
|
+
readonly retriable: boolean;
|
|
4
|
+
readonly retryAfterMs?: number | undefined;
|
|
5
|
+
/**
|
|
6
|
+
* @param retryAfterMs how long the server asked us to wait, when it said.
|
|
7
|
+
* A retriable error that carries one has a floor under its next attempt:
|
|
8
|
+
* see `retryDelay` in harness.ts.
|
|
9
|
+
*/
|
|
10
|
+
constructor(message: string, retriable?: boolean, retryAfterMs?: number | undefined);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* The longest server-requested wait this harness will sit through.
|
|
14
|
+
*
|
|
15
|
+
* A windowed rate limit can name a reset twenty minutes out. Honouring that
|
|
16
|
+
* in a terminal means the turn disappears for twenty minutes with nothing on
|
|
17
|
+
* screen, which the user reads as a hang; ignoring it means the retries land
|
|
18
|
+
* inside the window and the turn fails having proved nothing. So the wait is
|
|
19
|
+
* honoured up to here, and past it the failure is surfaced instead, with the
|
|
20
|
+
* time the limit lifts in the message the user reads.
|
|
21
|
+
*/
|
|
22
|
+
export declare const MAX_HONOURED_RETRY_AFTER_MS = 120000;
|
|
23
|
+
/**
|
|
24
|
+
* How long the server asked us to wait, in milliseconds.
|
|
25
|
+
*
|
|
26
|
+
* `Retry-After` is a count of seconds per RFC 9110, and an HTTP-date in the
|
|
27
|
+
* dialect several providers actually send. Both are honoured; a value that is
|
|
28
|
+
* neither is ignored rather than guessed at, because a misread directive is
|
|
29
|
+
* worse than no directive.
|
|
30
|
+
*/
|
|
31
|
+
export declare function retryAfterMs(headers: Headers, now?: number): number | undefined;
|
|
32
|
+
export type OpenAiCompatibleOptions = {
|
|
33
|
+
baseUrl: string;
|
|
34
|
+
apiKey?: string;
|
|
35
|
+
model: string;
|
|
36
|
+
fetchImpl?: typeof fetch;
|
|
37
|
+
headers?: Record<string, string>;
|
|
38
|
+
/**
|
|
39
|
+
* Override the request path. Defaults to `/chat/completions` appended to
|
|
40
|
+
* `baseUrl`. Gateways and application proxies routinely expose an
|
|
41
|
+
* OpenAI-shaped endpoint somewhere else — `/api/chat`, a tunnel, a route
|
|
42
|
+
* that also serves HTML — and forcing every one of them to sit at
|
|
43
|
+
* `baseUrl + /chat/completions` would be a transport limitation leaking
|
|
44
|
+
* into every host that has to work around it.
|
|
45
|
+
*/
|
|
46
|
+
path?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Reasoning effort for models that support it (o-series and reasoning
|
|
49
|
+
* models). Sent as `reasoning_effort`; omitted entirely when unset, so a
|
|
50
|
+
* non-reasoning endpoint never sees an unknown field.
|
|
51
|
+
*/
|
|
52
|
+
reasoningEffort?: "low" | "medium" | "high";
|
|
53
|
+
};
|
|
54
|
+
export declare class OpenAiCompatibleModel implements ModelClient {
|
|
55
|
+
private readonly endpoint;
|
|
56
|
+
private readonly apiKey?;
|
|
57
|
+
private readonly model;
|
|
58
|
+
private readonly fetchImpl;
|
|
59
|
+
private readonly headers;
|
|
60
|
+
private readonly reasoningEffort?;
|
|
61
|
+
constructor(options: OpenAiCompatibleOptions);
|
|
62
|
+
stream(messages: ChatMessage[], tools: ToolDefinition[], signal: AbortSignal): AsyncIterable<ModelEvent>;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* True when a response is an HTML document rather than a stream or a JSON
|
|
66
|
+
* error. Gateways, edge runtimes and bot checks all answer this way, and none
|
|
67
|
+
* of them say so in the body: the caller has to read the shape.
|
|
68
|
+
*/
|
|
69
|
+
export declare function looksLikeHtml(contentType: string | null, body: string | null): boolean; /** True when the response claims to be the event stream we asked for. */
|
|
70
|
+
/**
|
|
71
|
+
* Whether an error delivered *inside* a 200 response can be fixed by asking
|
|
72
|
+
* again.
|
|
73
|
+
*
|
|
74
|
+
* A 200 means the request was accepted, so the status classification above
|
|
75
|
+
* never runs — there is no status left to read. Everything then arrives in
|
|
76
|
+
* one shape, `data: {"error": {...}}`: a dropped upstream connection, a rate
|
|
77
|
+
* limit, a rejected key, a request that does not fit the context window.
|
|
78
|
+
* Calling all of them retriable, which is what this did, replays a
|
|
79
|
+
* deterministic failure three times with 1s/2s/4s of backoff, at four times the
|
|
80
|
+
* token cost, and ends in exactly the same error.
|
|
81
|
+
*
|
|
82
|
+
* Code and type are read first because they are exact, and because they are
|
|
83
|
+
* the part OpenAI, Anthropic, Gemini and OpenRouter all agree on. The message
|
|
84
|
+
* is the fallback for the servers that send neither. An unrecognised error
|
|
85
|
+
* stays retriable: a stream that died mid-flight is far more often a dropped
|
|
86
|
+
* connection than a request the server will never accept, and guessing wrong
|
|
87
|
+
* in that direction costs one wasted attempt, while guessing wrong the other
|
|
88
|
+
* way refuses to start the turn at all.
|
|
89
|
+
*/
|
|
90
|
+
export declare function isRetriableStreamError(message: string, code?: string, type?: string): boolean;
|
|
91
|
+
/**
|
|
92
|
+
* Is this failure the conversation not fitting the model?
|
|
93
|
+
*
|
|
94
|
+
* Named because it is the one transport failure with a real recovery, and
|
|
95
|
+
* recovery is not the transport layer's job: the caller has to shorten the
|
|
96
|
+
* history and ask again, which is a decision about the conversation.
|
|
97
|
+
*/
|
|
98
|
+
export declare function isContextOverflow(message: string): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Is this thrown value the model saying the request is too big?
|
|
101
|
+
*
|
|
102
|
+
* Asked of the error rather than of the message so a host does not have to
|
|
103
|
+
* know which layer raised it, or re-derive that a retriable failure of the
|
|
104
|
+
* same shape must not be compacted around. Both spellings land here: a 400
|
|
105
|
+
* whose body is the diagnosis, and an error frame inside a 200.
|
|
106
|
+
*/
|
|
107
|
+
/**
|
|
108
|
+
* A request the endpoint will never accept, however often it is
|
|
109
|
+
* sent — the one transport failure with a host-level recovery
|
|
110
|
+
* (compact the history and ask again), which is why this is a
|
|
111
|
+
* classifier and not just a message match.
|
|
112
|
+
*
|
|
113
|
+
* It also looks through a `FailedTurnError`: a turn that failed
|
|
114
|
+
* mid-flight wraps the transport error that ended it (see
|
|
115
|
+
* `failedTurn`), and without the unwrap every such failure reads
|
|
116
|
+
* as an unknown error, so the recovery never fires and a turn the
|
|
117
|
+
* endpoint merely refused rewinds the session instead of being
|
|
118
|
+
* asked again. That makes the return a plain boolean rather than
|
|
119
|
+
* a type predicate — in the wrapped case the error is a
|
|
120
|
+
* `FailedTurnError`, not the `ModelTransportError` the old
|
|
121
|
+
* signature claimed — and its one caller reads it as a gate.
|
|
122
|
+
*/
|
|
123
|
+
export declare function isContextOverflowError(error: unknown): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* The context window the endpoint said it has, in tokens, or undefined.
|
|
126
|
+
*
|
|
127
|
+
* The overflow message is not only a diagnosis, it is the one measurement of
|
|
128
|
+
* the limit the provider will ever volunteer, and reading it as a boolean
|
|
129
|
+
* throws the number away. A host recovering from an overflow has to decide
|
|
130
|
+
* how much history to keep, and a guess cannot be smaller than the truth: on
|
|
131
|
+
* a 4k-window model a recovery that targets 8,000 tokens does not fit by
|
|
132
|
+
* construction, and the one replay it is allowed fails exactly like the
|
|
133
|
+
* request it was meant to fix.
|
|
134
|
+
*
|
|
135
|
+
* Anchored on the number *and* the word "token" on purpose. The messages that
|
|
136
|
+
* carry a limit also carry the count that broke it — "your messages resulted
|
|
137
|
+
* in 91234 tokens" — and a looser pattern reads the wrong number, which is
|
|
138
|
+
* worse than reading none. A per-message char limit is not a window and is
|
|
139
|
+
* not returned for one; `OVERFLOW_TEXT` matches that shape too, deliberately,
|
|
140
|
+
* because it is a different failure with its own advice.
|
|
141
|
+
*
|
|
142
|
+
* Returned only for a failure that is a real refusal, so a retriable error
|
|
143
|
+
* carrying a similar string cannot talk a host into compacting a turn that
|
|
144
|
+
* was never the problem.
|
|
145
|
+
*/
|
|
146
|
+
export declare function contextWindowTokens(error: unknown): number | undefined;
|
|
147
|
+
/**
|
|
148
|
+
* A failure message a person can act on.
|
|
149
|
+
*
|
|
150
|
+
* The endpoint is included because "request failed" tells the reader nothing
|
|
151
|
+
* when three of them are configured, and the status because a body alone
|
|
152
|
+
* cannot distinguish a rate limit from a crash. An HTML body is summarised
|
|
153
|
+
* rather than quoted: the previous behaviour pasted its first 600 characters
|
|
154
|
+
* into the transcript, which buried a one-line diagnosis under a wall of markup
|
|
155
|
+
* and still omitted the two facts that would have identified the fault.
|
|
156
|
+
*
|
|
157
|
+
* The closing line is derived from `retriable`, never from a guess about what
|
|
158
|
+
* "usually" happens. Telling someone a 403 will be retried when it will not is
|
|
159
|
+
* worse than saying nothing, because they wait for a retry that never comes.
|
|
160
|
+
*
|
|
161
|
+
* The URL is safe to print — the constructor clears any query string, so a key
|
|
162
|
+
* passed as a query parameter is already gone by this point.
|
|
163
|
+
*/
|
|
164
|
+
export declare function describeHttpFailure(endpoint: string, response: Response, body: string, retriable: boolean, retryAfterMs?: number): string;
|
|
165
|
+
//# sourceMappingURL=model-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-client.d.ts","sourceRoot":"","sources":["../src/model-client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,UAAU,EAAY,cAAc,EAAS,MAAM,YAAY,CAAC;AAExG,qBAAa,mBAAoB,SAAQ,KAAK;IAMf,QAAQ,CAAC,SAAS;IAAU,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM;IALvF;;;;OAIG;gBACS,OAAO,EAAE,MAAM,EAAW,SAAS,UAAQ,EAAW,YAAY,CAAC,EAAE,MAAM,YAAA;CAIxF;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B,SAAU,CAAC;AAEnD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,GAAE,MAAmB,GAAG,MAAM,GAAG,SAAS,CAa3F;AAED,MAAM,MAAM,uBAAuB,GAAG;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC;;;;;;;OAOG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,eAAe,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,MAAM,CAAC;CAC7C,CAAC;AAyBF,qBAAa,qBAAsB,YAAW,WAAW;IACvD,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IACzC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAyB;IACjD,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAC,CAA4B;gBAEjD,OAAO,EAAE,uBAAuB;IAqBrC,MAAM,CAAC,QAAQ,EAAE,WAAW,EAAE,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,WAAW,GAAG,aAAa,CAAC,UAAU,CAAC;CA+GhH;AAkGD;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAMtF,CAAA,yEAAyE;AA0B1E;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAQ7F;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;;;;;GAOG;AACH;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAG9D;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAStE;AAqGD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,OAAO,EAClB,YAAY,CAAC,EAAE,MAAM,GACpB,MAAM,CAyBR"}
|