@statelyai/agent 2.0.0-alpha.10 → 2.0.0-alpha.11

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.
Files changed (45) hide show
  1. package/dist/adapter.cjs +15 -0
  2. package/dist/adapter.d.cts +4 -0
  3. package/dist/adapter.d.mts +4 -0
  4. package/dist/adapter.mjs +2 -0
  5. package/dist/ai-sdk.cjs +66 -102
  6. package/dist/ai-sdk.d.cts +5 -115
  7. package/dist/ai-sdk.d.mts +5 -115
  8. package/dist/ai-sdk.mjs +64 -91
  9. package/dist/decision-C3k4ve51.mjs +227 -0
  10. package/dist/decision-D8wJrM8W.cjs +286 -0
  11. package/dist/{decision-b-lkcs4L.cjs → events-CRQj3VtP.cjs} +10 -295
  12. package/dist/{decision-CQdrKc8k.mjs → events-JiVPYrct.mjs} +10 -229
  13. package/dist/index.cjs +2521 -52
  14. package/dist/index.d.cts +1029 -9
  15. package/dist/index.d.mts +1029 -9
  16. package/dist/index.mjs +2493 -4
  17. package/dist/openai-compat.cjs +23 -33
  18. package/dist/openai-compat.d.cts +3 -42
  19. package/dist/openai-compat.d.mts +3 -42
  20. package/dist/openai-compat.mjs +20 -24
  21. package/dist/steps-BALp1eZo.d.mts +198 -0
  22. package/dist/steps-CVe54GPP.cjs +420 -0
  23. package/dist/steps-CkyyyuHd.mjs +379 -0
  24. package/dist/steps-MjnQI4aB.d.cts +198 -0
  25. package/dist/steps.cjs +12 -0
  26. package/dist/steps.d.cts +3 -0
  27. package/dist/steps.d.mts +3 -0
  28. package/dist/steps.mjs +3 -0
  29. package/dist/{text-logic-C7WJpCIc.d.mts → text-logic-CaKqgX4Y.d.mts} +8 -8
  30. package/dist/{text-logic-CZjyACzQ.d.cts → text-logic-Ckhr2kKC.d.cts} +8 -8
  31. package/package.json +27 -4
  32. package/readme.md +18 -8
  33. package/schemas/agent-workflow.json +4 -5
  34. package/dist/cli.cjs +0 -64
  35. package/dist/cli.d.cts +0 -1
  36. package/dist/cli.d.mts +0 -1
  37. package/dist/cli.mjs +0 -65
  38. package/dist/run-agent-BFMkuI1F.cjs +0 -1599
  39. package/dist/run-agent-BVMd--1l.d.cts +0 -1103
  40. package/dist/run-agent-BoAOq_0Z.mjs +0 -1540
  41. package/dist/run-agent-DzYJb3CK.d.mts +0 -1103
  42. package/dist/src-D-77Ha5p.cjs +0 -1087
  43. package/dist/src-DUeIFjv-.mjs +0 -1016
  44. /package/dist/{utils-Dri7aeEG.d.cts → utils-BYqT_Dyv.d.cts} +0 -0
  45. /package/dist/{utils-Y6GDRGGE.d.mts → utils-Do5wIJrh.d.mts} +0 -0
@@ -1,4 +1,4 @@
1
- import { createAsyncLogic, createLogic, getNextTransitions } from "xstate";
1
+ import { createAsyncLogic, getNextTransitions } from "xstate";
2
2
  //#region src/utils.ts
3
3
  /**
4
4
  * Deep-clones a snapshot to a plain-JSON value via a `JSON` round-trip, the
@@ -221,9 +221,6 @@ function validateSchemaSync(schema, value) {
221
221
  //#endregion
222
222
  //#region src/internal/registry.ts
223
223
  const agentExecutionOptions = /* @__PURE__ */ new WeakMap();
