@vincemakes/kiso-runtime 0.26.3 → 0.28.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/dist/agent.d.ts +0 -9
- package/dist/agent.js +0 -1
- package/dist/compose.js +1 -1
- package/dist/provider/metadata.js +78 -16
- package/dist/run.js +0 -10
- package/dist/session.d.ts +0 -11
- package/dist/session.js +12 -60
- package/package.json +5 -5
package/dist/agent.d.ts
CHANGED
|
@@ -46,15 +46,6 @@ export interface AgentDefinition {
|
|
|
46
46
|
readonly maxTurns?: number;
|
|
47
47
|
readonly maxTokens?: number;
|
|
48
48
|
readonly temperature?: number;
|
|
49
|
-
/**
|
|
50
|
-
* DEPRECATED (ADR-0044): the classic auto-compaction path is retired —
|
|
51
|
-
* the loop ignores this (microcompact absorbed the responsibility; old
|
|
52
|
-
* sessions' `compacted` events still replay). Kept so old definitions
|
|
53
|
-
* type-check; removed at 1.0.
|
|
54
|
-
*/
|
|
55
|
-
readonly compaction?: {
|
|
56
|
-
readonly thresholdTokens: number;
|
|
57
|
-
};
|
|
58
49
|
/** C area: microcompact threshold — passed through to every session. */
|
|
59
50
|
readonly microcompact?: {
|
|
60
51
|
readonly thresholdTokens: number;
|
package/dist/agent.js
CHANGED
|
@@ -139,7 +139,6 @@ export class AgentRuntime {
|
|
|
139
139
|
...(this.#definition.maxTurns !== undefined ? { maxTurns: this.#definition.maxTurns } : {}),
|
|
140
140
|
...(this.#definition.maxTokens !== undefined ? { maxTokens: this.#definition.maxTokens } : {}),
|
|
141
141
|
...(this.#definition.temperature !== undefined ? { temperature: this.#definition.temperature } : {}),
|
|
142
|
-
...(this.#definition.compaction !== undefined ? { compaction: this.#definition.compaction } : {}),
|
|
143
142
|
...(this.#definition.microcompact !== undefined ? { microcompact: this.#definition.microcompact } : {}),
|
|
144
143
|
...(this.#definition.contextPolicy !== undefined ? { contextPolicy: this.#definition.contextPolicy } : {}),
|
|
145
144
|
...(this.#definition.maxRetries !== undefined ? { maxRetries: this.#definition.maxRetries } : {}),
|
package/dist/compose.js
CHANGED
|
@@ -73,7 +73,7 @@ export function composeHooks(existing, extensions) {
|
|
|
73
73
|
await h(payload, ctx);
|
|
74
74
|
};
|
|
75
75
|
};
|
|
76
|
-
for (const key of ["onPreLlm", "onEvent", "
|
|
76
|
+
for (const key of ["onPreLlm", "onEvent", "onPause", "onStop"]) {
|
|
77
77
|
const handler = observers((h) => h[key]);
|
|
78
78
|
if (handler !== undefined)
|
|
79
79
|
out[key] = handler;
|
|
@@ -29,6 +29,74 @@ const DEEPSEEK_PRICING = {
|
|
|
29
29
|
asOf: "2026-08-13",
|
|
30
30
|
source: "https://api-docs.deepseek.com/quick_start/pricing",
|
|
31
31
|
};
|
|
32
|
+
/** PA-1a: the Anthropic rates as read on 2026-09-07 (base input, output,
|
|
33
|
+
* cache read = "cache hits and refreshes", cache write = the 5-minute
|
|
34
|
+
* write). The pricing page notes Sonnet 5's $2/$10 is the standard
|
|
35
|
+
* price (the announced September increase did not occur). */
|
|
36
|
+
const ANTHROPIC_PRICING_SOURCE = "https://platform.claude.com/docs/en/about-claude/pricing";
|
|
37
|
+
const ANTHROPIC_MODELS_SOURCE = "https://platform.claude.com/docs/en/models/overview";
|
|
38
|
+
const ANTHROPIC_EFFORT_SOURCE = "https://platform.claude.com/docs/en/build-with-claude/effort";
|
|
39
|
+
const ANTHROPIC_ASOF = "2026-09-07";
|
|
40
|
+
const anthropicPricing = (inputPerM, outputPerM, cacheReadPerM, cacheWritePerM) => ({
|
|
41
|
+
inputPerM,
|
|
42
|
+
outputPerM,
|
|
43
|
+
cacheReadPerM,
|
|
44
|
+
cacheWritePerM,
|
|
45
|
+
asOf: ANTHROPIC_ASOF,
|
|
46
|
+
source: ANTHROPIC_PRICING_SOURCE,
|
|
47
|
+
});
|
|
48
|
+
/** The 5-line's effort control: five native levels, default high, wire
|
|
49
|
+
* output_config.effort (the effort page, read 2026-09-07). The thinking
|
|
50
|
+
* table (https://platform.claude.com/docs/en/build-with-claude/thinking-troubleshooting)
|
|
51
|
+
* gives the modes per model. */
|
|
52
|
+
const FIVE_LEVELS = { levels: ["low", "medium", "high", "xhigh", "max"], default: "high", wire: "output_config.effort" };
|
|
53
|
+
function anthropicLine() {
|
|
54
|
+
const row = (model, capabilities, pricing) => ({
|
|
55
|
+
model,
|
|
56
|
+
providerId: "anthropic",
|
|
57
|
+
capabilities,
|
|
58
|
+
capabilitiesAsOf: ANTHROPIC_ASOF,
|
|
59
|
+
capabilitiesSource: ANTHROPIC_MODELS_SOURCE,
|
|
60
|
+
pricing,
|
|
61
|
+
});
|
|
62
|
+
const fiveLine = (thinkingModes, forbidden) => ({
|
|
63
|
+
contextWindow: 1_000_000,
|
|
64
|
+
maxOutputTokens: 128_000,
|
|
65
|
+
promptCaching: "explicit",
|
|
66
|
+
reasoning: {
|
|
67
|
+
emitsThinkingStream: true,
|
|
68
|
+
thinking: { modes: thinkingModes, default: "adaptive" },
|
|
69
|
+
effort: FIVE_LEVELS,
|
|
70
|
+
...(forbidden !== undefined ? { forbidden } : {}),
|
|
71
|
+
asOf: ANTHROPIC_ASOF,
|
|
72
|
+
source: ANTHROPIC_EFFORT_SOURCE,
|
|
73
|
+
},
|
|
74
|
+
inputModalities: ["text", "image"],
|
|
75
|
+
});
|
|
76
|
+
const haiku = {
|
|
77
|
+
contextWindow: 200_000,
|
|
78
|
+
maxOutputTokens: 64_000,
|
|
79
|
+
promptCaching: "explicit",
|
|
80
|
+
// Extended thinking only (budget_tokens; adaptive rejected) — the
|
|
81
|
+
// XP-1 setting has no budget axis, so the toggle is not driven;
|
|
82
|
+
// effort: "Not supported" on the models overview. Unknown stays null.
|
|
83
|
+
reasoning: { emitsThinkingStream: true, thinking: null, effort: null, asOf: ANTHROPIC_ASOF, source: ANTHROPIC_EFFORT_SOURCE },
|
|
84
|
+
inputModalities: ["text", "image"],
|
|
85
|
+
};
|
|
86
|
+
const haikuPricing = anthropicPricing(1, 5, 0.1, 1.25);
|
|
87
|
+
return [
|
|
88
|
+
// Fable 5.1: adaptive only, ALWAYS on — "enabled" and "disabled" both 400.
|
|
89
|
+
row("claude-fable-5-1", fiveLine(["adaptive"]), anthropicPricing(10, 50, 0.25, 12.5)),
|
|
90
|
+
// Opus 5: adaptive, on by default; "disabled" accepted at effort high
|
|
91
|
+
// or below — with xhigh or max it is a 400 (the forbidden pair).
|
|
92
|
+
row("claude-opus-5", fiveLine(["adaptive", "disabled"], [{ thinking: "disabled", effort: "xhigh" }, { thinking: "disabled", effort: "max" }]), anthropicPricing(5, 25, 0.5, 6.25)),
|
|
93
|
+
// Sonnet 5: adaptive, on by default; "disabled" accepted.
|
|
94
|
+
row("claude-sonnet-5", fiveLine(["adaptive", "disabled"]), anthropicPricing(2, 10, 0.2, 2.5)),
|
|
95
|
+
// Haiku 4.5: the pinned id and its alias (the registry matches exact ids).
|
|
96
|
+
row("claude-haiku-4-5-20251001", haiku, haikuPricing),
|
|
97
|
+
row("claude-haiku-4-5", haiku, haikuPricing),
|
|
98
|
+
];
|
|
99
|
+
}
|
|
32
100
|
/** The v1 table. Nulls outnumber numbers ON PURPOSE: only values with a
|
|
33
101
|
* named source enter; everything else waits for one. */
|
|
34
102
|
const ENTRIES = [
|
|
@@ -54,22 +122,16 @@ const ENTRIES = [
|
|
|
54
122
|
capabilities: { contextWindow: null, maxOutputTokens: null, promptCaching: "automatic", reasoning: { emitsThinkingStream: true, thinking: null, effort: null, asOf: null, source: null }, inputModalities: null },
|
|
55
123
|
pricing: DEEPSEEK_PRICING,
|
|
56
124
|
},
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
},
|
|
68
|
-
inputModalities: null },
|
|
69
|
-
// Priced only when the rates are read from the live billing page
|
|
70
|
-
// and dated — never copied from memory (the review's boundary ②).
|
|
71
|
-
pricing: null,
|
|
72
|
-
},
|
|
125
|
+
// PA-1a (2026-09-07): the Anthropic first-party line, read from the live
|
|
126
|
+
// docs that day — the models overview (ids, context, max output,
|
|
127
|
+
// modalities, thinking type, default effort), the thinking table
|
|
128
|
+
// (accepted / rejected thinking.type per model, the Opus 5 forbidden
|
|
129
|
+
// pair), the effort page (levels), the pricing page (rates). Each row
|
|
130
|
+
// carries the dates; nothing here is from memory. Extended thinking
|
|
131
|
+
// (`enabled` + budget_tokens) is registered for NO model: the 5-line
|
|
132
|
+
// rejects it, and Haiku 4.5's manual-budget mode has no axis in the
|
|
133
|
+
// XP-1 setting — recorded as `thinking: null` on that row, never guessed.
|
|
134
|
+
...anthropicLine(),
|
|
73
135
|
{
|
|
74
136
|
// XP-1: the current DeepSeek line — the model every RD-1 benchmark
|
|
75
137
|
// artifact was produced with, previously ABSENT (null pricing and
|
package/dist/run.js
CHANGED
|
@@ -32,7 +32,6 @@ export class Run {
|
|
|
32
32
|
#abort = new AbortController();
|
|
33
33
|
#externalSignal;
|
|
34
34
|
#decisionIds = [];
|
|
35
|
-
#uncertaintyIds = [];
|
|
36
35
|
#started = false;
|
|
37
36
|
constructor(store, adapter, config, session, input, externalSignal, resume,
|
|
38
37
|
// TV-1B: durable PROVENANCE for the input (e.g. the verification
|
|
@@ -129,7 +128,6 @@ export class Run {
|
|
|
129
128
|
...(this.#config.maxTurns !== undefined ? { maxTurns: this.#config.maxTurns } : {}),
|
|
130
129
|
...(this.#config.maxTokens !== undefined ? { maxTokens: this.#config.maxTokens } : {}),
|
|
131
130
|
...(this.#config.temperature !== undefined ? { temperature: this.#config.temperature } : {}),
|
|
132
|
-
...(this.#config.compaction !== undefined ? { compaction: this.#config.compaction } : {}),
|
|
133
131
|
...(microcompact !== undefined ? { microcompact } : {}),
|
|
134
132
|
...(this.#config.maxRetries !== undefined ? { maxRetries: this.#config.maxRetries } : {}),
|
|
135
133
|
// MG-1 (A5): the kernel stamps committed envelopes with this.
|
|
@@ -151,11 +149,6 @@ export class Run {
|
|
|
151
149
|
// the human gave in the same instant as the abort is
|
|
152
150
|
// recorded, exactly once.
|
|
153
151
|
approvalVerdict: (decisionId) => this.#session.approvalVerdict(decisionId),
|
|
154
|
-
uncertaintyVerdict: (executionId) => this.#session.uncertaintyVerdict(executionId),
|
|
155
|
-
resolveUncertainty: (executionId) => new Promise((resolve) => {
|
|
156
|
-
this.#uncertaintyIds.push(executionId);
|
|
157
|
-
this.#session.registerUncertaintyResolver(executionId, resolve);
|
|
158
|
-
}),
|
|
159
152
|
});
|
|
160
153
|
const self = this;
|
|
161
154
|
const runLoop = async function* () {
|
|
@@ -287,9 +280,6 @@ export class Run {
|
|
|
287
280
|
for (const decisionId of this.#decisionIds) {
|
|
288
281
|
this.#session.dropResolver(decisionId);
|
|
289
282
|
}
|
|
290
|
-
for (const executionId of this.#uncertaintyIds) {
|
|
291
|
-
this.#session.dropUncertaintyResolver(executionId);
|
|
292
|
-
}
|
|
293
283
|
// E1: the run's ledger story — the run_end lands synchronously
|
|
294
284
|
// (a killed run leaves no run_end, and the next init marks it).
|
|
295
285
|
tracer?.finishRun();
|
package/dist/session.d.ts
CHANGED
|
@@ -287,13 +287,9 @@ export declare class AgentSession {
|
|
|
287
287
|
resolveUncertain(executionId: string, resolution: "rerun" | "abandoned"): Promise<void>;
|
|
288
288
|
/** The runId that owns an execution — from its durable started record. */
|
|
289
289
|
private runIdFor;
|
|
290
|
-
registerUncertaintyResolver(executionId: string, resolve: (resolution: "rerun" | "abandoned") => void): void;
|
|
291
|
-
dropUncertaintyResolver(executionId: string): void;
|
|
292
290
|
registerResolver(decisionId: string, resolve: (decision: PermissionDecision) => void): void;
|
|
293
291
|
/** round 4 (adversarial): a verdict the human already gave for a live decision. */
|
|
294
292
|
approvalVerdict(decisionId: string): boolean | undefined;
|
|
295
|
-
/** round 4 (adversarial): a verdict the human already gave for a live execution. */
|
|
296
|
-
uncertaintyVerdict(executionId: string): "rerun" | "abandoned" | undefined;
|
|
297
293
|
/**
|
|
298
294
|
* round 5(P1-5): flush every verdict submitted to a live resolver that is
|
|
299
295
|
* not yet durable. Called from the Run iterator's FINALLY — whether the
|
|
@@ -386,13 +382,6 @@ export interface SessionConfig {
|
|
|
386
382
|
readonly maxTurns?: number;
|
|
387
383
|
readonly maxTokens?: number;
|
|
388
384
|
readonly temperature?: number;
|
|
389
|
-
/**
|
|
390
|
-
* DEPRECATED (ADR-0044): forwarded to the loop's deprecated field,
|
|
391
|
-
* which IGNORES it — kept for type compatibility, removed at 1.0.
|
|
392
|
-
*/
|
|
393
|
-
readonly compaction?: {
|
|
394
|
-
readonly thresholdTokens: number;
|
|
395
|
-
};
|
|
396
385
|
/** C area: microcompact threshold — passed through to the loop verbatim. */
|
|
397
386
|
readonly microcompact?: {
|
|
398
387
|
readonly thresholdTokens: number;
|
package/dist/session.js
CHANGED
|
@@ -93,26 +93,21 @@ export class AgentSession {
|
|
|
93
93
|
// selection or first request — never eagerly at open.
|
|
94
94
|
#profilePending;
|
|
95
95
|
#pendingResolvers = new Map();
|
|
96
|
-
#uncertaintyResolvers = new Map();
|
|
97
96
|
#answered = new Set();
|
|
98
|
-
/** round 7: verdicts already passed to a live resolver — the resolution event
|
|
99
|
-
* lands in the log asynchronously (the loop owns it), so the ledger
|
|
100
|
-
* alone cannot make resolveUncertain idempotent across the same tick. */
|
|
101
|
-
#uncertaintyAnswered = new Set();
|
|
102
97
|
/** round 4 (adversarial): verdicts the human GAVE, recorded when passed to a live
|
|
103
98
|
* resolver. If an abort races the verdict, the loop / recovery queries
|
|
104
99
|
* these and records the decision (exactly once) instead of losing it. */
|
|
105
100
|
#approvalVerdicts = new Map();
|
|
106
|
-
#uncertaintyVerdicts = new Map();
|
|
107
101
|
/** round 5(P1-5): verdicts submitted to a LIVE resolver but not yet known
|
|
108
|
-
* durable. An async generator only advances on next(), so approve()
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
-
*
|
|
102
|
+
* durable. An async generator only advances on next(), so approve()
|
|
103
|
+
* CANNOT wait for the loop to persist — that would deadlock (the
|
|
104
|
+
* consumer waits while the generator needs a next()). Instead the
|
|
105
|
+
* verdict is recorded here, and the Run's iterator FINALLY flushes
|
|
106
|
+
* every not-yet-durable verdict to disk — an abandoned generator can
|
|
107
|
+
* never lose a verdict the human gave. (CT-1: uncertainty verdicts no
|
|
108
|
+
* longer have a live resolver — the loop never took one since
|
|
109
|
+
* ADR-0038 — so they always take the direct-persist path below.) */
|
|
114
110
|
#pendingDurableApprovals = new Map();
|
|
115
|
-
#pendingDurableUncertainties = new Map();
|
|
116
111
|
#poisoned = null;
|
|
117
112
|
/** E6 (h): the circuit-breaker counter — consecutive auto-policy
|
|
118
113
|
* summary failures this session (a success resets it). */
|
|
@@ -668,30 +663,10 @@ export class AgentSession {
|
|
|
668
663
|
if (!record)
|
|
669
664
|
throw new Error(`no execution record for ${executionId}`);
|
|
670
665
|
if (record.status !== "uncertain")
|
|
671
|
-
return; // idempotent + irreversible
|
|
672
|
-
//
|
|
673
|
-
//
|
|
674
|
-
//
|
|
675
|
-
if (this.#uncertaintyAnswered.has(executionId))
|
|
676
|
-
return;
|
|
677
|
-
this.#uncertaintyAnswered.add(executionId);
|
|
678
|
-
// round 7: with a LIVE resolver, the active loop / recovery generator
|
|
679
|
-
// OWNS the resolution event — it appends, yields, and persists it
|
|
680
|
-
// through the Run, so the consumer's stream and the durable log
|
|
681
|
-
// stay identical. We only pass the verdict; a hidden append here
|
|
682
|
-
// would leave a seq gap. round 4 (adversarial): the verdict is recorded so an
|
|
683
|
-
// abort racing it cannot lose it.
|
|
684
|
-
const resolver = this.#uncertaintyResolvers.get(executionId);
|
|
685
|
-
if (resolver !== undefined) {
|
|
686
|
-
this.#uncertaintyVerdicts.set(executionId, resolution);
|
|
687
|
-
// round 5(P1-5): submitted — flushed to disk by the Run's finally
|
|
688
|
-
// if the generator never persists it.
|
|
689
|
-
this.#pendingDurableUncertainties.set(executionId, { resolution, callId: record.callId });
|
|
690
|
-
this.#uncertaintyResolvers.delete(executionId);
|
|
691
|
-
resolver(resolution);
|
|
692
|
-
return;
|
|
693
|
-
}
|
|
694
|
-
// round 7: OFFLINE verdict — no live resolver: persist directly.
|
|
666
|
+
return; // idempotent + irreversible (the append below is synchronous, so a same-tick second call sees it)
|
|
667
|
+
// CT-1 (ADR-0051 Amendment 6): the verdict is persisted directly — there
|
|
668
|
+
// is no live resolver to hand it to (the loop never read one since
|
|
669
|
+
// ADR-0038; the round-7 live branch that waited for it was unreachable).
|
|
695
670
|
// round 4: the verdict is attributed to the ORIGINAL run of the execution
|
|
696
671
|
// — never the fake runId "resolution".
|
|
697
672
|
const runId = this.runIdFor(executionId);
|
|
@@ -738,12 +713,6 @@ export class AgentSession {
|
|
|
738
713
|
throw new Error(`no durable execution record for ${executionId}`);
|
|
739
714
|
return rec.runId;
|
|
740
715
|
}
|
|
741
|
-
registerUncertaintyResolver(executionId, resolve) {
|
|
742
|
-
this.#uncertaintyResolvers.set(executionId, resolve);
|
|
743
|
-
}
|
|
744
|
-
dropUncertaintyResolver(executionId) {
|
|
745
|
-
this.#uncertaintyResolvers.delete(executionId);
|
|
746
|
-
}
|
|
747
716
|
// ── internal: the resolver registry ──────────────────────────────────
|
|
748
717
|
registerResolver(decisionId, resolve) {
|
|
749
718
|
this.#pendingResolvers.set(decisionId, resolve);
|
|
@@ -752,10 +721,6 @@ export class AgentSession {
|
|
|
752
721
|
approvalVerdict(decisionId) {
|
|
753
722
|
return this.#approvalVerdicts.get(decisionId);
|
|
754
723
|
}
|
|
755
|
-
/** round 4 (adversarial): a verdict the human already gave for a live execution. */
|
|
756
|
-
uncertaintyVerdict(executionId) {
|
|
757
|
-
return this.#uncertaintyVerdicts.get(executionId);
|
|
758
|
-
}
|
|
759
724
|
/**
|
|
760
725
|
* round 5(P1-5): flush every verdict submitted to a live resolver that is
|
|
761
726
|
* not yet durable. Called from the Run iterator's FINALLY — whether the
|
|
@@ -777,19 +742,6 @@ export class AgentSession {
|
|
|
777
742
|
}
|
|
778
743
|
this.#pendingDurableApprovals.delete(decisionId);
|
|
779
744
|
}
|
|
780
|
-
for (const [executionId, pending] of this.#pendingDurableUncertainties) {
|
|
781
|
-
const resolved = log.all.find((e) => e.type === "tool_execution_resolved" && e.executionId === executionId);
|
|
782
|
-
if (resolved === undefined) {
|
|
783
|
-
const app = log.append({
|
|
784
|
-
type: "tool_execution_resolved",
|
|
785
|
-
executionId,
|
|
786
|
-
callId: pending.callId,
|
|
787
|
-
resolution: pending.resolution,
|
|
788
|
-
});
|
|
789
|
-
await this.persist(runId, app);
|
|
790
|
-
}
|
|
791
|
-
this.#pendingDurableUncertainties.delete(executionId);
|
|
792
|
-
}
|
|
793
745
|
}
|
|
794
746
|
dropResolver(decisionId) {
|
|
795
747
|
this.#pendingResolvers.delete(decisionId);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vincemakes/kiso-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.28.0",
|
|
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,11 +25,11 @@
|
|
|
25
25
|
"test": "vitest run"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
|
-
"@vincemakes/kiso-core": "0.
|
|
28
|
+
"@vincemakes/kiso-core": "0.28.0"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
31
|
-
"@vincemakes/kiso-provider-anthropic": "0.
|
|
32
|
-
"@vincemakes/kiso-provider-openai": "0.
|
|
31
|
+
"@vincemakes/kiso-provider-anthropic": "0.28.0",
|
|
32
|
+
"@vincemakes/kiso-provider-openai": "0.28.0"
|
|
33
33
|
},
|
|
34
34
|
"peerDependenciesMeta": {
|
|
35
35
|
"@vincemakes/kiso-provider-anthropic": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
}
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@vincemakes/kiso-evals": "0.
|
|
43
|
+
"@vincemakes/kiso-evals": "0.28.0",
|
|
44
44
|
"@types/node": "^26.1.2",
|
|
45
45
|
"typescript": "^5.7.2",
|
|
46
46
|
"vitest": "^3.0.0"
|