@vincemakes/kiso-runtime 0.31.1 → 0.32.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/dist/agent.d.ts +4 -0
- package/dist/agent.js +1 -0
- package/dist/extensions.js +23 -1
- package/dist/idle-guard.d.ts +38 -0
- package/dist/idle-guard.js +122 -0
- package/dist/provider/metadata.js +30 -0
- package/dist/run.js +5 -1
- package/dist/session.d.ts +2 -0
- package/dist/session.js +3 -1
- package/dist/store.js +8 -1
- package/package.json +6 -6
package/dist/agent.d.ts
CHANGED
|
@@ -65,6 +65,10 @@ export interface AgentDefinition {
|
|
|
65
65
|
/** E6: the session context policy (run-start actions, injection-side only). */
|
|
66
66
|
readonly contextPolicy?: import("./session.js").ContextPolicy;
|
|
67
67
|
readonly maxRetries?: number;
|
|
68
|
+
/** LT-1: the stream watchdog — milliseconds between adapter events
|
|
69
|
+
* before the request is aborted and retried (default 120 s; 0 off).
|
|
70
|
+
* Type-only additive; read by the runtime's idle guard. */
|
|
71
|
+
readonly streamIdleMs?: number;
|
|
68
72
|
/** E1: loaded extensions — their tools merge into the registry (a name
|
|
69
73
|
* collision with a built-in is a loud startup error), their hooks
|
|
70
74
|
* compose after the agent's own (the existing come first), their approvals join the
|
package/dist/agent.js
CHANGED
|
@@ -145,6 +145,7 @@ export class AgentRuntime {
|
|
|
145
145
|
...(this.#definition.microcompact !== undefined ? { microcompact: this.#definition.microcompact } : {}),
|
|
146
146
|
...(this.#definition.contextPolicy !== undefined ? { contextPolicy: this.#definition.contextPolicy } : {}),
|
|
147
147
|
...(this.#definition.maxRetries !== undefined ? { maxRetries: this.#definition.maxRetries } : {}),
|
|
148
|
+
...(this.#definition.streamIdleMs !== undefined ? { streamIdleMs: this.#definition.streamIdleMs } : {}),
|
|
148
149
|
...(this.#definition.extensions !== undefined ? { extensions: this.#definition.extensions } : {}),
|
|
149
150
|
};
|
|
150
151
|
return new AgentSession(options.id, log, store, adapter, config);
|
package/dist/extensions.js
CHANGED
|
@@ -28,6 +28,27 @@ export async function loadProjectExtensions(dir, existing = []) {
|
|
|
28
28
|
}
|
|
29
29
|
return projectExts;
|
|
30
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* §2.5 — the load counter behind the import URL's `?load=` query.
|
|
33
|
+
*
|
|
34
|
+
* Node caches ESM modules by URL forever. Without a distinguishing query
|
|
35
|
+
* a second load of the same directory returns the FIRST load's modules,
|
|
36
|
+
* so `/reload` would report success and change nothing — and a
|
|
37
|
+
* module-level Set held across the boundary would be mutated by one side
|
|
38
|
+
* and read by the other.
|
|
39
|
+
*
|
|
40
|
+
* It is unconditional on purpose. A parameter would put a stale mode
|
|
41
|
+
* back within reach and would move `loadExtensions` in the public
|
|
42
|
+
* surface file for no gain: at startup this is one load and invisible,
|
|
43
|
+
* and on a reload it is the entire point.
|
|
44
|
+
*
|
|
45
|
+
* The cost, stated rather than hidden: Node has no module unloader, so
|
|
46
|
+
* each superseded module object stays allocated and unreachable for the
|
|
47
|
+
* life of the process — one per extension file per reload. The only
|
|
48
|
+
* real resources an extension holds are its MCP servers, and those are
|
|
49
|
+
* torn down by `disposeExtensions`, which whoever loaded them owes.
|
|
50
|
+
*/
|
|
51
|
+
let loadSerial = 0;
|
|
31
52
|
export async function loadExtensions(dir) {
|
|
32
53
|
let files;
|
|
33
54
|
try {
|
|
@@ -39,10 +60,11 @@ export async function loadExtensions(dir) {
|
|
|
39
60
|
throw err;
|
|
40
61
|
}
|
|
41
62
|
const out = [];
|
|
63
|
+
const serial = ++loadSerial; // one nonce per CALL — a directory's files load together
|
|
42
64
|
for (const file of files) {
|
|
43
65
|
let ext;
|
|
44
66
|
try {
|
|
45
|
-
const mod = (await import(pathToFileURL(join(dir, file)).href));
|
|
67
|
+
const mod = (await import(`${pathToFileURL(join(dir, file)).href}?load=${serial}`));
|
|
46
68
|
ext = mod.default;
|
|
47
69
|
if (typeof ext === "function")
|
|
48
70
|
ext = await ext(); // a factory
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LT-1 — the stream watchdog (kiso-doc/kiso-lt1-mini-spec-2026-09-09.md).
|
|
3
|
+
*
|
|
4
|
+
* The third guard beside `truncationGuard` and `traceGuard`: it wraps the
|
|
5
|
+
* adapter's `stream()` so that a request whose events STOP ARRIVING is
|
|
6
|
+
* ended rather than waited on forever. Before this, a model stream that
|
|
7
|
+
* went silent — a hung socket, an upstream that stopped writing without
|
|
8
|
+
* closing — held the run open until a human pressed esc; the 0.31.0
|
|
9
|
+
* review filed it as the one long-task hazard nothing handled.
|
|
10
|
+
*
|
|
11
|
+
* The rule is per EVENT, not per request: a long think that keeps
|
|
12
|
+
* streaming is never tripped, a socket that stops is tripped `idleMs`
|
|
13
|
+
* after its last byte. On a trip the guard aborts the UNDERLYING request
|
|
14
|
+
* through a controller it owns (combined with the caller's signal, so
|
|
15
|
+
* esc still wins) and throws a retryable `network` StructuredError. From
|
|
16
|
+
* there the kernel's existing mid-stream retry does the rest: the
|
|
17
|
+
* attempt is voided (`model_output_abandoned` with this reason), the
|
|
18
|
+
* request is retried with backoff, and when the budget is spent the run
|
|
19
|
+
* ends in the error terminal the CLI prints (OR-5). Nothing new is
|
|
20
|
+
* written to the log; the kernel is untouched.
|
|
21
|
+
*
|
|
22
|
+
* `idleMs` ≤ 0 (or absent) returns the adapter itself: the guard is
|
|
23
|
+
* declared off, not silently ignored.
|
|
24
|
+
*/
|
|
25
|
+
import type { Adapter, StructuredError } from "@vincemakes/kiso-core";
|
|
26
|
+
/** The default: 120 s between events. The ChatGPT backend at a high effort
|
|
27
|
+
* can think without writing (no reasoning summaries are requested), and
|
|
28
|
+
* no measured bound exists for an `ultra` turn — 120 s is the order of
|
|
29
|
+
* magnitude the reference implementation allows a whole request, applied
|
|
30
|
+
* here per event: stricter where it matters, looser where it should be.
|
|
31
|
+
* A knob (`streamIdleMs` on the profile) because the first dogfood may
|
|
32
|
+
* move it. */
|
|
33
|
+
export declare const DEFAULT_STREAM_IDLE_MS = 120000;
|
|
34
|
+
export declare function idleGuard(adapter: Adapter, idleMs: number | undefined): Adapter;
|
|
35
|
+
/** The error the kernel receives on a trip — the same shape the adapters
|
|
36
|
+
* produce for a connection failure, so the retry authority (ADR-0005)
|
|
37
|
+
* treats a stall exactly like a dropped socket. */
|
|
38
|
+
export declare function stalledError(idleMs: number, elapsedMs: number): StructuredError;
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LT-1 — the stream watchdog (kiso-doc/kiso-lt1-mini-spec-2026-09-09.md).
|
|
3
|
+
*
|
|
4
|
+
* The third guard beside `truncationGuard` and `traceGuard`: it wraps the
|
|
5
|
+
* adapter's `stream()` so that a request whose events STOP ARRIVING is
|
|
6
|
+
* ended rather than waited on forever. Before this, a model stream that
|
|
7
|
+
* went silent — a hung socket, an upstream that stopped writing without
|
|
8
|
+
* closing — held the run open until a human pressed esc; the 0.31.0
|
|
9
|
+
* review filed it as the one long-task hazard nothing handled.
|
|
10
|
+
*
|
|
11
|
+
* The rule is per EVENT, not per request: a long think that keeps
|
|
12
|
+
* streaming is never tripped, a socket that stops is tripped `idleMs`
|
|
13
|
+
* after its last byte. On a trip the guard aborts the UNDERLYING request
|
|
14
|
+
* through a controller it owns (combined with the caller's signal, so
|
|
15
|
+
* esc still wins) and throws a retryable `network` StructuredError. From
|
|
16
|
+
* there the kernel's existing mid-stream retry does the rest: the
|
|
17
|
+
* attempt is voided (`model_output_abandoned` with this reason), the
|
|
18
|
+
* request is retried with backoff, and when the budget is spent the run
|
|
19
|
+
* ends in the error terminal the CLI prints (OR-5). Nothing new is
|
|
20
|
+
* written to the log; the kernel is untouched.
|
|
21
|
+
*
|
|
22
|
+
* `idleMs` ≤ 0 (or absent) returns the adapter itself: the guard is
|
|
23
|
+
* declared off, not silently ignored.
|
|
24
|
+
*/
|
|
25
|
+
/** The default: 120 s between events. The ChatGPT backend at a high effort
|
|
26
|
+
* can think without writing (no reasoning summaries are requested), and
|
|
27
|
+
* no measured bound exists for an `ultra` turn — 120 s is the order of
|
|
28
|
+
* magnitude the reference implementation allows a whole request, applied
|
|
29
|
+
* here per event: stricter where it matters, looser where it should be.
|
|
30
|
+
* A knob (`streamIdleMs` on the profile) because the first dogfood may
|
|
31
|
+
* move it. */
|
|
32
|
+
export const DEFAULT_STREAM_IDLE_MS = 120_000;
|
|
33
|
+
export function idleGuard(adapter, idleMs) {
|
|
34
|
+
if (idleMs === undefined || !(idleMs > 0))
|
|
35
|
+
return adapter;
|
|
36
|
+
return {
|
|
37
|
+
stream: (options) => guardStream(adapter, options, idleMs),
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** The error the kernel receives on a trip — the same shape the adapters
|
|
41
|
+
* produce for a connection failure, so the retry authority (ADR-0005)
|
|
42
|
+
* treats a stall exactly like a dropped socket. */
|
|
43
|
+
export function stalledError(idleMs, elapsedMs) {
|
|
44
|
+
return {
|
|
45
|
+
code: "network",
|
|
46
|
+
retryable: true,
|
|
47
|
+
message: `stream stalled: no event for ${Math.round(idleMs / 1000)}s (${Math.round(elapsedMs / 1000)}s into the request)`,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
/** The caller's abort, as the kernel's catch reads it: an error NAMED
|
|
51
|
+
* AbortError with the signal set — `aborted by user`, never a stall. */
|
|
52
|
+
function abortError() {
|
|
53
|
+
const err = new Error("stream aborted by the caller");
|
|
54
|
+
err.name = "AbortError";
|
|
55
|
+
return err;
|
|
56
|
+
}
|
|
57
|
+
async function* guardStream(adapter, options, idleMs) {
|
|
58
|
+
const own = new AbortController();
|
|
59
|
+
const caller = options.signal;
|
|
60
|
+
// the caller's abort (esc) reaches the adapter through OUR controller —
|
|
61
|
+
// one signal goes down — and it also settles OUR wait at once: an
|
|
62
|
+
// adapter that ignores its signal (a stub, a transport that only
|
|
63
|
+
// notices on the next write) must not turn the caller's abort into a
|
|
64
|
+
// stall by keeping the guard waiting until the idle timer fires.
|
|
65
|
+
let rejectOnCallerAbort = () => undefined;
|
|
66
|
+
const callerAborted = new Promise((_, reject) => {
|
|
67
|
+
rejectOnCallerAbort = reject;
|
|
68
|
+
});
|
|
69
|
+
callerAborted.catch(() => undefined); // settled only when raced; never an unhandled rejection
|
|
70
|
+
const onCallerAbort = () => {
|
|
71
|
+
own.abort();
|
|
72
|
+
rejectOnCallerAbort(abortError());
|
|
73
|
+
};
|
|
74
|
+
if (caller?.aborted === true)
|
|
75
|
+
onCallerAbort();
|
|
76
|
+
else
|
|
77
|
+
caller?.addEventListener("abort", onCallerAbort, { once: true });
|
|
78
|
+
const iterator = adapter.stream({ ...options, signal: own.signal })[Symbol.asyncIterator]();
|
|
79
|
+
const started = Date.now();
|
|
80
|
+
let tripped = false;
|
|
81
|
+
try {
|
|
82
|
+
for (;;) {
|
|
83
|
+
let timer;
|
|
84
|
+
const stall = new Promise((_, reject) => {
|
|
85
|
+
timer = setTimeout(() => {
|
|
86
|
+
if (caller?.aborted === true) {
|
|
87
|
+
// the caller gave up first; the silence is theirs, not a stall
|
|
88
|
+
reject(abortError());
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
tripped = true;
|
|
92
|
+
own.abort();
|
|
93
|
+
reject(stalledError(idleMs, Date.now() - started));
|
|
94
|
+
}, idleMs);
|
|
95
|
+
});
|
|
96
|
+
let next;
|
|
97
|
+
try {
|
|
98
|
+
next = await Promise.race([iterator.next(), stall, callerAborted]);
|
|
99
|
+
}
|
|
100
|
+
catch (err) {
|
|
101
|
+
// an abort the CALLER asked for is theirs (the kernel reads its
|
|
102
|
+
// own signal and records `aborted by user`); an abort WE caused
|
|
103
|
+
// is the stall, whatever shape the adapter turned it into
|
|
104
|
+
if (tripped && caller?.aborted !== true)
|
|
105
|
+
throw stalledError(idleMs, Date.now() - started);
|
|
106
|
+
throw err;
|
|
107
|
+
}
|
|
108
|
+
finally {
|
|
109
|
+
clearTimeout(timer);
|
|
110
|
+
}
|
|
111
|
+
if (next.done)
|
|
112
|
+
return;
|
|
113
|
+
yield next.value;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
finally {
|
|
117
|
+
caller?.removeEventListener("abort", onCallerAbort);
|
|
118
|
+
// release the underlying generator whichever way this one ends
|
|
119
|
+
// (a trip, the caller's abort, or the consumer walking away)
|
|
120
|
+
await iterator.return?.().catch(() => undefined);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -246,6 +246,36 @@ const ENTRIES = [
|
|
|
246
246
|
openaiRow("gpt-5.6-sol", "medium", { inputPerM: 4, outputPerM: 20, cacheReadPerM: 0.4 }, "https://developers.openai.com/api/docs/models/gpt-5.6-sol", { levels: ["none", "low", "medium", "high", "xhigh", "max"], asOf: OPENAI_MODELS_ASOF_2 }),
|
|
247
247
|
chatgptRow("gpt-6-astra", { levels: ULTRA_LADDER, default: "low", source: CHATGPT_PRESETS_SOURCE_2, asOf: OPENAI_MODELS_ASOF_2 }),
|
|
248
248
|
chatgptRow("gpt-5.6-sol", { levels: ULTRA_LADDER, default: "low", source: CHATGPT_PRESETS_SOURCE_2, asOf: OPENAI_MODELS_ASOF_2 }),
|
|
249
|
+
// The compat table's SECOND row (roadmap R3.2 §1a step 1): GLM 5.3 Flash
|
|
250
|
+
// through OpenRouter, read from OpenRouter's models API on 2026-09-09. The
|
|
251
|
+
// id is OpenRouter's, so the row is keyed to that origin; the
|
|
252
|
+
// continuation scope stamps such a profile `custom` at openrouter.ai
|
|
253
|
+
// (manifest.ts's KNOWN_ORIGINS is deliberately not widened — the scope
|
|
254
|
+
// identity is a durable fact and this row needs only the lookup). The
|
|
255
|
+
// window is the TOP provider's (1,048,576), not the listing's 1,310,720:
|
|
256
|
+
// what a request actually gets. No default effort — the page states
|
|
257
|
+
// none. `reasoning_effort` is in the model's supported parameters; the
|
|
258
|
+
// stream's think arrives as `reasoning` (GLM-F1, the compat adapter).
|
|
259
|
+
{
|
|
260
|
+
model: "z-ai/glm-5.3-flash",
|
|
261
|
+
endpoint: "https://openrouter.ai",
|
|
262
|
+
capabilities: {
|
|
263
|
+
contextWindow: 1_048_576,
|
|
264
|
+
maxOutputTokens: 131_072,
|
|
265
|
+
promptCaching: "automatic",
|
|
266
|
+
reasoning: {
|
|
267
|
+
emitsThinkingStream: true,
|
|
268
|
+
thinking: null,
|
|
269
|
+
effort: { levels: ["low", "medium", "high"], default: null, wire: "reasoning_effort" },
|
|
270
|
+
asOf: "2026-09-09",
|
|
271
|
+
source: "https://openrouter.ai/docs/use-cases/reasoning-tokens",
|
|
272
|
+
},
|
|
273
|
+
inputModalities: null,
|
|
274
|
+
},
|
|
275
|
+
capabilitiesAsOf: "2026-09-09",
|
|
276
|
+
capabilitiesSource: "https://openrouter.ai/api/v1/models",
|
|
277
|
+
pricing: { inputPerM: 0.075, outputPerM: 0.25, cacheReadPerM: 0.015, cacheWritePerM: 0, asOf: "2026-09-09", source: "https://openrouter.ai/api/v1/models" },
|
|
278
|
+
},
|
|
249
279
|
];
|
|
250
280
|
/**
|
|
251
281
|
* Look a model up. `endpoint` narrows: an entry WITH an endpoint only
|
package/dist/run.js
CHANGED
|
@@ -9,6 +9,7 @@ import { resolveReasoning } from "./provider/metadata.js";
|
|
|
9
9
|
import { deriveRecoveryPlan, invocationSeqOf } from "./recovery-plan.js";
|
|
10
10
|
import { composeApprovalChain, composeSystemPrompt, composeToolTable, microcompactFor } from "./compose.js";
|
|
11
11
|
import { truncationGuard } from "./truncation-guard.js";
|
|
12
|
+
import { DEFAULT_STREAM_IDLE_MS, idleGuard } from "./idle-guard.js";
|
|
12
13
|
import { RequestTracer, traceGuard } from "./trace/guard.js";
|
|
13
14
|
import { runtimeVersion } from "./trace/writer.js";
|
|
14
15
|
import { ResumeBlockedError } from "./session.js";
|
|
@@ -121,7 +122,10 @@ export class Run {
|
|
|
121
122
|
const loopConfig = () => ({
|
|
122
123
|
// 0.1.40 (R-C item 3): the truncation guard gates the model
|
|
123
124
|
// stream — a truncated turn's tool batch never executes.
|
|
124
|
-
|
|
125
|
+
// LT-1: the idle guard sits closest to the adapter — a stall is
|
|
126
|
+
// aborted and thrown there, the truncation guard and the tracer see
|
|
127
|
+
// the same events and the same error every other transport failure shows them.
|
|
128
|
+
adapter: traceGuard(tracer, truncationGuard(idleGuard(this.#adapter, this.#config.streamIdleMs ?? DEFAULT_STREAM_IDLE_MS))), // tracer assigned above, before loopConfig
|
|
125
129
|
model: this.#config.model,
|
|
126
130
|
sessionId: this.#session.id, // P3: tools see their session (ToolContext.sessionId)
|
|
127
131
|
...(systemPrompt !== undefined ? { systemPrompt } : {}),
|
package/dist/session.d.ts
CHANGED
|
@@ -414,6 +414,8 @@ export interface SessionConfig {
|
|
|
414
414
|
/** E6: the session context policy (run-start actions, injection-side only). */
|
|
415
415
|
readonly contextPolicy?: ContextPolicy;
|
|
416
416
|
readonly maxRetries?: number;
|
|
417
|
+
/** LT-1: the stream watchdog's idle bound (ms); default 120 s, 0 off. */
|
|
418
|
+
readonly streamIdleMs?: number;
|
|
417
419
|
/**
|
|
418
420
|
* E1: loaded extensions — their tools join the registry (idempotently;
|
|
419
421
|
* a collision with a built-in name was already rejected at agent
|
package/dist/session.js
CHANGED
|
@@ -47,6 +47,7 @@ import { Run } from "./run.js";
|
|
|
47
47
|
// TUI2-R3v2 ③ — the side query rides the SAME tracer the runs ride; that
|
|
48
48
|
// sameness is the whole point (one ledger, one shape, no second path).
|
|
49
49
|
import { RequestTracer, traceGuard } from "./trace/guard.js";
|
|
50
|
+
import { DEFAULT_STREAM_IDLE_MS, idleGuard } from "./idle-guard.js";
|
|
50
51
|
import { runtimeVersion } from "./trace/writer.js";
|
|
51
52
|
/** A session whose disk write was rejected (stale handle) is PERMANENTLY
|
|
52
53
|
* poisoned: its in-memory log no longer matches the disk, so no further
|
|
@@ -338,7 +339,8 @@ export class AgentSession {
|
|
|
338
339
|
rentParts: { base: options.systemPrompt, appends: [] },
|
|
339
340
|
});
|
|
340
341
|
tracer.init();
|
|
341
|
-
|
|
342
|
+
// LT-1: the summary request is a model stream too — the same watchdog
|
|
343
|
+
const guarded = traceGuard(tracer, idleGuard(this.#adapter, this.#config.streamIdleMs ?? DEFAULT_STREAM_IDLE_MS));
|
|
342
344
|
let text = "";
|
|
343
345
|
try {
|
|
344
346
|
for await (const ev of guarded.stream({
|
package/dist/store.js
CHANGED
|
@@ -108,7 +108,14 @@ export function sessionTitle(records) {
|
|
|
108
108
|
if (asked.length === 0)
|
|
109
109
|
return "(no prompt)";
|
|
110
110
|
const substantive = asked.find((t) => !isOpener(t));
|
|
111
|
-
|
|
111
|
+
// HF-2 (0.32.1): a title is a LABEL and goes on one row — the resume
|
|
112
|
+
// picker's card row, `kiso sessions`, the session card. A pasted
|
|
113
|
+
// heredoc as the first turn kept its newlines here and reached the
|
|
114
|
+
// compositor's one-physical-row check through the picker (the HF-1
|
|
115
|
+
// family). Projected at the source, where the value is produced, so
|
|
116
|
+
// the three consumers cannot differ: a break or a tab is one space,
|
|
117
|
+
// runs collapse, and the cut applies to the projected line.
|
|
118
|
+
return (substantive ?? asked[0]).replace(/[\r\n\t ]+/g, " ").trim().slice(0, 60);
|
|
112
119
|
}
|
|
113
120
|
export class SessionStore {
|
|
114
121
|
root;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.32.1",
|
|
4
4
|
"description": "kiso runtime — durable multi-turn agent sessions: AgentDefinition, AgentRuntime, AgentSession, Run, append-only JSONL store.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -25,12 +25,12 @@
|
|
|
25
25
|
"test": "vitest run"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@vincemakes/kiso-core": "0.
|
|
28
|
+
"@vincemakes/kiso-core": "0.32.1"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"@vincemakes/kiso-provider-anthropic": "0.
|
|
32
|
-
"@vincemakes/kiso-provider-openai": "0.
|
|
33
|
-
"@vincemakes/kiso-provider-openai-responses": "0.
|
|
31
|
+
"@vincemakes/kiso-provider-anthropic": "0.32.1",
|
|
32
|
+
"@vincemakes/kiso-provider-openai": "0.32.1",
|
|
33
|
+
"@vincemakes/kiso-provider-openai-responses": "0.32.1"
|
|
34
34
|
},
|
|
35
35
|
"peerDependenciesMeta": {
|
|
36
36
|
"@vincemakes/kiso-provider-anthropic": {
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
}
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
47
|
-
"@vincemakes/kiso-evals": "0.
|
|
47
|
+
"@vincemakes/kiso-evals": "0.32.1",
|
|
48
48
|
"@types/node": "^26.1.2",
|
|
49
49
|
"typescript": "^5.7.2",
|
|
50
50
|
"vitest": "^3.0.0"
|