@statelyai/agent 2.0.0-alpha.20 → 2.0.0-alpha.22
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/ai-sdk.cjs +89 -25
- package/dist/ai-sdk.d.cts +56 -12
- package/dist/ai-sdk.d.mts +56 -12
- package/dist/ai-sdk.mjs +89 -26
- package/dist/{decision-DhsKLYAI.cjs → decision-1o45_ZrS.cjs} +120 -9
- package/dist/{decision-BfhSgCc6.mjs → decision-DxSTqzgZ.mjs} +103 -10
- package/dist/index.cjs +203 -41
- package/dist/index.d.cts +141 -20
- package/dist/index.d.mts +141 -20
- package/dist/index.mjs +202 -42
- package/dist/machines.cjs +1 -1
- package/dist/machines.d.cts +151 -54
- package/dist/machines.d.mts +151 -54
- package/dist/machines.mjs +1 -1
- package/dist/otel.d.cts +1 -1
- package/dist/otel.d.mts +1 -1
- package/dist/{run-agent-CwmzAZwj.d.mts → run-agent-0fpEZ1wJ.d.mts} +3 -3
- package/dist/{run-agent--4bbms-D.d.cts → run-agent-Zbkx7XP8.d.cts} +3 -3
- package/dist/{setup-agent-gISRLxRe.cjs → setup-agent-DkCTy5Eu.cjs} +76 -23
- package/dist/{setup-agent-BOcSpsIq.mjs → setup-agent-nSFYrNTP.mjs} +77 -18
- package/dist/sqlite.d.cts +1 -1
- package/dist/sqlite.d.mts +1 -1
- package/dist/{text-logic-Cavva1W6.d.cts → text-logic-BaxPrcLk.d.cts} +52 -6
- package/dist/{text-logic-Er5KkTX6.d.mts → text-logic-DhfFWzu9.d.mts} +52 -6
- package/dist/{types-DYpK3QF4.d.mts → types-CvWRGFxP.d.mts} +6 -1
- package/dist/{types-pJ5Hn8fv.d.cts → types-DSdj2tGs.d.cts} +6 -1
- package/dist/validate.cjs +2 -2
- package/dist/validate.mjs +1 -1
- package/package.json +28 -28
- package/readme.md +4 -4
- package/schemas/agent-workflow.json +1 -1
|
@@ -363,6 +363,13 @@ function getCallUsage(raw) {
|
|
|
363
363
|
}
|
|
364
364
|
return out;
|
|
365
365
|
}
|
|
366
|
+
function textRequestSourceIssue(request) {
|
|
367
|
+
const hasPrompt = typeof request.prompt === "string" && request.prompt.length > 0;
|
|
368
|
+
const hasMessages = Array.isArray(request.messages) && request.messages.length > 0;
|
|
369
|
+
const label = request.name ? ` '${request.name}'` : "";
|
|
370
|
+
if (hasPrompt && hasMessages) return `Agent text request${label} has both a non-empty \`prompt\` and \`messages\` — provide exactly one so the model has a single input source.`;
|
|
371
|
+
if (!hasPrompt && !hasMessages) return `Agent text request${label} has neither a non-empty \`prompt\` nor \`messages\` — provide at least one so the model has something to respond to.`;
|
|
372
|
+
}
|
|
366
373
|
const agentTextInputSchema = { "~standard": {
|
|
367
374
|
version: 1,
|
|
368
375
|
vendor: "statelyai-agent",
|
|
@@ -370,9 +377,8 @@ const agentTextInputSchema = { "~standard": {
|
|
|
370
377
|
if (!value || typeof value !== "object") return { issues: [{ message: "Expected agent text input object" }] };
|
|
371
378
|
const request = value;
|
|
372
379
|
if (typeof request.model !== "string") return { issues: [{ message: "Expected agent text input with a string `model`" }] };
|
|
373
|
-
const
|
|
374
|
-
|
|
375
|
-
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.` }] };
|
|
380
|
+
const issue = textRequestSourceIssue(request);
|
|
381
|
+
if (issue) return { issues: [{ message: issue }] };
|
|
376
382
|
return { value: request };
|
|
377
383
|
}
|
|
378
384
|
} };
|
|
@@ -424,7 +430,7 @@ function createBuiltinTextActor(src, mode, outputSchema) {
|
|
|
424
430
|
messages: ({ input }) => input.messages,
|
|
425
431
|
tools: ({ input }) => input.tools,
|
|
426
432
|
toolChoice: ({ input }) => input.toolChoice,
|
|
427
|
-
|
|
433
|
+
includeReasoning: ({ input }) => input.includeReasoning,
|
|
428
434
|
temperature: ({ input }) => input.temperature,
|
|
429
435
|
maxOutputTokens: ({ input }) => input.maxOutputTokens,
|
|
430
436
|
topP: ({ input }) => input.topP,
|
|
@@ -487,16 +493,25 @@ function createTextLogic(config, execute) {
|
|
|
487
493
|
};
|
|
488
494
|
const request = (input) => {
|
|
489
495
|
const args = { input: validateSchemaSync(schemas.input, input) };
|
|
496
|
+
const name = resolveTextLogicValue(config.name, args);
|
|
497
|
+
const prompt = resolveTextLogicValue(config.prompt, args);
|
|
498
|
+
const messages = resolveTextLogicValue(config.messages, args);
|
|
499
|
+
const sourceIssue = textRequestSourceIssue({
|
|
500
|
+
name,
|
|
501
|
+
prompt,
|
|
502
|
+
messages
|
|
503
|
+
});
|
|
504
|
+
if (sourceIssue) throw new Error(sourceIssue);
|
|
490
505
|
return {
|
|
491
|
-
name
|
|
506
|
+
name,
|
|
492
507
|
model: resolveTextLogicValue(config.model, args),
|
|
493
508
|
system: resolveTextLogicValue(config.system, args),
|
|
494
|
-
prompt
|
|
495
|
-
messages
|
|
509
|
+
prompt,
|
|
510
|
+
messages,
|
|
496
511
|
tools: resolveTextLogicValue(config.tools, args),
|
|
497
512
|
toolChoice: resolveTextLogicValue(config.toolChoice, args),
|
|
498
513
|
outputSchema: schemas.output,
|
|
499
|
-
|
|
514
|
+
includeReasoning: resolveTextLogicValue(config.includeReasoning, args),
|
|
500
515
|
temperature: resolveTextLogicValue(config.temperature, args),
|
|
501
516
|
maxOutputTokens: resolveTextLogicValue(config.maxOutputTokens, args),
|
|
502
517
|
topP: resolveTextLogicValue(config.topP, args),
|
|
@@ -643,7 +658,7 @@ function buildEnvelopeSchema(inner, options = {}) {
|
|
|
643
658
|
*/
|
|
644
659
|
function parseStructuredEnvelope(request, value) {
|
|
645
660
|
if (!request.outputSchema) throw new Error("parseStructuredEnvelope: the request declares no outputSchema.");
|
|
646
|
-
return validateSchemaSync(buildEnvelopeSchema(request.outputSchema, { reasoning: request.
|
|
661
|
+
return validateSchemaSync(buildEnvelopeSchema(request.outputSchema, { reasoning: request.includeReasoning }), value);
|
|
647
662
|
}
|
|
648
663
|
/**
|
|
649
664
|
* Merges request-declared and call-site `tools`, dispatches to the
|
|
@@ -663,6 +678,8 @@ async function executeAgentTextRequest(mode, id, input, executors, tools = {}, i
|
|
|
663
678
|
...tools
|
|
664
679
|
}
|
|
665
680
|
};
|
|
681
|
+
const sourceIssue = textRequestSourceIssue(request);
|
|
682
|
+
if (sourceIssue) throw new Error(sourceIssue);
|
|
666
683
|
const executor = mode === "stream" ? executors.streamText : executors.generateText;
|
|
667
684
|
if (!executor) throw new Error(`No executor provided for ${mode === "stream" ? "stream" : "generate"} request '${id}'.`);
|
|
668
685
|
const raw = await executor(request, info);
|
|
@@ -911,6 +928,82 @@ function resolveAllowedEventTypes(allowedEvents, input) {
|
|
|
911
928
|
const resolved = typeof allowedEvents === "function" ? allowedEvents({ input }) : allowedEvents;
|
|
912
929
|
return typeof resolved === "string" ? [resolved] : resolved;
|
|
913
930
|
}
|
|
931
|
+
/**
|
|
932
|
+
* Creates reusable, standalone {@link DecisionLogic}: an actor that, when
|
|
933
|
+
* run, resolves to exactly one currently-legal {@link ChosenEvent} by
|
|
934
|
+
* calling the host `decide` executor (passed here as `execute`, or supplied
|
|
935
|
+
* later via {@link DecisionLogic.withExecutor}, `machine.provide(...)`, or
|
|
936
|
+
* `runAgent`'s `decide` option). Register the result under `actors:` and
|
|
937
|
+
* invoke it by name; for a one-off, state-local decision, prefer the
|
|
938
|
+
* `agent.decide` builtin invoke instead — it needs no separate declaration
|
|
939
|
+
* and types `allowedEvents` against the machine's own event schemas.
|
|
940
|
+
*
|
|
941
|
+
* @example
|
|
942
|
+
* ```ts
|
|
943
|
+
* import { createDecisionLogic } from '@statelyai/agent';
|
|
944
|
+
* import { z } from 'zod';
|
|
945
|
+
*
|
|
946
|
+
* export const chooseMove = createDecisionLogic({
|
|
947
|
+
* schemas: { input: z.object({ playerHp: z.number(), enemyHp: z.number() }) },
|
|
948
|
+
* model: 'openai/gpt-5.4-mini',
|
|
949
|
+
* system: 'You are playing a turn-based game. Choose exactly one legal move.',
|
|
950
|
+
* prompt: ({ input }) => `Player HP: ${input.playerHp}\nEnemy HP: ${input.enemyHp}`,
|
|
951
|
+
* allowedEvents: ({ input }) =>
|
|
952
|
+
* input.playerHp <= 6
|
|
953
|
+
* ? ['ATTACK', 'DEFEND', 'HEAL', 'FLEE']
|
|
954
|
+
* : ['ATTACK', 'DEFEND', 'FLEE'],
|
|
955
|
+
* });
|
|
956
|
+
* ```
|
|
957
|
+
*/
|
|
958
|
+
function createDecisionLogic(config, execute) {
|
|
959
|
+
const maxRetries = config.maxRetries ?? 2;
|
|
960
|
+
const request = (input) => {
|
|
961
|
+
const parsedInput = config.schemas ? validateSchemaSync(config.schemas.input, input) : input;
|
|
962
|
+
const args = { input: parsedInput };
|
|
963
|
+
const allowedEventTypes = resolveAllowedEventTypes(config.allowedEvents, parsedInput);
|
|
964
|
+
return {
|
|
965
|
+
kind: "decision",
|
|
966
|
+
id: "",
|
|
967
|
+
model: resolveTextLogicValue(config.model, args),
|
|
968
|
+
system: resolveTextLogicValue(config.system, args),
|
|
969
|
+
prompt: resolveTextLogicValue(config.prompt, args),
|
|
970
|
+
messages: resolveTextLogicValue(config.messages, args),
|
|
971
|
+
events: (allowedEventTypes ?? []).map((type) => ({
|
|
972
|
+
type,
|
|
973
|
+
toolName: sanitizeEventToolName(type)
|
|
974
|
+
})),
|
|
975
|
+
attempts: [],
|
|
976
|
+
temperature: resolveTextLogicValue(config.temperature, args),
|
|
977
|
+
maxOutputTokens: resolveTextLogicValue(config.maxOutputTokens, args),
|
|
978
|
+
topP: resolveTextLogicValue(config.topP, args),
|
|
979
|
+
topK: resolveTextLogicValue(config.topK, args),
|
|
980
|
+
seed: resolveTextLogicValue(config.seed, args),
|
|
981
|
+
stopSequences: resolveTextLogicValue(config.stopSequences, args),
|
|
982
|
+
metadata: resolveTextLogicValue(config.metadata, args)
|
|
983
|
+
};
|
|
984
|
+
};
|
|
985
|
+
const logic = (0, xstate.createAsyncLogic)({ run: async ({ input, signal }) => {
|
|
986
|
+
if (!execute) throw new Error("Decision logic has no host execution. Pass an executor as the second argument to createDecisionLogic(...), provide a runtime adapter, or extract it with getAgentEffects(..., { actors }) and resolveDecision(...).");
|
|
987
|
+
const allowedEventTypes = resolveAllowedEventTypes(config.allowedEvents, input);
|
|
988
|
+
if (allowedEventTypes === void 0) throw new Error("Decision logic 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 on this logic to use it here.");
|
|
989
|
+
if (allowedEventTypes.some(isEventPattern)) throw new Error("Decision logic 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.");
|
|
990
|
+
return resolveDecision(request(input), { decide: execute }, {
|
|
991
|
+
maxRetries,
|
|
992
|
+
signal
|
|
993
|
+
});
|
|
994
|
+
} });
|
|
995
|
+
const decisionLogic = Object.assign(logic, {
|
|
996
|
+
kind: "statelyai.decisionLogic",
|
|
997
|
+
maxRetries,
|
|
998
|
+
request,
|
|
999
|
+
allowedEventTypes: (input) => resolveAllowedEventTypes(config.allowedEvents, input),
|
|
1000
|
+
withExecutor(nextExecute) {
|
|
1001
|
+
return createDecisionLogic(config, nextExecute);
|
|
1002
|
+
}
|
|
1003
|
+
});
|
|
1004
|
+
if (execute) executorBoundLogics.add(decisionLogic);
|
|
1005
|
+
return decisionLogic;
|
|
1006
|
+
}
|
|
914
1007
|
/** Type guard: true for any actor logic built by createDecisionLogic/createDecideActor (checks the `kind` marker). @internal */
|
|
915
1008
|
function isDecisionLogic(value) {
|
|
916
1009
|
return !!value && typeof value === "object" && value.kind === "statelyai.decisionLogic" && typeof value.request === "function";
|
|
@@ -1048,12 +1141,24 @@ Object.defineProperty(exports, "DECIDE_ACTOR", {
|
|
|
1048
1141
|
return DECIDE_ACTOR;
|
|
1049
1142
|
}
|
|
1050
1143
|
});
|
|
1144
|
+
Object.defineProperty(exports, "GENERATE_TEXT_ACTOR", {
|
|
1145
|
+
enumerable: true,
|
|
1146
|
+
get: function() {
|
|
1147
|
+
return GENERATE_TEXT_ACTOR;
|
|
1148
|
+
}
|
|
1149
|
+
});
|
|
1051
1150
|
Object.defineProperty(exports, "INTERPRET_SOURCE", {
|
|
1052
1151
|
enumerable: true,
|
|
1053
1152
|
get: function() {
|
|
1054
1153
|
return INTERPRET_SOURCE;
|
|
1055
1154
|
}
|
|
1056
1155
|
});
|
|
1156
|
+
Object.defineProperty(exports, "STREAM_TEXT_ACTOR", {
|
|
1157
|
+
enumerable: true,
|
|
1158
|
+
get: function() {
|
|
1159
|
+
return STREAM_TEXT_ACTOR;
|
|
1160
|
+
}
|
|
1161
|
+
});
|
|
1057
1162
|
Object.defineProperty(exports, "USER_INPUT_ACTOR", {
|
|
1058
1163
|
enumerable: true,
|
|
1059
1164
|
get: function() {
|
|
@@ -1096,6 +1201,12 @@ Object.defineProperty(exports, "createDecideActor", {
|
|
|
1096
1201
|
return createDecideActor;
|
|
1097
1202
|
}
|
|
1098
1203
|
});
|
|
1204
|
+
Object.defineProperty(exports, "createDecisionLogic", {
|
|
1205
|
+
enumerable: true,
|
|
1206
|
+
get: function() {
|
|
1207
|
+
return createDecisionLogic;
|
|
1208
|
+
}
|
|
1209
|
+
});
|
|
1099
1210
|
Object.defineProperty(exports, "createTextLogic", {
|
|
1100
1211
|
enumerable: true,
|
|
1101
1212
|
get: function() {
|
|
@@ -362,6 +362,13 @@ function getCallUsage(raw) {
|
|
|
362
362
|
}
|
|
363
363
|
return out;
|
|
364
364
|
}
|
|
365
|
+
function textRequestSourceIssue(request) {
|
|
366
|
+
const hasPrompt = typeof request.prompt === "string" && request.prompt.length > 0;
|
|
367
|
+
const hasMessages = Array.isArray(request.messages) && request.messages.length > 0;
|
|
368
|
+
const label = request.name ? ` '${request.name}'` : "";
|
|
369
|
+
if (hasPrompt && hasMessages) return `Agent text request${label} has both a non-empty \`prompt\` and \`messages\` — provide exactly one so the model has a single input source.`;
|
|
370
|
+
if (!hasPrompt && !hasMessages) return `Agent text request${label} has neither a non-empty \`prompt\` nor \`messages\` — provide at least one so the model has something to respond to.`;
|
|
371
|
+
}
|
|
365
372
|
const agentTextInputSchema = { "~standard": {
|
|
366
373
|
version: 1,
|
|
367
374
|
vendor: "statelyai-agent",
|
|
@@ -369,9 +376,8 @@ const agentTextInputSchema = { "~standard": {
|
|
|
369
376
|
if (!value || typeof value !== "object") return { issues: [{ message: "Expected agent text input object" }] };
|
|
370
377
|
const request = value;
|
|
371
378
|
if (typeof request.model !== "string") return { issues: [{ message: "Expected agent text input with a string `model`" }] };
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
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.` }] };
|
|
379
|
+
const issue = textRequestSourceIssue(request);
|
|
380
|
+
if (issue) return { issues: [{ message: issue }] };
|
|
375
381
|
return { value: request };
|
|
376
382
|
}
|
|
377
383
|
} };
|
|
@@ -423,7 +429,7 @@ function createBuiltinTextActor(src, mode, outputSchema) {
|
|
|
423
429
|
messages: ({ input }) => input.messages,
|
|
424
430
|
tools: ({ input }) => input.tools,
|
|
425
431
|
toolChoice: ({ input }) => input.toolChoice,
|
|
426
|
-
|
|
432
|
+
includeReasoning: ({ input }) => input.includeReasoning,
|
|
427
433
|
temperature: ({ input }) => input.temperature,
|
|
428
434
|
maxOutputTokens: ({ input }) => input.maxOutputTokens,
|
|
429
435
|
topP: ({ input }) => input.topP,
|
|
@@ -486,16 +492,25 @@ function createTextLogic(config, execute) {
|
|
|
486
492
|
};
|
|
487
493
|
const request = (input) => {
|
|
488
494
|
const args = { input: validateSchemaSync(schemas.input, input) };
|
|
495
|
+
const name = resolveTextLogicValue(config.name, args);
|
|
496
|
+
const prompt = resolveTextLogicValue(config.prompt, args);
|
|
497
|
+
const messages = resolveTextLogicValue(config.messages, args);
|
|
498
|
+
const sourceIssue = textRequestSourceIssue({
|
|
499
|
+
name,
|
|
500
|
+
prompt,
|
|
501
|
+
messages
|
|
502
|
+
});
|
|
503
|
+
if (sourceIssue) throw new Error(sourceIssue);
|
|
489
504
|
return {
|
|
490
|
-
name
|
|
505
|
+
name,
|
|
491
506
|
model: resolveTextLogicValue(config.model, args),
|
|
492
507
|
system: resolveTextLogicValue(config.system, args),
|
|
493
|
-
prompt
|
|
494
|
-
messages
|
|
508
|
+
prompt,
|
|
509
|
+
messages,
|
|
495
510
|
tools: resolveTextLogicValue(config.tools, args),
|
|
496
511
|
toolChoice: resolveTextLogicValue(config.toolChoice, args),
|
|
497
512
|
outputSchema: schemas.output,
|
|
498
|
-
|
|
513
|
+
includeReasoning: resolveTextLogicValue(config.includeReasoning, args),
|
|
499
514
|
temperature: resolveTextLogicValue(config.temperature, args),
|
|
500
515
|
maxOutputTokens: resolveTextLogicValue(config.maxOutputTokens, args),
|
|
501
516
|
topP: resolveTextLogicValue(config.topP, args),
|
|
@@ -642,7 +657,7 @@ function buildEnvelopeSchema(inner, options = {}) {
|
|
|
642
657
|
*/
|
|
643
658
|
function parseStructuredEnvelope(request, value) {
|
|
644
659
|
if (!request.outputSchema) throw new Error("parseStructuredEnvelope: the request declares no outputSchema.");
|
|
645
|
-
return validateSchemaSync(buildEnvelopeSchema(request.outputSchema, { reasoning: request.
|
|
660
|
+
return validateSchemaSync(buildEnvelopeSchema(request.outputSchema, { reasoning: request.includeReasoning }), value);
|
|
646
661
|
}
|
|
647
662
|
/**
|
|
648
663
|
* Merges request-declared and call-site `tools`, dispatches to the
|
|
@@ -662,6 +677,8 @@ async function executeAgentTextRequest(mode, id, input, executors, tools = {}, i
|
|
|
662
677
|
...tools
|
|
663
678
|
}
|
|
664
679
|
};
|
|
680
|
+
const sourceIssue = textRequestSourceIssue(request);
|
|
681
|
+
if (sourceIssue) throw new Error(sourceIssue);
|
|
665
682
|
const executor = mode === "stream" ? executors.streamText : executors.generateText;
|
|
666
683
|
if (!executor) throw new Error(`No executor provided for ${mode === "stream" ? "stream" : "generate"} request '${id}'.`);
|
|
667
684
|
const raw = await executor(request, info);
|
|
@@ -910,6 +927,82 @@ function resolveAllowedEventTypes(allowedEvents, input) {
|
|
|
910
927
|
const resolved = typeof allowedEvents === "function" ? allowedEvents({ input }) : allowedEvents;
|
|
911
928
|
return typeof resolved === "string" ? [resolved] : resolved;
|
|
912
929
|
}
|
|
930
|
+
/**
|
|
931
|
+
* Creates reusable, standalone {@link DecisionLogic}: an actor that, when
|
|
932
|
+
* run, resolves to exactly one currently-legal {@link ChosenEvent} by
|
|
933
|
+
* calling the host `decide` executor (passed here as `execute`, or supplied
|
|
934
|
+
* later via {@link DecisionLogic.withExecutor}, `machine.provide(...)`, or
|
|
935
|
+
* `runAgent`'s `decide` option). Register the result under `actors:` and
|
|
936
|
+
* invoke it by name; for a one-off, state-local decision, prefer the
|
|
937
|
+
* `agent.decide` builtin invoke instead — it needs no separate declaration
|
|
938
|
+
* and types `allowedEvents` against the machine's own event schemas.
|
|
939
|
+
*
|
|
940
|
+
* @example
|
|
941
|
+
* ```ts
|
|
942
|
+
* import { createDecisionLogic } from '@statelyai/agent';
|
|
943
|
+
* import { z } from 'zod';
|
|
944
|
+
*
|
|
945
|
+
* export const chooseMove = createDecisionLogic({
|
|
946
|
+
* schemas: { input: z.object({ playerHp: z.number(), enemyHp: z.number() }) },
|
|
947
|
+
* model: 'openai/gpt-5.4-mini',
|
|
948
|
+
* system: 'You are playing a turn-based game. Choose exactly one legal move.',
|
|
949
|
+
* prompt: ({ input }) => `Player HP: ${input.playerHp}\nEnemy HP: ${input.enemyHp}`,
|
|
950
|
+
* allowedEvents: ({ input }) =>
|
|
951
|
+
* input.playerHp <= 6
|
|
952
|
+
* ? ['ATTACK', 'DEFEND', 'HEAL', 'FLEE']
|
|
953
|
+
* : ['ATTACK', 'DEFEND', 'FLEE'],
|
|
954
|
+
* });
|
|
955
|
+
* ```
|
|
956
|
+
*/
|
|
957
|
+
function createDecisionLogic(config, execute) {
|
|
958
|
+
const maxRetries = config.maxRetries ?? 2;
|
|
959
|
+
const request = (input) => {
|
|
960
|
+
const parsedInput = config.schemas ? validateSchemaSync(config.schemas.input, input) : input;
|
|
961
|
+
const args = { input: parsedInput };
|
|
962
|
+
const allowedEventTypes = resolveAllowedEventTypes(config.allowedEvents, parsedInput);
|
|
963
|
+
return {
|
|
964
|
+
kind: "decision",
|
|
965
|
+
id: "",
|
|
966
|
+
model: resolveTextLogicValue(config.model, args),
|
|
967
|
+
system: resolveTextLogicValue(config.system, args),
|
|
968
|
+
prompt: resolveTextLogicValue(config.prompt, args),
|
|
969
|
+
messages: resolveTextLogicValue(config.messages, args),
|
|
970
|
+
events: (allowedEventTypes ?? []).map((type) => ({
|
|
971
|
+
type,
|
|
972
|
+
toolName: sanitizeEventToolName(type)
|
|
973
|
+
})),
|
|
974
|
+
attempts: [],
|
|
975
|
+
temperature: resolveTextLogicValue(config.temperature, args),
|
|
976
|
+
maxOutputTokens: resolveTextLogicValue(config.maxOutputTokens, args),
|
|
977
|
+
topP: resolveTextLogicValue(config.topP, args),
|
|
978
|
+
topK: resolveTextLogicValue(config.topK, args),
|
|
979
|
+
seed: resolveTextLogicValue(config.seed, args),
|
|
980
|
+
stopSequences: resolveTextLogicValue(config.stopSequences, args),
|
|
981
|
+
metadata: resolveTextLogicValue(config.metadata, args)
|
|
982
|
+
};
|
|
983
|
+
};
|
|
984
|
+
const logic = createAsyncLogic({ run: async ({ input, signal }) => {
|
|
985
|
+
if (!execute) throw new Error("Decision logic has no host execution. Pass an executor as the second argument to createDecisionLogic(...), provide a runtime adapter, or extract it with getAgentEffects(..., { actors }) and resolveDecision(...).");
|
|
986
|
+
const allowedEventTypes = resolveAllowedEventTypes(config.allowedEvents, input);
|
|
987
|
+
if (allowedEventTypes === void 0) throw new Error("Decision logic 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 on this logic to use it here.");
|
|
988
|
+
if (allowedEventTypes.some(isEventPattern)) throw new Error("Decision logic 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.");
|
|
989
|
+
return resolveDecision(request(input), { decide: execute }, {
|
|
990
|
+
maxRetries,
|
|
991
|
+
signal
|
|
992
|
+
});
|
|
993
|
+
} });
|
|
994
|
+
const decisionLogic = Object.assign(logic, {
|
|
995
|
+
kind: "statelyai.decisionLogic",
|
|
996
|
+
maxRetries,
|
|
997
|
+
request,
|
|
998
|
+
allowedEventTypes: (input) => resolveAllowedEventTypes(config.allowedEvents, input),
|
|
999
|
+
withExecutor(nextExecute) {
|
|
1000
|
+
return createDecisionLogic(config, nextExecute);
|
|
1001
|
+
}
|
|
1002
|
+
});
|
|
1003
|
+
if (execute) executorBoundLogics.add(decisionLogic);
|
|
1004
|
+
return decisionLogic;
|
|
1005
|
+
}
|
|
913
1006
|
/** Type guard: true for any actor logic built by createDecisionLogic/createDecideActor (checks the `kind` marker). @internal */
|
|
914
1007
|
function isDecisionLogic(value) {
|
|
915
1008
|
return !!value && typeof value === "object" && value.kind === "statelyai.decisionLogic" && typeof value.request === "function";
|
|
@@ -1029,4 +1122,4 @@ async function resolveDecision(request, executors, options = {}) {
|
|
|
1029
1122
|
throw new AgentDecisionExhaustedError(attempts);
|
|
1030
1123
|
}
|
|
1031
1124
|
//#endregion
|
|
1032
|
-
export {
|
|
1125
|
+
export { getMachineIdlePredicate as A, getAgentMessages as B, normalizeGeneratorResult as C, userInputActor as D, parseStructuredEnvelope as E, machineStaticTransitionTargets as F, isStandardSchema as G, getJsonSchemaSync as H, missingActor as I, toolMessage as J, resolveMachineVersion as K, assistantMessage as L, getRegisteredAgentExecutionOptions as M, isUnboundPlaceholder as N, agentExecutionOptions as O, machineIdlePredicates as P, djb2Hex as R, isTextLogic as S, parseOutput as T, getMachineStructuralHash as U, getJsonSchema as V, getStateMeta as W, validateSchemaSync as X, userMessage as Y, builtinTextActors as _, renderDecisionAttempts as a, getAgentOutputMode as b, parseAgentEvent as c, GENERATE_TEXT_ACTOR as d, INTERPRET_SOURCE as f, buildEnvelopeSchema as g, bindRequestExecutor as h, isDecisionLogic as i, getMachineStaticTransitionTargets as j, executorBoundLogics as k, AGENT_USAGE_TOKEN_FIELDS as l, USER_INPUT_ACTOR as m, createDecideActor as n, resolveDecision as o, STREAM_TEXT_ACTOR as p, systemMessage as q, createDecisionLogic as r, getAcceptedEvents as s, AgentDecisionExhaustedError as t, DECIDE_ACTOR as u, createTextLogic as v, parseModelRef as w, getCallUsage as x, executeAgentTextRequest as y, findNonSerializableContextPaths as z };
|