224
- function getRegisteredAgentModels(machine) {
225
- return agentExecutionOptions.get(machine)?.models;
226
- }
227
224
  /**
228
225
  * Machine-carried wait-state predicates, keyed on the machine's root `config`
229
226
  * object. `config` is shared by reference across `machine.provide(...)` (unlike
@@ -294,7 +291,13 @@ const agentTextInputSchema = { "~standard": {
294
291
  version: 1,
295
292
  vendor: "statelyai-agent",
296
293
  validate(value) {
297
- return !!value && typeof value === "object" && typeof value.model === "string" ? { value } : { issues: [{ message: "Expected agent text input with a model" }] };
294
+ if (!value || typeof value !== "object") return { issues: [{ message: "Expected agent text input object" }] };
295
+ const request = value;
296
+ if (typeof request.model !== "string") return { issues: [{ message: "Expected agent text input with a string `model`" }] };
297
+ const hasPrompt = typeof request.prompt === "string" && request.prompt.length > 0;
298
+ const hasMessages = Array.isArray(request.messages) && request.messages.length > 0;
299
+ if (!hasPrompt && !hasMessages) return { issues: [{ message: `Agent text request${request.name ? ` '${request.name}'` : ""} has neither a non-empty \`prompt\` nor \`messages\` — provide at least one so the model has something to respond to.` }] };
300
+ return { value: request };
298
301
  }
299
302
  } };
300
303
  const unknownOutputSchema = { "~standard": {
@@ -654,7 +657,7 @@ function invalidGeneratorResult(id) {
654
657
  }
655
658
  //#endregion
656
659
  //#region src/events.ts
657
- /** Default prefix for the synthetic tool name generated per candidate event (e.g. `send_event_ASK`). Override per-request with {@link AgentEventToolNameResolver}. */
660
+ /** Default prefix for the synthetic tool name generated per candidate event (e.g. `send_event_ASK`). Override per-request with {@link AgentEventToolNameResolver}. @internal */
658
661
  const EVENT_TOOL_PREFIX = "send_event_";
659
662
  function hashString(value) {
660
663
  let hash = 5381;
@@ -753,226 +756,4 @@ function getAcceptedEvents(snapshot, options = {}) {
753
756
  });
754
757
  }
755
758
  //#endregion
