@statelyai/agent 2.0.0-alpha.30 → 2.0.0-alpha.32
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 +1743 -0
- package/dist/ai-sdk.cjs +8 -8
- package/dist/ai-sdk.d.cts +1 -1
- package/dist/ai-sdk.d.mts +1 -1
- package/dist/ai-sdk.mjs +3 -3
- package/dist/{decision-CIb7ddIv.cjs → decision-BPdEaxPf.cjs} +30 -17
- package/dist/{decision-BHkvuImD.mjs → decision-CV7WiV5C.mjs} +22 -9
- package/dist/{event-log-BZRfBRd7.cjs → event-log-CKWeC7H-.cjs} +125 -27
- package/dist/{event-log-DJCMHek_.mjs → event-log-DAqsalT1.mjs} +108 -28
- package/dist/{event-log-store-DsP6GCRh.mjs → event-log-store-BGehvVTb.mjs} +2 -2
- package/dist/{event-log-store-CIIJohjj.d.mts → event-log-store-C2NjVlWU.d.mts} +13 -5
- package/dist/{event-log-store-DZR4IIWe.cjs → event-log-store-DKyE7JKr.cjs} +2 -2
- package/dist/{event-log-store-CLAC9q2Y.d.cts → event-log-store-s73r1Hxf.d.cts} +13 -5
- package/dist/index.cjs +129 -21
- package/dist/index.d.cts +59 -11
- package/dist/index.d.mts +59 -11
- package/dist/index.mjs +126 -19
- package/dist/log.cjs +40 -5
- package/dist/log.d.cts +1 -1
- package/dist/log.d.mts +1 -1
- package/dist/log.mjs +40 -5
- package/dist/machines.cjs +1 -1
- package/dist/machines.mjs +1 -1
- package/dist/{model-source-BCKg4qJ1.cjs → model-source-BQ97_l1-.cjs} +4 -5
- package/dist/{model-source-BaHwJ1wK.mjs → model-source-BilDEyqk.mjs} +1 -2
- package/dist/openai.cjs +2 -2
- package/dist/openai.d.cts +1 -1
- package/dist/openai.d.mts +1 -1
- package/dist/openai.mjs +2 -2
- package/dist/otel.d.cts +1 -1
- package/dist/otel.d.mts +1 -1
- package/dist/{run-agent-BpHqkaZw.mjs → run-agent-2UnSUhDb.mjs} +93 -37
- package/dist/{run-agent-CAVt5R-r.d.mts → run-agent-Atu-wEk7.d.mts} +17 -6
- package/dist/{run-agent-CTlMc3Jb.d.cts → run-agent-B5QhabdY.d.cts} +17 -6
- package/dist/{run-agent-ctLCvNgL.cjs → run-agent-Cg0xd3K-.cjs} +93 -37
- package/dist/{setup-agent-CLPCkXsu.d.cts → setup-agent-BiF1N3td.d.cts} +11 -3
- package/dist/{setup-agent-7rV_cujV.mjs → setup-agent-CmhB-U5P.mjs} +38 -3
- package/dist/{setup-agent-DoUk7EdC.cjs → setup-agent-CwUJyqKB.cjs} +38 -3
- package/dist/{setup-agent-CGELn1qZ.d.mts → setup-agent-J9f_Wu5T.d.mts} +11 -3
- package/dist/tanstack-ai.cjs +3 -3
- package/dist/tanstack-ai.d.cts +1 -1
- package/dist/tanstack-ai.d.mts +1 -1
- package/dist/tanstack-ai.mjs +3 -3
- package/dist/testing.cjs +73 -29
- package/dist/testing.d.cts +47 -10
- package/dist/testing.d.mts +47 -10
- package/dist/testing.mjs +65 -22
- package/dist/{text-logic-DmciuVUQ.d.cts → text-logic-CYP502VT.d.cts} +9 -3
- package/dist/{text-logic-BRYOPWvY.d.mts → text-logic-DuK9HIFM.d.mts} +9 -3
- package/dist/{usage-BkM3z02Y.d.mts → usage-D7JKAxLc.d.mts} +1 -1
- package/dist/{usage-Cm_ovz9V.d.cts → usage-DVw-646x.d.cts} +1 -1
- package/dist/validate.cjs +3 -3
- package/dist/validate.d.cts +2 -2
- package/dist/validate.d.mts +2 -2
- package/dist/validate.mjs +3 -3
- package/dist/{verify-Cn86rT8l.d.mts → verify-BVz4cURF.d.mts} +14 -6
- package/dist/{verify-COFWyprJ.mjs → verify-CoCvR1eM.mjs} +55 -5
- package/dist/{verify-CVlsTZ-V.cjs → verify-D_llRCTr.cjs} +57 -7
- package/dist/{verify-Dzwd4Mvk.d.cts → verify-Dk3Vwnha.d.cts} +14 -6
- package/package.json +34 -4
- package/readme.md +70 -40
- package/skills/add-evals/SKILL.md +23 -8
- package/skills/add-traces/SKILL.md +23 -11
- package/skills/generate-machine/SKILL.md +2 -2
- package/skills/graph-engineering/SKILL.md +1 -1
- package/skills/improve-machine/SKILL.md +7 -6
- package/skills/loop-to-machine/SKILL.md +34 -7
- package/skills/loop-to-machine/policy.md +14 -18
package/dist/log.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { S as validateReplayEntries, _ as getUsageFromEvents, a as AgentReplayDivergenceError, b as recordLog, c as assertAgentLogEntry, d as createReplayEntry, g as getSnapshotStateHash, h as getLogExecutionId, i as AgentMachineVersionMismatchError, l as assertJsonSerializable, m as getDecisionAttempts, n as AGENT_INIT_EVENT_TYPE, o as NonSerializableAgentEventError, p as forkEventLog, r as AgentEventLogError, s as agentCallOccurrence, t as AGENT_EVENT_SCHEMA_VERSION, v as initEntry, x as replay, y as rebindActorSession } from "./event-log-
|
|
2
|
-
import { n as createInMemoryEventLogStore, t as AgentEventLogConflictError } from "./event-log-store-
|
|
1
|
+
import { S as validateReplayEntries, _ as getUsageFromEvents, a as AgentReplayDivergenceError, b as recordLog, c as assertAgentLogEntry, d as createReplayEntry, g as getSnapshotStateHash, h as getLogExecutionId, i as AgentMachineVersionMismatchError, l as assertJsonSerializable, m as getDecisionAttempts, n as AGENT_INIT_EVENT_TYPE, o as NonSerializableAgentEventError, p as forkEventLog, r as AgentEventLogError, s as agentCallOccurrence, t as AGENT_EVENT_SCHEMA_VERSION, v as initEntry, x as replay, y as rebindActorSession } from "./event-log-DAqsalT1.mjs";
|
|
2
|
+
import { n as createInMemoryEventLogStore, t as AgentEventLogConflictError } from "./event-log-store-BGehvVTb.mjs";
|
|
3
3
|
//#region src/event-log-store-conformance.ts
|
|
4
4
|
/**
|
|
5
5
|
* The runner-agnostic conformance suite for {@link AgentEventLogStore}
|
|
@@ -29,8 +29,11 @@ function entry(index, type, metadata) {
|
|
|
29
29
|
...metadata !== void 0 ? { metadata } : {}
|
|
30
30
|
};
|
|
31
31
|
}
|
|
32
|
+
function initFixture(executionId = "exec-src") {
|
|
33
|
+
return entry(0, AGENT_INIT_EVENT_TYPE, { executionId });
|
|
34
|
+
}
|
|
32
35
|
function entriesFrom(start, count) {
|
|
33
|
-
return Array.from({ length: count }, (_unused, i) => entry(start + i, `e${start + i}`));
|
|
36
|
+
return Array.from({ length: count }, (_unused, i) => start + i === 0 ? initFixture() : entry(start + i, `e${start + i}`));
|
|
34
37
|
}
|
|
35
38
|
function assertJsonEqual(actual, expected, message) {
|
|
36
39
|
const a = JSON.stringify(actual);
|
|
@@ -280,10 +283,42 @@ const cases = [
|
|
|
280
283
|
expectedIndex: 1,
|
|
281
284
|
entries: [entry(1, "branch")]
|
|
282
285
|
});
|
|
283
|
-
assertJsonEqual((await store.read("fork-1")).map((e) => e.event.type), [
|
|
286
|
+
assertJsonEqual((await store.read("fork-1")).map((e) => e.event.type), [AGENT_INIT_EVENT_TYPE, "branch"], "a forked thread must append independently from its copied length");
|
|
284
287
|
if (await store.length("src") !== 3) fail("appending to a fork must not touch the source thread");
|
|
285
288
|
}
|
|
286
289
|
},
|
|
290
|
+
{
|
|
291
|
+
name: "a fork is its own lineage: a fresh executionId, and forkedFrom naming the parent",
|
|
292
|
+
async run(create) {
|
|
293
|
+
const store = await create();
|
|
294
|
+
const source = entriesFrom(0, 3);
|
|
295
|
+
await store.append({
|
|
296
|
+
threadId: "src",
|
|
297
|
+
expectedIndex: 0,
|
|
298
|
+
entries: source
|
|
299
|
+
});
|
|
300
|
+
await store.fork({
|
|
301
|
+
threadId: "src",
|
|
302
|
+
newThreadId: "fork-a",
|
|
303
|
+
upToIndex: 2
|
|
304
|
+
});
|
|
305
|
+
await store.fork({
|
|
306
|
+
threadId: "src",
|
|
307
|
+
newThreadId: "fork-b",
|
|
308
|
+
upToIndex: 2
|
|
309
|
+
});
|
|
310
|
+
const [a, b] = [await store.read("fork-a"), await store.read("fork-b")];
|
|
311
|
+
const ids = [getLogExecutionId(a), getLogExecutionId(b)];
|
|
312
|
+
if (typeof ids[0] !== "string" || typeof ids[1] !== "string") fail("a fork's init entry must carry a string metadata.executionId");
|
|
313
|
+
if (ids.includes("exec-src") || ids[0] === ids[1]) fail("every fork must mint its own executionId, not reuse the parent's or a sibling's");
|
|
314
|
+
assertJsonEqual(a[0].metadata?.forkedFrom, {
|
|
315
|
+
executionId: "exec-src",
|
|
316
|
+
logIndex: 2
|
|
317
|
+
}, "a fork's init entry must record forkedFrom: { executionId, logIndex }");
|
|
318
|
+
assertJsonEqual(a.slice(1), source.slice(1, 2), "a fork must copy every entry after the init entry unchanged");
|
|
319
|
+
assertJsonEqual(await store.read("src"), source, "forking must not touch the source thread");
|
|
320
|
+
}
|
|
321
|
+
},
|
|
287
322
|
{
|
|
288
323
|
name: "fork rejects a non-empty target, an unknown source, and an out-of-range cutoff (0 included)",
|
|
289
324
|
async run(create) {
|
|
@@ -356,7 +391,7 @@ const cases = [
|
|
|
356
391
|
]) await store.append({
|
|
357
392
|
threadId,
|
|
358
393
|
expectedIndex: 0,
|
|
359
|
-
entries: [
|
|
394
|
+
entries: [initFixture()]
|
|
360
395
|
});
|
|
361
396
|
await store.fork({
|
|
362
397
|
threadId: "user:a",
|
package/dist/machines.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_setup_agent = require("./setup-agent-
|
|
2
|
+
const require_setup_agent = require("./setup-agent-CwUJyqKB.cjs");
|
|
3
3
|
//#region src/machines/internal.ts
|
|
4
4
|
/** The builtin inline text request every preset lowers a request entry to. */
|
|
5
5
|
const GENERATE_TEXT_SRC = "agent.generateText";
|
package/dist/machines.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as setupAgent } from "./setup-agent-
|
|
1
|
+
import { r as setupAgent } from "./setup-agent-CmhB-U5P.mjs";
|
|
2
2
|
//#region src/machines/internal.ts
|
|
3
3
|
/** The builtin inline text request every preset lowers a request entry to. */
|
|
4
4
|
const GENERATE_TEXT_SRC = "agent.generateText";
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
const require_event_log = require("./event-log-
|
|
2
|
-
const require_decision = require("./decision-CIb7ddIv.cjs");
|
|
1
|
+
const require_event_log = require("./event-log-CKWeC7H-.cjs");
|
|
3
2
|
//#region src/internal/model-source.ts
|
|
4
3
|
function hasEntries(value) {
|
|
5
|
-
return
|
|
4
|
+
return require_event_log.isRecord(value) && Object.keys(value).length > 0;
|
|
6
5
|
}
|
|
7
6
|
function isMachineLike(value) {
|
|
8
7
|
return "config" in value && typeof value.transition === "function";
|
|
@@ -25,13 +24,13 @@ function describeValue(value) {
|
|
|
25
24
|
* model values are. Throws, naming what it got, for anything else. @internal
|
|
26
25
|
*/
|
|
27
26
|
function resolveModelSource(adapter, source) {
|
|
28
|
-
if (
|
|
27
|
+
if (require_event_log.isRecord(source)) {
|
|
29
28
|
if (typeof source.createMachine === "function") {
|
|
30
29
|
if (hasEntries(source.models)) return { models: source.models };
|
|
31
30
|
} else if (isMachineLike(source)) {
|
|
32
31
|
const models = require_event_log.getAgentExecutionOptions(source)?.models;
|
|
33
32
|
if (hasEntries(models)) return { models };
|
|
34
|
-
} else if (
|
|
33
|
+
} else if (require_event_log.isRecord(source.models) || typeof source.resolveModel === "function") return source;
|
|
35
34
|
}
|
|
36
35
|
throw new TypeError(`${adapter}: expected { models }, { resolveModel }, a setupAgent(...) result with models, or a machine from its createMachine; got ${describeValue(source)}.`);
|
|
37
36
|
}
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { H as getAgentExecutionOptions } from "./event-log-
|
|
2
|
-
import { m as isRecord } from "./decision-BHkvuImD.mjs";
|
|
1
|
+
import { H as getAgentExecutionOptions, lt as isRecord } from "./event-log-DAqsalT1.mjs";
|
|
3
2
|
//#region src/internal/model-source.ts
|
|
4
3
|
function hasEntries(value) {
|
|
5
4
|
return isRecord(value) && Object.keys(value).length > 0;
|
package/dist/openai.cjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_event_log = require("./event-log-
|
|
3
|
-
const require_decision = require("./decision-
|
|
2
|
+
const require_event_log = require("./event-log-CKWeC7H-.cjs");
|
|
3
|
+
const require_decision = require("./decision-BPdEaxPf.cjs");
|
|
4
4
|
//#region src/openai/index.ts
|
|
5
5
|
/** Thrown for a message part Chat Completions cannot carry — dropping it would
|
|
6
6
|
* silently change what the model sees. */
|
package/dist/openai.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as AgentToolChoice, n as AgentMessage, s as AgentTools, u as ChosenEvent } from "./types-Dp5_Ru4R.cjs";
|
|
2
|
-
import { N as AgentDecisionRequest, W as AgentEventDescriptor, c as AgentRequestExecutorInfo, f as AgentTextRequest, r as AgentFinishReason, t as AgentCallUsage } from "./text-logic-
|
|
2
|
+
import { N as AgentDecisionRequest, W as AgentEventDescriptor, c as AgentRequestExecutorInfo, f as AgentTextRequest, r as AgentFinishReason, t as AgentCallUsage } from "./text-logic-CYP502VT.cjs";
|
|
3
3
|
import OpenAI from "openai";
|
|
4
4
|
import { ChatCompletion, ChatCompletionCreateParamsNonStreaming, ChatCompletionMessageParam, ChatCompletionTool } from "openai/resources/chat/completions/completions.js";
|
|
5
5
|
//#region src/openai/index.d.ts
|
package/dist/openai.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { i as AgentToolChoice, n as AgentMessage, s as AgentTools, u as ChosenEvent } from "./types-Dp5_Ru4R.mjs";
|
|
2
|
-
import { N as AgentDecisionRequest, W as AgentEventDescriptor, c as AgentRequestExecutorInfo, f as AgentTextRequest, r as AgentFinishReason, t as AgentCallUsage } from "./text-logic-
|
|
2
|
+
import { N as AgentDecisionRequest, W as AgentEventDescriptor, c as AgentRequestExecutorInfo, f as AgentTextRequest, r as AgentFinishReason, t as AgentCallUsage } from "./text-logic-DuK9HIFM.mjs";
|
|
3
3
|
import OpenAI from "openai";
|
|
4
4
|
import { ChatCompletion, ChatCompletionCreateParamsNonStreaming, ChatCompletionMessageParam, ChatCompletionTool } from "openai/resources/chat/completions/completions.js";
|
|
5
5
|
//#region src/openai/index.d.ts
|
package/dist/openai.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { L as parseProviderOutput, R as providerOutputSchema, X as getJsonSchemaSync, Y as getJsonSchema,
|
|
2
|
-
import { c as renderDecisionAttempts } from "./decision-
|
|
1
|
+
import { L as parseProviderOutput, R as providerOutputSchema, X as getJsonSchemaSync, Y as getJsonSchema, dt as AgentTruncatedError, j as getAgentOutputMode, tt as isStandardSchema, w as AGENT_USAGE_TOKEN_FIELDS } from "./event-log-DAqsalT1.mjs";
|
|
2
|
+
import { c as renderDecisionAttempts } from "./decision-CV7WiV5C.mjs";
|
|
3
3
|
//#region src/openai/index.ts
|
|
4
4
|
/** Thrown for a message part Chat Completions cannot carry — dropping it would
|
|
5
5
|
* silently change what the model sees. */
|
package/dist/otel.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as AgentTraceEvent } from "./run-agent-
|
|
1
|
+
import { g as AgentTraceEvent } from "./run-agent-B5QhabdY.cjs";
|
|
2
2
|
import { Attributes, Tracer, TracerProvider } from "@opentelemetry/api";
|
|
3
3
|
//#region src/otel/index.d.ts
|
|
4
4
|
/** Options for {@link createOtelTraceHandler}. */
|
package/dist/otel.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { g as AgentTraceEvent } from "./run-agent-
|
|
1
|
+
import { g as AgentTraceEvent } from "./run-agent-Atu-wEk7.mjs";
|
|
2
2
|
import { Attributes, Tracer, TracerProvider } from "@opentelemetry/api";
|
|
3
3
|
//#region src/otel/index.d.ts
|
|
4
4
|
/** Options for {@link createOtelTraceHandler}. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { B as responseMessagesOf, C as AGENT_USAGE_EVENT_TYPE, F as normalizeGeneratorResult, J as findNonSerializableContextPaths, M as getCallFinishReason, N as getCallUsage, P as isTextLogic, S as validateReplayEntries, U as getRegisteredAgentExecutionOptions, V as executorBoundLogics, W as isUnboundPlaceholder, _ as getUsageFromEvents, d as createReplayEntry, f as foldLog, g as getSnapshotStateHash, h as getLogExecutionId, i as AgentMachineVersionMismatchError, l as assertJsonSerializable, nt as resolveMachineVersion, ot as validateSchemaSync, s as agentCallOccurrence, st as
|
|
2
|
-
import { d as getAcceptedEvents, l as resolveDecision, n as acceptedDecisionOptions, s as isDecisionLogic, t as AgentDecisionExhaustedError } from "./decision-
|
|
3
|
-
import { t as AgentEventLogConflictError } from "./event-log-store-
|
|
1
|
+
import { B as responseMessagesOf, C as AGENT_USAGE_EVENT_TYPE, F as normalizeGeneratorResult, J as findNonSerializableContextPaths, M as getCallFinishReason, N as getCallUsage, P as isTextLogic, S as validateReplayEntries, U as getRegisteredAgentExecutionOptions, V as executorBoundLogics, W as isUnboundPlaceholder, _ as getUsageFromEvents, d as createReplayEntry, f as foldLog, g as getSnapshotStateHash, h as getLogExecutionId, i as AgentMachineVersionMismatchError, l as assertJsonSerializable, nt as resolveMachineVersion, ot as validateSchemaSync, s as agentCallOccurrence, st as canonicalJson, tt as isStandardSchema, u as canonicalEventJson, ut as AgentError, v as initEntry, x as replay } from "./event-log-DAqsalT1.mjs";
|
|
2
|
+
import { d as getAcceptedEvents, f as getHumanEventTypes, l as resolveDecision, n as acceptedDecisionOptions, s as isDecisionLogic, t as AgentDecisionExhaustedError } from "./decision-CV7WiV5C.mjs";
|
|
3
|
+
import { t as AgentEventLogConflictError } from "./event-log-store-BGehvVTb.mjs";
|
|
4
4
|
import { createAsyncLogic, getNextTransitions, isMachineSnapshot, stopActor } from "xstate";
|
|
5
5
|
import { createDurable } from "xstate/durable";
|
|
6
6
|
//#region src/run-agent.ts
|
|
@@ -290,6 +290,13 @@ function unrebindableChildRequestError(childPath, stateName, requestSrc, kind) {
|
|
|
290
290
|
function declaresUsageTransition(snapshot) {
|
|
291
291
|
return getNextTransitions(snapshot).some((transition) => transition.eventType === "@agent.usage" || transition.eventType === "*");
|
|
292
292
|
}
|
|
293
|
+
function observe(name, call) {
|
|
294
|
+
try {
|
|
295
|
+
call();
|
|
296
|
+
} catch (error) {
|
|
297
|
+
console.error(`@statelyai/agent: ${name} threw; the run continues.`, error);
|
|
298
|
+
}
|
|
299
|
+
}
|
|
293
300
|
/**
|
|
294
301
|
* Builds the ONE place a trace payload is emitted: it hands the payload to the
|
|
295
302
|
* envelope-stamping trace sink and, from that same payload, invokes the sugar
|
|
@@ -306,21 +313,21 @@ function createTraceDispatch(sinks) {
|
|
|
306
313
|
return (payload, self) => {
|
|
307
314
|
switch (payload.type) {
|
|
308
315
|
case "stream.chunk":
|
|
309
|
-
sinks.onTrace?.(payload, self);
|
|
310
|
-
sinks.onChunk?.(payload.chunk, { request: payload.request });
|
|
316
|
+
observe("onTrace", () => sinks.onTrace?.(payload, self));
|
|
317
|
+
observe("onChunk", () => sinks.onChunk?.(payload.chunk, { request: payload.request }));
|
|
311
318
|
return;
|
|
312
319
|
case "request.end":
|
|
313
|
-
sinks.onResult?.(payload.request, {
|
|
320
|
+
observe("onResult", () => sinks.onResult?.(payload.request, {
|
|
314
321
|
result: payload.output,
|
|
315
322
|
raw: payload.raw
|
|
316
|
-
});
|
|
317
|
-
sinks.onTrace?.(payload, self);
|
|
323
|
+
}));
|
|
324
|
+
observe("onTrace", () => sinks.onTrace?.(payload, self));
|
|
318
325
|
return;
|
|
319
326
|
case "machine.transition":
|
|
320
|
-
sinks.onTrace?.(payload, self);
|
|
321
|
-
sinks.onTransition?.(payload.snapshot, payload.event);
|
|
327
|
+
observe("onTrace", () => sinks.onTrace?.(payload, self));
|
|
328
|
+
observe("onTransition", () => sinks.onTransition?.(payload.snapshot, payload.event));
|
|
322
329
|
return;
|
|
323
|
-
default: sinks.onTrace?.(payload, self);
|
|
330
|
+
default: observe("onTrace", () => sinks.onTrace?.(payload, self));
|
|
324
331
|
}
|
|
325
332
|
};
|
|
326
333
|
}
|
|
@@ -509,6 +516,11 @@ function bindDecisionLogic(logic, runCtx) {
|
|
|
509
516
|
schemas: runCtx.schemas,
|
|
510
517
|
eventTypes: declaredEventTypes
|
|
511
518
|
}) : [];
|
|
519
|
+
const agentCan = (event) => {
|
|
520
|
+
if (!actorRef) return true;
|
|
521
|
+
const snapshot = actorRef.getSnapshot();
|
|
522
|
+
return !getHumanEventTypes(snapshot).has(event.type) && snapshot.can(event);
|
|
523
|
+
};
|
|
512
524
|
const lowered = logic.request(input);
|
|
513
525
|
const request = {
|
|
514
526
|
...lowered,
|
|
@@ -521,7 +533,7 @@ function bindDecisionLogic(logic, runCtx) {
|
|
|
521
533
|
const options = acceptedDecisionOptions(request, (event) => {
|
|
522
534
|
let accepted;
|
|
523
535
|
try {
|
|
524
|
-
accepted =
|
|
536
|
+
accepted = agentCan(event);
|
|
525
537
|
} catch {
|
|
526
538
|
accepted = false;
|
|
527
539
|
}
|
|
@@ -532,6 +544,10 @@ function bindDecisionLogic(logic, runCtx) {
|
|
|
532
544
|
request.options = options;
|
|
533
545
|
request.withheld = withheld;
|
|
534
546
|
}
|
|
547
|
+
if (actorRef) {
|
|
548
|
+
const humanEventTypes = getHumanEventTypes(actorRef.getSnapshot());
|
|
549
|
+
request.events = events.filter((event) => !humanEventTypes.has(event.type));
|
|
550
|
+
}
|
|
535
551
|
if (options?.length === 0) {
|
|
536
552
|
const error = new AgentDecisionExhaustedError([]);
|
|
537
553
|
error.message = `Decision '${request.name}' has no offered option the current snapshot accepts; no model call was made.`;
|
|
@@ -554,7 +570,7 @@ function bindDecisionLogic(logic, runCtx) {
|
|
|
554
570
|
} }, {
|
|
555
571
|
maxRetries: lowered.maxRetries ?? logic.maxRetries,
|
|
556
572
|
signal,
|
|
557
|
-
canTake:
|
|
573
|
+
canTake: agentCan
|
|
558
574
|
});
|
|
559
575
|
if (priorAttempts.length > 0) runCtx.noteDecision?.(chosen, priorAttempts);
|
|
560
576
|
actorRef?.send(chosen);
|
|
@@ -870,7 +886,7 @@ function assertThreadMatchesEvents(threadId, stored, events) {
|
|
|
870
886
|
const givenEntry = events[index];
|
|
871
887
|
const storedHash = storedEntry.verification?.stateHash;
|
|
872
888
|
const givenHash = givenEntry.verification?.stateHash;
|
|
873
|
-
if (!(storedEntry.id === givenEntry.id && storedEntry.index === givenEntry.index && canonicalEventJson(storedEntry.event) === canonicalEventJson(givenEntry.event) && (storedHash === void 0 || givenHash === void 0 || storedHash === givenHash))) throw new AgentError("event-log-conflict", `createAgentRuntime: the given \`events\` diverge from thread "${threadId}" at index ${index} (stored entry '${storedEntry.id}', given '${givenEntry.id}') — the log passed in is not this thread's log.`);
|
|
889
|
+
if (!(storedEntry.id === givenEntry.id && storedEntry.index === givenEntry.index && canonicalEventJson(storedEntry.event) === canonicalEventJson(givenEntry.event) && (storedHash === void 0 || givenHash === void 0 || storedHash === givenHash) && (index > 0 || getLogExecutionId([storedEntry]) === getLogExecutionId([givenEntry])))) throw new AgentError("event-log-conflict", `createAgentRuntime: the given \`events\` diverge from thread "${threadId}" at index ${index} (stored entry '${storedEntry.id}', given '${givenEntry.id}') — the log passed in is not this thread's log.`);
|
|
874
890
|
}
|
|
875
891
|
}
|
|
876
892
|
const QUIESCENT = Symbol("quiescent");
|
|
@@ -1000,13 +1016,32 @@ function createAgentRuntime(machine, options = {}) {
|
|
|
1000
1016
|
let loggingEnabled = true;
|
|
1001
1017
|
const attemptsByEvent = /* @__PURE__ */ new WeakMap();
|
|
1002
1018
|
let logFold;
|
|
1019
|
+
const stopLogging = (error) => {
|
|
1020
|
+
if (!loggingEnabled) return;
|
|
1021
|
+
loggingEnabled = false;
|
|
1022
|
+
if (store !== void 0) {
|
|
1023
|
+
journalError ??= error;
|
|
1024
|
+
stopRun({
|
|
1025
|
+
cause: "journal",
|
|
1026
|
+
error
|
|
1027
|
+
});
|
|
1028
|
+
return;
|
|
1029
|
+
}
|
|
1030
|
+
console.warn(`@statelyai/agent: this run's log stopped at entry ${logEntries.length}, so result.events is incomplete: ${error instanceof Error ? error.message : String(error)}. Pass input and events that JSON can hold.`);
|
|
1031
|
+
};
|
|
1003
1032
|
const appendLogEntry = (event, attempts) => {
|
|
1004
1033
|
if (!loggingEnabled) return;
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1034
|
+
let entry;
|
|
1035
|
+
try {
|
|
1036
|
+
entry = createReplayEntry(logMachine, logEntries, event, {
|
|
1037
|
+
machineVersion,
|
|
1038
|
+
verification: false,
|
|
1039
|
+
...attempts !== void 0 ? { attempts } : {}
|
|
1040
|
+
});
|
|
1041
|
+
} catch (error) {
|
|
1042
|
+
stopLogging(error);
|
|
1043
|
+
return;
|
|
1044
|
+
}
|
|
1010
1045
|
if (verificationEnabled && logFold !== null) try {
|
|
1011
1046
|
logFold ??= foldLog(logMachine, logEntries, {
|
|
1012
1047
|
machineVersion,
|
|
@@ -1018,7 +1053,7 @@ function createAgentRuntime(machine, options = {}) {
|
|
|
1018
1053
|
}
|
|
1019
1054
|
logEntries.push(entry);
|
|
1020
1055
|
journalEntry(entry);
|
|
1021
|
-
options.onEvent?.(entry);
|
|
1056
|
+
observe("onEvent", () => options.onEvent?.(entry));
|
|
1022
1057
|
return entry;
|
|
1023
1058
|
};
|
|
1024
1059
|
const recordUsage = (usage, source = {}) => {
|
|
@@ -1193,8 +1228,8 @@ function createAgentRuntime(machine, options = {}) {
|
|
|
1193
1228
|
event
|
|
1194
1229
|
});
|
|
1195
1230
|
const on = options.on ?? {};
|
|
1196
|
-
on[event.type]?.(event);
|
|
1197
|
-
if (event.type !== "*") on["*"]?.(event);
|
|
1231
|
+
observe(`on['${event.type}']`, () => on[event.type]?.(event));
|
|
1232
|
+
if (event.type !== "*") observe("on['*']", () => on["*"]?.(event));
|
|
1198
1233
|
};
|
|
1199
1234
|
const inspect = options.inspect === void 0 ? void 0 : (event) => {
|
|
1200
1235
|
if (typeof options.inspect === "function") options.inspect(event);
|
|
@@ -1248,14 +1283,15 @@ function createAgentRuntime(machine, options = {}) {
|
|
|
1248
1283
|
}
|
|
1249
1284
|
}, inspect ? { inspect } : void 0);
|
|
1250
1285
|
const runErrorCause = (error) => budgetExceeded ? "max-model-calls" : wrapsDecisionExhausted(error) ? "decision-exhausted" : "machine";
|
|
1251
|
-
const commit = (snapshot, event) => {
|
|
1286
|
+
const commit = (snapshot, event, ignored = false) => {
|
|
1252
1287
|
const from = { value: (current ?? snapshot).value };
|
|
1253
1288
|
current = snapshot;
|
|
1254
1289
|
onTrace({
|
|
1255
1290
|
type: "machine.transition",
|
|
1256
1291
|
from,
|
|
1257
1292
|
snapshot,
|
|
1258
|
-
event
|
|
1293
|
+
event,
|
|
1294
|
+
...ignored ? { ignored: true } : {}
|
|
1259
1295
|
});
|
|
1260
1296
|
};
|
|
1261
1297
|
/** True for a child completion/failure whose child is no longer running under the current state. */
|
|
@@ -1269,14 +1305,23 @@ function createAgentRuntime(machine, options = {}) {
|
|
|
1269
1305
|
if (started) throw new AgentError("runtime-started", "createAgentRuntime: `start` was already called.");
|
|
1270
1306
|
started = true;
|
|
1271
1307
|
let resumeEvents = init.events;
|
|
1308
|
+
let resumedFromStore = false;
|
|
1272
1309
|
if (store !== void 0) {
|
|
1273
1310
|
const storedThread = await store.read(threadId);
|
|
1274
1311
|
if (resumeEvents !== void 0) {
|
|
1275
1312
|
if (storedThread.length !== resumeEvents.length) throw new AgentEventLogConflictError(threadId, resumeEvents.length, storedThread.length);
|
|
1276
1313
|
assertThreadMatchesEvents(threadId, storedThread, resumeEvents);
|
|
1277
|
-
|
|
1314
|
+
resumedFromStore = storedThread.length > 0;
|
|
1315
|
+
} else if (storedThread.length > 0) {
|
|
1316
|
+
resumeEvents = storedThread;
|
|
1317
|
+
resumedFromStore = true;
|
|
1318
|
+
}
|
|
1278
1319
|
}
|
|
1279
1320
|
const resolvedInput = resolveMachineInput(machine, init.input);
|
|
1321
|
+
const threadInit = resumeEvents?.[0]?.event;
|
|
1322
|
+
if (resumedFromStore && init.input !== void 0 && threadInit !== void 0 && Object.hasOwn(threadInit, "input")) {
|
|
1323
|
+
if (canonicalJson(threadInit.input) !== canonicalJson(resolvedInput)) throw new AgentError("thread-input-mismatch", `createAgentRuntime: thread '${threadId}' was started with different input. A thread that already has entries is resumed, not restarted; give a new run a new threadId.`);
|
|
1324
|
+
}
|
|
1280
1325
|
let effectiveSnapshot = init.snapshot;
|
|
1281
1326
|
let seedInitEntry;
|
|
1282
1327
|
const restoredPersistedSnapshot = () => {
|
|
@@ -1294,18 +1339,25 @@ function createAgentRuntime(machine, options = {}) {
|
|
|
1294
1339
|
* run WITHOUT a log rather than failing it.
|
|
1295
1340
|
*/
|
|
1296
1341
|
const appendInitEntry = (candidates, metadata) => {
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1342
|
+
let lastError;
|
|
1343
|
+
for (const candidate of candidates) for (const verification of verificationEnabled ? [true, false] : [false]) {
|
|
1344
|
+
let entry;
|
|
1345
|
+
try {
|
|
1346
|
+
entry = initEntry(logMachine, candidate, {
|
|
1347
|
+
machineVersion,
|
|
1348
|
+
verification,
|
|
1349
|
+
metadata
|
|
1350
|
+
});
|
|
1351
|
+
} catch (error) {
|
|
1352
|
+
lastError = error;
|
|
1353
|
+
continue;
|
|
1354
|
+
}
|
|
1303
1355
|
logEntries.push(entry);
|
|
1304
1356
|
journalEntry(entry);
|
|
1305
|
-
options.onEvent?.(entry);
|
|
1357
|
+
observe("onEvent", () => options.onEvent?.(entry));
|
|
1306
1358
|
return;
|
|
1307
|
-
}
|
|
1308
|
-
|
|
1359
|
+
}
|
|
1360
|
+
stopLogging(lastError);
|
|
1309
1361
|
};
|
|
1310
1362
|
/** Init forms for a snapshot resume, most faithful first. */
|
|
1311
1363
|
const snapshotInitCandidates = () => {
|
|
@@ -1355,7 +1407,9 @@ function createAgentRuntime(machine, options = {}) {
|
|
|
1355
1407
|
machineVersion: tail.machineVersion
|
|
1356
1408
|
});
|
|
1357
1409
|
const bridgeMeta = readAgentMeta(init.snapshot);
|
|
1358
|
-
|
|
1410
|
+
const forkedFrom = resumeEvents[0].metadata?.forkedFrom;
|
|
1411
|
+
const parentCache = forkedFrom?.executionId !== void 0 && bridgeMeta?.logId === forkedFrom.executionId && forkedFrom.logIndex === resumeEvents.length;
|
|
1412
|
+
if (inheritedExecutionId === void 0 || bridgeMeta?.logId !== inheritedExecutionId && !parentCache) throw new AgentMachineVersionMismatchError(tail.id, tail.index, {
|
|
1359
1413
|
machineId,
|
|
1360
1414
|
machineVersion
|
|
1361
1415
|
}, {
|
|
@@ -1456,9 +1510,11 @@ function createAgentRuntime(machine, options = {}) {
|
|
|
1456
1510
|
const attempts = transitionOptions?.attempts ?? attemptsByEvent.get(event);
|
|
1457
1511
|
if (transitionOptions?.attempts !== void 0) assertJsonSerializable(transitionOptions.attempts, "attempts");
|
|
1458
1512
|
const [next, effects] = execution.transition(state, event);
|
|
1459
|
-
|
|
1513
|
+
const ignored = !fromMailbox.has(event) && next === state && effects.length === 0;
|
|
1514
|
+
if (ignored) ignoredEvent = event;
|
|
1460
1515
|
appendLogEntry(event, attempts);
|
|
1461
|
-
|
|
1516
|
+
if (stopReason !== void 0) return [state, []];
|
|
1517
|
+
commit(next, event, ignored);
|
|
1462
1518
|
return [next, effects];
|
|
1463
1519
|
},
|
|
1464
1520
|
async execute(effects) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { _ as StandardSchemaV1, m as InferInput, s as AgentTools, w as WithAgentInputSchema } from "./types-Dp5_Ru4R.mjs";
|
|
2
|
-
import { I as DecisionAttempt, N as AgentDecisionRequest, Q as AgentError, W as AgentEventDescriptor, d as AgentRequestMode, f as AgentTextRequest, m as AgentUsage, q as AgentRequestSource, r as AgentFinishReason, t as AgentCallUsage, u as AgentRequestExecutors } from "./text-logic-
|
|
3
|
-
import { n as AgentUsageEvent } from "./usage-
|
|
4
|
-
import { c as AgentLogEntry, h as JsonValue$1, n as AgentEventLogStore } from "./event-log-store-
|
|
2
|
+
import { I as DecisionAttempt, N as AgentDecisionRequest, Q as AgentError, W as AgentEventDescriptor, d as AgentRequestMode, f as AgentTextRequest, m as AgentUsage, q as AgentRequestSource, r as AgentFinishReason, t as AgentCallUsage, u as AgentRequestExecutors } from "./text-logic-DuK9HIFM.mjs";
|
|
3
|
+
import { n as AgentUsageEvent } from "./usage-D7JKAxLc.mjs";
|
|
4
|
+
import { c as AgentLogEntry, h as JsonValue$1, n as AgentEventLogStore } from "./event-log-store-C2NjVlWU.mjs";
|
|
5
5
|
import { AnyActorLogic, AnyActorRef, AnyMachineSnapshot, AnyStateMachine, AsyncActorLogic, EmittedFrom, EventFromLogic, EventObject, InputFrom, InspectionEvent, OutputFrom, Snapshot, SnapshotFrom, StateValue } from "xstate";
|
|
6
6
|
import { DurableExecution } from "xstate/durable";
|
|
7
7
|
//#region src/steps.d.ts
|
|
@@ -121,6 +121,13 @@ type AgentTraceEvent<TMachine extends AnyStateMachine = AnyStateMachine> = {
|
|
|
121
121
|
};
|
|
122
122
|
snapshot: SnapshotFrom<TMachine>;
|
|
123
123
|
event: EventFromLogic<TMachine>;
|
|
124
|
+
/**
|
|
125
|
+
* `true` when the host's own event (the run's opening `event`, or one
|
|
126
|
+
* sent with `runtime.transition`) had no transition in this state, so
|
|
127
|
+
* nothing changed: the same event {@link AgentRunResult.ignored}
|
|
128
|
+
* reports. Absent otherwise.
|
|
129
|
+
*/
|
|
130
|
+
ignored?: true;
|
|
124
131
|
} | {
|
|
125
132
|
type: "emit";
|
|
126
133
|
event: EmittedFrom<TMachine>;
|
|
@@ -246,9 +253,13 @@ interface AgentRuntimeOptions<TMachine extends AnyStateMachine> {
|
|
|
246
253
|
onEvent?: (entry: AgentLogEntry) => void;
|
|
247
254
|
/**
|
|
248
255
|
* Record a `verification.stateHash` on every appended entry (default `true`).
|
|
249
|
-
* The hash is
|
|
250
|
-
*
|
|
251
|
-
* the
|
|
256
|
+
* The hash is of the state the log folds to after that entry, the same fold
|
|
257
|
+
* `replay` runs, so `replay(machine, events)` can check each entry against
|
|
258
|
+
* the fold before it. It does not show the log is complete (a dropped last
|
|
259
|
+
* entry leaves the rest intact), nor compare against the live snapshot: a
|
|
260
|
+
* machine that reads something the log does not keep (an error's class, a
|
|
261
|
+
* non-JSON field) can replay to a different state. Set `false` for a
|
|
262
|
+
* smaller, unverifiable log.
|
|
252
263
|
*/
|
|
253
264
|
verification?: boolean;
|
|
254
265
|
/**
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { _ as StandardSchemaV1, m as InferInput, s as AgentTools, w as WithAgentInputSchema } from "./types-Dp5_Ru4R.cjs";
|
|
2
|
-
import { I as DecisionAttempt, N as AgentDecisionRequest, Q as AgentError, W as AgentEventDescriptor, d as AgentRequestMode, f as AgentTextRequest, m as AgentUsage, q as AgentRequestSource, r as AgentFinishReason, t as AgentCallUsage, u as AgentRequestExecutors } from "./text-logic-
|
|
3
|
-
import { n as AgentUsageEvent } from "./usage-
|
|
4
|
-
import { c as AgentLogEntry, h as JsonValue$1, n as AgentEventLogStore } from "./event-log-store-
|
|
2
|
+
import { I as DecisionAttempt, N as AgentDecisionRequest, Q as AgentError, W as AgentEventDescriptor, d as AgentRequestMode, f as AgentTextRequest, m as AgentUsage, q as AgentRequestSource, r as AgentFinishReason, t as AgentCallUsage, u as AgentRequestExecutors } from "./text-logic-CYP502VT.cjs";
|
|
3
|
+
import { n as AgentUsageEvent } from "./usage-DVw-646x.cjs";
|
|
4
|
+
import { c as AgentLogEntry, h as JsonValue$1, n as AgentEventLogStore } from "./event-log-store-s73r1Hxf.cjs";
|
|
5
5
|
import { AnyActorLogic, AnyActorRef, AnyMachineSnapshot, AnyStateMachine, AsyncActorLogic, EmittedFrom, EventFromLogic, EventObject, InputFrom, InspectionEvent, OutputFrom, Snapshot, SnapshotFrom, StateValue } from "xstate";
|
|
6
6
|
import { DurableExecution } from "xstate/durable";
|
|
7
7
|
//#region src/steps.d.ts
|
|
@@ -121,6 +121,13 @@ type AgentTraceEvent<TMachine extends AnyStateMachine = AnyStateMachine> = {
|
|
|
121
121
|
};
|
|
122
122
|
snapshot: SnapshotFrom<TMachine>;
|
|
123
123
|
event: EventFromLogic<TMachine>;
|
|
124
|
+
/**
|
|
125
|
+
* `true` when the host's own event (the run's opening `event`, or one
|
|
126
|
+
* sent with `runtime.transition`) had no transition in this state, so
|
|
127
|
+
* nothing changed: the same event {@link AgentRunResult.ignored}
|
|
128
|
+
* reports. Absent otherwise.
|
|
129
|
+
*/
|
|
130
|
+
ignored?: true;
|
|
124
131
|
} | {
|
|
125
132
|
type: "emit";
|
|
126
133
|
event: EmittedFrom<TMachine>;
|
|
@@ -246,9 +253,13 @@ interface AgentRuntimeOptions<TMachine extends AnyStateMachine> {
|
|
|
246
253
|
onEvent?: (entry: AgentLogEntry) => void;
|
|
247
254
|
/**
|
|
248
255
|
* Record a `verification.stateHash` on every appended entry (default `true`).
|
|
249
|
-
* The hash is
|
|
250
|
-
*
|
|
251
|
-
* the
|
|
256
|
+
* The hash is of the state the log folds to after that entry, the same fold
|
|
257
|
+
* `replay` runs, so `replay(machine, events)` can check each entry against
|
|
258
|
+
* the fold before it. It does not show the log is complete (a dropped last
|
|
259
|
+
* entry leaves the rest intact), nor compare against the live snapshot: a
|
|
260
|
+
* machine that reads something the log does not keep (an error's class, a
|
|
261
|
+
* non-JSON field) can replay to a different state. Set `false` for a
|
|
262
|
+
* smaller, unverifiable log.
|
|
252
263
|
*/
|
|
253
264
|
verification?: boolean;
|
|
254
265
|
/**
|