756
- //#region src/decision.ts
757
- function decideRequestFromInput(input) {
758
- const allowedEventTypes = resolveAllowedEventTypes(input.allowedEvents, input) ?? [];
759
- return {
760
- kind: "decision",
761
- id: "",
762
- model: input.model,
763
- system: input.system,
764
- prompt: input.prompt,
765
- messages: input.messages,
766
- events: allowedEventTypes.filter((type) => !isEventPattern(type)).map((type) => ({
767
- type,
768
- toolName: sanitizeEventToolName(type)
769
- })),
770
- attempts: [],
771
- temperature: input.temperature,
772
- maxOutputTokens: input.maxOutputTokens,
773
- topP: input.topP,
774
- topK: input.topK,
775
- seed: input.seed,
776
- stopSequences: input.stopSequences,
777
- metadata: input.metadata
778
- };
779
- }
780
- function decideActorWithExecutor(execute) {
781
- const logic = createAsyncLogic({ run: async ({ input, signal }) => {
782
- if (!execute) throw new Error(`'${DECIDE_ACTOR}' has no host execution. Provide an implementation with machine.provide({ actorSources: { '${DECIDE_ACTOR}': ... } }) or resolve the returned agent request with resolveDecision(...).`);
783
- const resolvedEventTypes = resolveAllowedEventTypes(input.allowedEvents, input);
784
- if (resolvedEventTypes === void 0) throw new Error(`'${DECIDE_ACTOR}' input has omitted \`allowedEvents\`, which means "all currently-legal events" — but that requires a snapshot-aware host (runAgent or the step path) to resolve. Under a bare createActor(...), declare \`allowedEvents\` explicitly to use this actor here.`);
785
- if (resolvedEventTypes.some(isEventPattern)) throw new Error(`'${DECIDE_ACTOR}' input uses wildcard \`allowedEvents\` patterns, which expand against the live snapshot — that requires a snapshot-aware host (runAgent or the step path). Under a bare createActor(...), list event types explicitly.`);
786
- return resolveDecision(decideRequestFromInput(input), execute, {
787
- maxRetries: input.maxRetries ?? 2,
788
- signal
789
- });
790
- } });
791
- return Object.assign(logic, {
792
- kind: "statelyai.decisionLogic",
793
- maxRetries: 2,
794
- request: decideRequestFromInput,
795
- allowedEventTypes: (input) => resolveAllowedEventTypes(input.allowedEvents, input),
796
- withExecutor: (nextExecute) => decideActorWithExecutor(nextExecute)
797
- });
798
- }
799
- function createDecideActor() {
800
- return decideActorWithExecutor();
801
- }
802
- /**
803
- * Reserved event type the `agent.plan` builtin adds to every step's
804
- * candidates as the explicit "no further action needed" move. Choosing it
805
- * ends the plan (`stopped: 'done'`); it is never sent to the machine, so
806
- * machines need no no-op sentinel event of their own.
807
- */
808
- const PLAN_DONE_EVENT_TYPE = "agent.plan.done";
809
- function createPlanActor() {
810
- const logic = createLogic({
811
- context: ({ input }) => ({
812
- applied: [],
813
- stepsRemaining: input.maxSteps ?? 8,
814
- stopped: null
815
- }),
816
- run: ({ context, event }) => event.type === "plan.applied" ? { context: {
817
- ...context,
818
- applied: [...context.applied, event.event],
819
- stepsRemaining: context.stepsRemaining - 1
820
- } } : event.type === "plan.ended" ? {
821
- context: {
822
- ...context,
823
- stopped: event.stopped
824
- },
825
- status: "done",
826
- output: {
827
- steps: context.applied,
828
- stopped: event.stopped
829
- }
830
- } : void 0
831
- });
832
- return Object.assign(logic, {
833
- kind: "statelyai.planLogic",
834
- maxRetries: 2,
835
- request: decideRequestFromInput,
836
- allowedEventTypes: (input) => resolveAllowedEventTypes(input.allowedEvents, input)
837
- });
838
- }
839
- const PLAN_LEDGER_SCOPE = { emit: () => {} };
840
- /**
841
- * Builds a fresh plan ledger snapshot from resolved plan input — the shared
842
- * starting point for BOTH hosts (the step path reads the invoke child's own
843
- * initial snapshot; runAgent seeds a local ledger with this). @internal
844
- */
845
- function initialPlanLedger(logic, input) {
846
- return logic.getInitialSnapshot(PLAN_LEDGER_SCOPE, input);
847
- }
848
- /**
849
- * Advances a plan ledger by one {@link PlanLedgerEvent}, returning the next
850
- * snapshot (unwrapping `createLogic`'s `[snapshot, effects]` tuple). Pure — no
851
- * mutation of the input snapshot. @internal
852
- */
853
- function advancePlanLedger(logic, snapshot, event) {
854
- const result = logic.transition(snapshot, event, PLAN_LEDGER_SCOPE);
855
- return Array.isArray(result) ? result[0] : result;
856
- }
857
- /** Type guard: true for the `agent.plan` builtin logic (checks the `kind` marker). @internal */
858
- function isPlanLogic(logic) {
859
- return !!logic && logic.kind === "statelyai.planLogic";
860
- }
861
- function resolveAllowedEventTypes(allowedEvents, input) {
862
- if (allowedEvents === void 0) return;
863
- const resolved = typeof allowedEvents === "function" ? allowedEvents({ input }) : allowedEvents;
864
- return typeof resolved === "string" ? [resolved] : resolved;
865
- }
866
- /** Type guard: true for any actor logic built by createDecisionLogic/createDecideActor (checks the `kind` marker). @internal */
867
- function isDecisionLogic(value) {
868
- return !!value && typeof value === "object" && value.kind === "statelyai.decisionLogic" && typeof value.request === "function";
869
- }
870
- /**
871
- * Thrown by {@link resolveDecision} when every attempt (up to
872
- * `maxRetries + 1` of them) fails one of the three checks recorded in
873
- * {@link DecisionAttempt.failure}. Carries the full `attempts` list for
874
- * diagnostics; a machine typically routes this via the decision invoke's
875
- * `onError`.
876
- */
877
- var DecisionExhaustedError = class extends Error {
878
- attempts;
879
- constructor(attempts) {
880
- super(`Decision exhausted after ${attempts.length} attempt${attempts.length === 1 ? "" : "s"}: ` + attempts.map((attempt) => attempt.reason).join("; "));
881
- this.name = "DecisionExhaustedError";
882
- this.attempts = attempts;
883
- }
884
- };
885
- /**
886
- * Renders a decision request's prior failed `attempts` into feedback messages
887
- * a host appends to the model call so retries converge — the transport-agnostic
888
- * "your last choice failed because X, choose again from Y" logic every adapter
889
- * and raw-SDK host repeats. Returns one `user`-role {@link AgentMessage} per
890
- * attempt (empty when there are none); adapters map each onto their wire
891
- * message shape (`attempt.content` is always a string). Core never rewrites the
892
- * request itself — this only turns the recorded attempts into messages.
893
- *
894
- * @example
895
- * ```ts
896
- * const messages = [...baseMessages, ...renderDecisionAttempts(request)];
897
- * ```
898
- */
899
- function renderDecisionAttempts(request) {
900
- const types = request.events.map((event) => event.type).join(", ") || "(none)";
901
- return request.attempts.map((attempt) => userMessage(`Your previous choice failed: ${attempt.reason}. Choose again from: ${types}`));
902
- }
903
- /**
904
- * Validation + retry core for decisions. No provider mechanics — the
905
- * `executor` is responsible for making the model choose an event; this
906
- * function only validates the choice and retries on failure, up to
907
- * `options.maxRetries` (default 2, i.e. up to 3 attempts total).
908
- *
909
- * Each attempt is checked in order and can fail one of three ways (recorded
910
- * as a {@link DecisionAttempt}): `'unknown-event'` (the chosen `type` is not
911
- * among `request.events`), `'invalid-payload'` (the payload fails that
912
- * event's schema), or `'rejected-by-guard'` (passes both checks but
913
- * `options.canTake` returns `false` — a type/payload-legal event the
914
- * machine's guard rejects right now; omit `canTake` to skip this check).
915
- * Every prior failed attempt for this call is fed back to the executor on
916
- * the next attempt via `request.attempts`, so an adapter can render "your
917
- * last choice failed because X — try again" into the next model call; core
918
- * never rewrites the request itself. Exhausting all attempts throws
919
- * {@link DecisionExhaustedError} with the full attempts list.
920
- *
921
- * @example
922
- * ```ts
923
- * const event = await resolveDecision(request, decide, {
924
- * canTake: (e) => snapshot.can(e),
925
- * });
926
- * ```
927
- */
928
- async function resolveDecision(request, executor, options = {}) {
929
- const maxRetries = options.maxRetries ?? 2;
930
- const attempts = [];
931
- const eventsByType = new Map(request.events.map((event) => [event.type, event]));
932
- for (let attempt = 0; attempt <= maxRetries; attempt++) {
933
- options.signal?.throwIfAborted();
934
- const { event } = await executor({
935
- ...request,
936
- attempts: [...attempts],
937
- signal: options.signal
938
- });
939
- const descriptor = eventsByType.get(event.type);
940
- if (!descriptor) {
941
- attempts.push({
942
- event,
943
- failure: "unknown-event",
944
- reason: `'${event.type}' is not among the currently allowed events: ${request.events.map((candidate) => candidate.type).join(", ") || "(none)"}.`
945
- });
946
- continue;
947
- }
948
- let validatedEvent = event;
949
- if (descriptor.inputSchema) {
950
- const { type, ...payload } = event;
951
- try {
952
- validatedEvent = {
953
- ...validateSchemaSync(descriptor.inputSchema, payload),
954
- type
955
- };
956
- } catch (error) {
957
- attempts.push({
958
- event,
959
- failure: "invalid-payload",
960
- reason: `'${event.type}' payload failed validation: ${error instanceof Error ? error.message : String(error)}`
961
- });
962
- continue;
963
- }
964
- }
965
- if (options.canTake?.(validatedEvent) === false) {
966
- attempts.push({
967
- event: validatedEvent,
968
- failure: "rejected-by-guard",
969
- reason: `'${validatedEvent.type}' is not currently takeable (guard rejected it).`
970
- });
971
- continue;
972
- }
973
- return validatedEvent;
974
- }
975
- throw new DecisionExhaustedError(attempts);
976
- }
977
- //#endregion
978
- export { validateSchemaSync as $, parseOutput as A, missingActor as B, createTextLogic as C, isTextLogic as D, isStructuredOutputSchema as E, getMachineSuspensionPredicate as F, getJsonSchemaSync as G, findNonSerializableContextPaths as H, getRegisteredAgentExecutionOptions as I, isStandardSchema as J, getMachineStructuralHash as K, getRegisteredAgentModels as L, userInputActor as M, agentExecutionOptions as N, normalizeGeneratorResult as O, executorBoundLogics as P, userMessage as Q, isUnboundPlaceholder as R, builtinTextActors as S, getAgentOutputMode as T, getAgentMessages as U, assistantMessage as V, getJsonSchema as W, systemMessage as X, persistSnapshot as Y, toolMessage as Z, INTERPRET_SOURCE as _, createPlanActor as a, bindRequestExecutor as b, isPlanLogic as c, EVENT_TOOL_PREFIX as d, getAcceptedEvents as f, DECIDE_ACTOR as g, sanitizeEventToolName as h, createDecideActor as i, parseStructuredEnvelope as j, parseModelRef as k, renderDecisionAttempts as l, parseAgentEvent as m, PLAN_DONE_EVENT_TYPE as n, initialPlanLedger as o, matchesEventPattern as p, getStateMeta as q, advancePlanLedger as r, isDecisionLogic as s, DecisionExhaustedError as t, resolveDecision as u, PLAN_ACTOR as v, executeAgentTextRequest as w, buildEnvelopeSchema as x, USER_INPUT_ACTOR as y, machineSuspensionPredicates as z };
759
+ export { assistantMessage as A, toolMessage as B, agentExecutionOptions as C, isUnboundPlaceholder as D, getRegisteredAgentExecutionOptions as E, getMachineStructuralHash as F, validateSchemaSync as H, getStateMeta as I, isStandardSchema as L, getAgentMessages as M, getJsonSchema as N, machineSuspensionPredicates as O, getJsonSchemaSync as P, persistSnapshot as R, userInputActor as S, getMachineSuspensionPredicate as T, userMessage as V, isTextLogic as _, sanitizeEventToolName as a, parseOutput as b, PLAN_ACTOR as c, buildEnvelopeSchema as d, builtinTextActors as f, isStructuredOutputSchema as g, getAgentOutputMode as h, parseAgentEvent as i, findNonSerializableContextPaths as j, missingActor as k, USER_INPUT_ACTOR as l, executeAgentTextRequest as m, isEventPattern as n, DECIDE_ACTOR as o, createTextLogic as p, matchesEventPattern as r, INTERPRET_SOURCE as s, getAcceptedEvents as t, bindRequestExecutor as u, normalizeGeneratorResult as v, executorBoundLogics as w, parseStructuredEnvelope as x, parseModelRef as y, systemMessage as z };