@falai/agent 4.0.0-alpha.9 → 4.0.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/README.md +2 -0
- package/dist/cjs/core/Agent.d.ts +8 -1
- package/dist/cjs/core/Agent.d.ts.map +1 -1
- package/dist/cjs/core/Agent.js +18 -0
- package/dist/cjs/core/Agent.js.map +1 -1
- package/dist/cjs/core/CompactionEngine.d.ts.map +1 -1
- package/dist/cjs/core/CompactionEngine.js +21 -7
- package/dist/cjs/core/CompactionEngine.js.map +1 -1
- package/dist/cjs/core/FlowSpec.d.ts +21 -2
- package/dist/cjs/core/FlowSpec.d.ts.map +1 -1
- package/dist/cjs/core/FlowSpec.js +282 -60
- package/dist/cjs/core/FlowSpec.js.map +1 -1
- package/dist/cjs/core/Migrate.d.ts.map +1 -1
- package/dist/cjs/core/Migrate.js +3 -1
- package/dist/cjs/core/Migrate.js.map +1 -1
- package/dist/cjs/core/Prompt.d.ts +16 -0
- package/dist/cjs/core/Prompt.d.ts.map +1 -1
- package/dist/cjs/core/Prompt.js +39 -0
- package/dist/cjs/core/Prompt.js.map +1 -1
- package/dist/cjs/core/Runner.d.ts +37 -4
- package/dist/cjs/core/Runner.d.ts.map +1 -1
- package/dist/cjs/core/Runner.js +281 -72
- package/dist/cjs/core/Runner.js.map +1 -1
- package/dist/cjs/core/Speak.d.ts.map +1 -1
- package/dist/cjs/core/Speak.js +63 -19
- package/dist/cjs/core/Speak.js.map +1 -1
- package/dist/cjs/core/Understand.d.ts +6 -3
- package/dist/cjs/core/Understand.d.ts.map +1 -1
- package/dist/cjs/core/Understand.js +18 -42
- package/dist/cjs/core/Understand.js.map +1 -1
- package/dist/cjs/core/contracts.d.ts +26 -6
- package/dist/cjs/core/contracts.d.ts.map +1 -1
- package/dist/cjs/index.d.ts +1 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/persistence/OpenSearchStore.d.ts +2 -1
- package/dist/cjs/persistence/OpenSearchStore.d.ts.map +1 -1
- package/dist/cjs/persistence/OpenSearchStore.js +2 -2
- package/dist/cjs/persistence/OpenSearchStore.js.map +1 -1
- package/dist/cjs/persistence/RedisStore.d.ts +1 -1
- package/dist/cjs/persistence/RedisStore.d.ts.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.d.ts +2 -5
- package/dist/cjs/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/cjs/providers/AnthropicProvider.js +3 -4
- package/dist/cjs/providers/AnthropicProvider.js.map +1 -1
- package/dist/cjs/providers/DeepSeekProvider.d.ts.map +1 -1
- package/dist/cjs/providers/DeepSeekProvider.js +3 -4
- package/dist/cjs/providers/DeepSeekProvider.js.map +1 -1
- package/dist/cjs/providers/FallbackAiProvider.js +1 -1
- package/dist/cjs/providers/FallbackAiProvider.js.map +1 -1
- package/dist/cjs/providers/GeminiProvider.d.ts +1 -2
- package/dist/cjs/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/cjs/providers/GeminiProvider.js +3 -4
- package/dist/cjs/providers/GeminiProvider.js.map +1 -1
- package/dist/cjs/providers/GenericOpenAICompatibleProvider.js +4 -4
- package/dist/cjs/providers/GenericOpenAICompatibleProvider.js.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenAIProvider.js +3 -4
- package/dist/cjs/providers/OpenAIProvider.js.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/cjs/providers/OpenRouterProvider.js +4 -3
- package/dist/cjs/providers/OpenRouterProvider.js.map +1 -1
- package/dist/cjs/providers/ProviderAdapter.d.ts +26 -11
- package/dist/cjs/providers/ProviderAdapter.d.ts.map +1 -1
- package/dist/cjs/providers/ProviderAdapter.js +13 -13
- package/dist/cjs/providers/ProviderAdapter.js.map +1 -1
- package/dist/cjs/providers/ZaiProvider.js +1 -1
- package/dist/cjs/providers/ZaiProvider.js.map +1 -1
- package/dist/cjs/types/agent.d.ts +14 -3
- package/dist/cjs/types/agent.d.ts.map +1 -1
- package/dist/cjs/types/ai.d.ts +10 -6
- package/dist/cjs/types/ai.d.ts.map +1 -1
- package/dist/cjs/types/compaction.d.ts +1 -0
- package/dist/cjs/types/compaction.d.ts.map +1 -1
- package/dist/cjs/types/errors.d.ts +4 -9
- package/dist/cjs/types/errors.d.ts.map +1 -1
- package/dist/cjs/types/errors.js +12 -12
- package/dist/cjs/types/errors.js.map +1 -1
- package/dist/cjs/types/flow.d.ts +17 -1
- package/dist/cjs/types/flow.d.ts.map +1 -1
- package/dist/cjs/types/history.d.ts +0 -7
- package/dist/cjs/types/history.d.ts.map +1 -1
- package/dist/cjs/types/index.d.ts +2 -2
- package/dist/cjs/types/index.d.ts.map +1 -1
- package/dist/cjs/types/session.d.ts +4 -2
- package/dist/cjs/types/session.d.ts.map +1 -1
- package/dist/cjs/utils/clock.js +1 -1
- package/dist/cjs/utils/clock.js.map +1 -1
- package/dist/cjs/utils/outcomes.d.ts +2 -0
- package/dist/cjs/utils/outcomes.d.ts.map +1 -1
- package/dist/cjs/utils/outcomes.js +2 -0
- package/dist/cjs/utils/outcomes.js.map +1 -1
- package/dist/cjs/utils/schema.d.ts +3 -12
- package/dist/cjs/utils/schema.d.ts.map +1 -1
- package/dist/cjs/utils/schema.js +3 -43
- package/dist/cjs/utils/schema.js.map +1 -1
- package/dist/cjs/utils/template.d.ts.map +1 -1
- package/dist/cjs/utils/template.js +9 -2
- package/dist/cjs/utils/template.js.map +1 -1
- package/dist/core/Agent.d.ts +8 -1
- package/dist/core/Agent.d.ts.map +1 -1
- package/dist/core/Agent.js +19 -1
- package/dist/core/Agent.js.map +1 -1
- package/dist/core/CompactionEngine.d.ts.map +1 -1
- package/dist/core/CompactionEngine.js +21 -7
- package/dist/core/CompactionEngine.js.map +1 -1
- package/dist/core/FlowSpec.d.ts +21 -2
- package/dist/core/FlowSpec.d.ts.map +1 -1
- package/dist/core/FlowSpec.js +281 -61
- package/dist/core/FlowSpec.js.map +1 -1
- package/dist/core/Migrate.d.ts.map +1 -1
- package/dist/core/Migrate.js +3 -1
- package/dist/core/Migrate.js.map +1 -1
- package/dist/core/Prompt.d.ts +16 -0
- package/dist/core/Prompt.d.ts.map +1 -1
- package/dist/core/Prompt.js +37 -0
- package/dist/core/Prompt.js.map +1 -1
- package/dist/core/Runner.d.ts +37 -4
- package/dist/core/Runner.d.ts.map +1 -1
- package/dist/core/Runner.js +282 -73
- package/dist/core/Runner.js.map +1 -1
- package/dist/core/Speak.d.ts.map +1 -1
- package/dist/core/Speak.js +64 -20
- package/dist/core/Speak.js.map +1 -1
- package/dist/core/Understand.d.ts +6 -3
- package/dist/core/Understand.d.ts.map +1 -1
- package/dist/core/Understand.js +18 -42
- package/dist/core/Understand.js.map +1 -1
- package/dist/core/contracts.d.ts +26 -6
- package/dist/core/contracts.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/persistence/OpenSearchStore.d.ts +2 -1
- package/dist/persistence/OpenSearchStore.d.ts.map +1 -1
- package/dist/persistence/OpenSearchStore.js +2 -2
- package/dist/persistence/OpenSearchStore.js.map +1 -1
- package/dist/persistence/RedisStore.d.ts +1 -1
- package/dist/persistence/RedisStore.d.ts.map +1 -1
- package/dist/providers/AnthropicProvider.d.ts +2 -5
- package/dist/providers/AnthropicProvider.d.ts.map +1 -1
- package/dist/providers/AnthropicProvider.js +3 -4
- package/dist/providers/AnthropicProvider.js.map +1 -1
- package/dist/providers/DeepSeekProvider.d.ts.map +1 -1
- package/dist/providers/DeepSeekProvider.js +3 -4
- package/dist/providers/DeepSeekProvider.js.map +1 -1
- package/dist/providers/FallbackAiProvider.js +1 -1
- package/dist/providers/FallbackAiProvider.js.map +1 -1
- package/dist/providers/GeminiProvider.d.ts +1 -2
- package/dist/providers/GeminiProvider.d.ts.map +1 -1
- package/dist/providers/GeminiProvider.js +3 -4
- package/dist/providers/GeminiProvider.js.map +1 -1
- package/dist/providers/GenericOpenAICompatibleProvider.js +4 -4
- package/dist/providers/GenericOpenAICompatibleProvider.js.map +1 -1
- package/dist/providers/OpenAIProvider.d.ts.map +1 -1
- package/dist/providers/OpenAIProvider.js +3 -4
- package/dist/providers/OpenAIProvider.js.map +1 -1
- package/dist/providers/OpenRouterProvider.d.ts.map +1 -1
- package/dist/providers/OpenRouterProvider.js +4 -3
- package/dist/providers/OpenRouterProvider.js.map +1 -1
- package/dist/providers/ProviderAdapter.d.ts +26 -11
- package/dist/providers/ProviderAdapter.d.ts.map +1 -1
- package/dist/providers/ProviderAdapter.js +14 -14
- package/dist/providers/ProviderAdapter.js.map +1 -1
- package/dist/providers/ZaiProvider.js +1 -1
- package/dist/providers/ZaiProvider.js.map +1 -1
- package/dist/types/agent.d.ts +14 -3
- package/dist/types/agent.d.ts.map +1 -1
- package/dist/types/ai.d.ts +10 -6
- package/dist/types/ai.d.ts.map +1 -1
- package/dist/types/compaction.d.ts +1 -0
- package/dist/types/compaction.d.ts.map +1 -1
- package/dist/types/errors.d.ts +4 -9
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +12 -12
- package/dist/types/errors.js.map +1 -1
- package/dist/types/flow.d.ts +17 -1
- package/dist/types/flow.d.ts.map +1 -1
- package/dist/types/history.d.ts +0 -7
- package/dist/types/history.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/session.d.ts +4 -2
- package/dist/types/session.d.ts.map +1 -1
- package/dist/utils/clock.js +1 -1
- package/dist/utils/clock.js.map +1 -1
- package/dist/utils/outcomes.d.ts +2 -0
- package/dist/utils/outcomes.d.ts.map +1 -1
- package/dist/utils/outcomes.js +2 -0
- package/dist/utils/outcomes.js.map +1 -1
- package/dist/utils/schema.d.ts +3 -12
- package/dist/utils/schema.d.ts.map +1 -1
- package/dist/utils/schema.js +3 -42
- package/dist/utils/schema.js.map +1 -1
- package/dist/utils/template.d.ts.map +1 -1
- package/dist/utils/template.js +9 -2
- package/dist/utils/template.js.map +1 -1
- package/docs/concepts/architecture.md +2 -2
- package/docs/concepts/collection.md +40 -5
- package/docs/concepts/pipeline.md +10 -7
- package/docs/concepts/runs-and-waits.md +2 -2
- package/docs/guides/actions-and-events.md +1 -1
- package/docs/guides/branching.md +4 -2
- package/docs/guides/compaction.md +2 -2
- package/docs/guides/error-handling.md +2 -2
- package/docs/guides/flow-control.md +4 -2
- package/docs/guides/persistence.md +2 -2
- package/docs/guides/testing.md +1 -1
- package/docs/guides/triggers.md +3 -3
- package/docs/migration/v3-to-v4.md +8 -7
- package/docs/reference/actions-events-conditions.md +1 -1
- package/docs/reference/agent.md +9 -5
- package/docs/reference/branches.md +1 -1
- package/docs/reference/errors.md +14 -11
- package/docs/reference/fields.md +5 -3
- package/docs/reference/flow-spec.md +35 -8
- package/docs/reference/flow.md +8 -3
- package/docs/reference/outcomes.md +4 -2
- package/docs/reference/providers.md +5 -3
- package/docs/reference/session.md +2 -0
- package/docs/reference/step.md +9 -5
- package/docs/reference/stores.md +5 -3
- package/docs/reference/trigger.md +2 -2
- package/docs/rfc/v4-one-flow.md +5 -3
- package/docs/start/01-install.md +2 -0
- package/docs/start/05-go-to-production.md +18 -1
- package/examples/05-branches.ts +1 -1
- package/examples/06-triggers-and-waits.ts +4 -3
- package/package.json +4 -3
- package/src/core/Agent.ts +23 -2
- package/src/core/CompactionEngine.ts +25 -9
- package/src/core/FlowSpec.ts +296 -70
- package/src/core/Migrate.ts +2 -1
- package/src/core/Prompt.ts +40 -0
- package/src/core/Runner.ts +279 -69
- package/src/core/Speak.ts +67 -19
- package/src/core/Understand.ts +24 -44
- package/src/core/contracts.ts +26 -4
- package/src/index.ts +1 -1
- package/src/persistence/OpenSearchStore.ts +3 -2
- package/src/persistence/RedisStore.ts +1 -1
- package/src/providers/AnthropicProvider.ts +4 -9
- package/src/providers/DeepSeekProvider.ts +2 -4
- package/src/providers/FallbackAiProvider.ts +1 -1
- package/src/providers/GeminiProvider.ts +3 -6
- package/src/providers/GenericOpenAICompatibleProvider.ts +4 -4
- package/src/providers/OpenAIProvider.ts +3 -4
- package/src/providers/OpenRouterProvider.ts +4 -2
- package/src/providers/ProviderAdapter.ts +35 -33
- package/src/providers/ZaiProvider.ts +1 -1
- package/src/types/agent.ts +15 -4
- package/src/types/ai.ts +10 -6
- package/src/types/compaction.ts +1 -0
- package/src/types/errors.ts +11 -12
- package/src/types/flow.ts +17 -1
- package/src/types/history.ts +0 -10
- package/src/types/index.ts +1 -1
- package/src/types/session.ts +5 -1
- package/src/utils/clock.ts +1 -1
- package/src/utils/outcomes.ts +2 -0
- package/src/utils/schema.ts +3 -48
- package/src/utils/template.ts +9 -2
- package/dist/cjs/providers/index.d.ts +0 -26
- package/dist/cjs/providers/index.d.ts.map +0 -1
- package/dist/cjs/providers/index.js +0 -30
- package/dist/cjs/providers/index.js.map +0 -1
- package/dist/cjs/utils/clone.d.ts +0 -8
- package/dist/cjs/utils/clone.d.ts.map +0 -1
- package/dist/cjs/utils/clone.js +0 -32
- package/dist/cjs/utils/clone.js.map +0 -1
- package/dist/cjs/utils/index.d.ts +0 -9
- package/dist/cjs/utils/index.d.ts.map +0 -1
- package/dist/cjs/utils/index.js +0 -29
- package/dist/cjs/utils/index.js.map +0 -1
- package/dist/providers/index.d.ts +0 -26
- package/dist/providers/index.d.ts.map +0 -1
- package/dist/providers/index.js +0 -17
- package/dist/providers/index.js.map +0 -1
- package/dist/utils/clone.d.ts +0 -8
- package/dist/utils/clone.d.ts.map +0 -1
- package/dist/utils/clone.js +0 -29
- package/dist/utils/clone.js.map +0 -1
- package/dist/utils/index.d.ts +0 -9
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -9
- package/dist/utils/index.js.map +0 -1
- package/src/providers/index.ts +0 -38
- package/src/utils/clone.ts +0 -34
- package/src/utils/index.ts +0 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CompactionEngine.js","sourceRoot":"","sources":["../../src/core/CompactionEngine.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,GAAG,MAAM,UAAU,CAAC;AAI3B,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,MAAM,OAAO,gBAAgB;IACzB;;OAEG;IACH,MAAM,CAAC,eAAe,CAAC,OAA0B;QAC7C,IACI,OAAO,OAAO,CAAC,mBAAmB,KAAK,QAAQ;YAC/C,OAAO,CAAC,mBAAmB,GAAG,GAAG;YACjC,OAAO,CAAC,mBAAmB,GAAG,IAAI,EACpC,CAAC;YACC,MAAM,IAAI,KAAK,CACX,
|
|
1
|
+
{"version":3,"file":"CompactionEngine.js","sourceRoot":"","sources":["../../src/core/CompactionEngine.ts"],"names":[],"mappings":"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"}
|
package/dist/core/FlowSpec.d.ts
CHANGED
|
@@ -67,6 +67,7 @@ export type StepSpec = StepBase<LooseData> & (({
|
|
|
67
67
|
kind: "collect";
|
|
68
68
|
collect: string[];
|
|
69
69
|
prompt?: Template;
|
|
70
|
+
question?: Template;
|
|
70
71
|
} & TalkSpecExtras) | ({
|
|
71
72
|
kind: "say";
|
|
72
73
|
} & SayStep) | ({
|
|
@@ -91,14 +92,23 @@ export interface FlowSpec {
|
|
|
91
92
|
on?: TriggerSpec[];
|
|
92
93
|
anchor?: string;
|
|
93
94
|
while?: ConditionSpec<LooseData>;
|
|
95
|
+
collect?: string[];
|
|
94
96
|
clearOnStart?: string[];
|
|
95
97
|
steps: StepSpec[];
|
|
96
98
|
onEnd?: "end" | "stay" | "reset";
|
|
97
99
|
instructions?: InstructionSpec[];
|
|
98
100
|
tools?: string[];
|
|
99
101
|
}
|
|
100
|
-
/**
|
|
101
|
-
|
|
102
|
+
/**
|
|
103
|
+
* What a flow's names resolve against: the agent's fields, actions, events,
|
|
104
|
+
* conditions and tools. With `flows`, a literal `{ flow }` target must name
|
|
105
|
+
* one of them; the agent passes its own.
|
|
106
|
+
*/
|
|
107
|
+
export type Registries = Pick<AgentOptions, "fields" | "actions" | "events" | "conditions" | "tools"> & {
|
|
108
|
+
flows?: ReadonlyArray<{
|
|
109
|
+
id: string;
|
|
110
|
+
}>;
|
|
111
|
+
};
|
|
102
112
|
/**
|
|
103
113
|
* A spec as a typed flow. The slugs and names inside a spec are strings from
|
|
104
114
|
* storage, so the result is typed by claim: `validateFlow` (which the agent
|
|
@@ -108,6 +118,9 @@ export type Registries = Pick<AgentOptions, "fields" | "actions" | "events" | "c
|
|
|
108
118
|
export declare function fromSpec<C = unknown, D = LooseData>(spec: FlowSpec): Flow<C, D>;
|
|
109
119
|
/** Throws `FlowConfigurationError` when the flow carries a function predicate: it cannot be stored. */
|
|
110
120
|
export declare function toSpec<C, D extends LooseData>(flow: Flow<C, D>): FlowSpec;
|
|
121
|
+
/** A read-only view that a typed Flow and a spec-derived Flow both fit; the validator only reads. */
|
|
122
|
+
type LoosePred = ((ctx: never) => boolean) | Record<string, unknown>;
|
|
123
|
+
export declare const BUILT_IN_CONDITIONS: string[];
|
|
111
124
|
/**
|
|
112
125
|
* Check a flow, typed or as a spec, against the agent's registries. Throws
|
|
113
126
|
* `FlowConfigurationError` on the first problem that would break at runtime;
|
|
@@ -116,6 +129,12 @@ export declare function toSpec<C, D extends LooseData>(flow: Flow<C, D>): FlowSp
|
|
|
116
129
|
export declare function validateFlow<C = unknown, D = LooseData>(input: Flow<C, D> | FlowSpec, registries: Registries): {
|
|
117
130
|
warnings: string[];
|
|
118
131
|
};
|
|
132
|
+
/**
|
|
133
|
+
* A predicate's names against the registries: the fields `equals` and `known`
|
|
134
|
+
* read, and every other key as one of the agent's conditions. A function is
|
|
135
|
+
* code and passes as is. The agent runs this on its own instructions too.
|
|
136
|
+
*/
|
|
137
|
+
export declare function checkPred(value: LoosePred | undefined, at: string, where: string, registries: Registries): void;
|
|
119
138
|
/**
|
|
120
139
|
* FlowSpec's JSON schema with this workspace's actions (each with its
|
|
121
140
|
* parameter schema), events, conditions and field slugs as enums. Every
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FlowSpec.d.ts","sourceRoot":"","sources":["../../src/core/FlowSpec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,KAAK,EAEV,aAAa,EACb,MAAM,EACN,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,SAAS,EACT,WAAW,EACX,IAAI,EAEJ,SAAS,EAET,MAAM,EACN,OAAO,EAGP,QAAQ,EACR,QAAQ,EAER,aAAa,EAEd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAO3D,0FAA0F;AAC1F,KAAK,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;AAEtC,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;AAEzF,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;CAAE,GAAG,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;CAAE,CAAC,CAAC;AAE3G,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;CAAE,CAAC;AAE1F,+EAA+E;AAC/E,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,CAC5C;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,EAAE,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;CAAE,GACpD;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAAC,EAAE,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;CAAE,GACzE;IAAE,OAAO,EAAE,QAAQ,CAAC;IAAC,EAAE,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7E;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAC9F,CAAC;AAEF,UAAU,cAAc;IACtB,GAAG,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;CAClC;AAED,0DAA0D;AAC1D,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,GACxC,CACI,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,cAAc,CAAC,GAC5E,CAAC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,CAAA;CAAE,GAAG,cAAc,CAAC,
|
|
1
|
+
{"version":3,"file":"FlowSpec.d.ts","sourceRoot":"","sources":["../../src/core/FlowSpec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,KAAK,EAEV,aAAa,EACb,MAAM,EACN,QAAQ,EACR,SAAS,EACT,IAAI,EACJ,SAAS,EACT,WAAW,EACX,IAAI,EAEJ,SAAS,EAET,MAAM,EACN,OAAO,EAGP,QAAQ,EACR,QAAQ,EAER,aAAa,EAEd,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAO3D,0FAA0F;AAC1F,KAAK,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;AAEtC,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,MAAM,GAAG,WAAW,GAAG,IAAI,CAAC;AAEzF,MAAM,MAAM,UAAU,GAAG;IAAE,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;CAAE,GAAG,CAAC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;CAAE,CAAC,CAAC;AAE3G,MAAM,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,GAAG;IAAE,EAAE,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;CAAE,CAAC;AAE1F,+EAA+E;AAC/E,MAAM,MAAM,WAAW,GAAG;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,CAC5C;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,EAAE,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;CAAE,GACpD;IAAE,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,CAAC;IAAC,EAAE,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;CAAE,GACzE;IAAE,OAAO,EAAE,QAAQ,CAAC;IAAC,EAAE,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,GAC7E;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,EAAE,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE,QAAQ,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAA;CAAE,CAC9F,CAAC;AAEF,UAAU,cAAc;IACtB,GAAG,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAC;IACxB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;CAClC;AAED,0DAA0D;AAC1D,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,SAAS,CAAC,GACxC,CACI,CAAC;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,MAAM,EAAE,QAAQ,CAAC;IAAC,OAAO,CAAC,EAAE,SAAS,CAAA;CAAE,GAAG,cAAc,CAAC,GAC5E,CAAC;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,MAAM,EAAE,CAAC;IAAC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAAC,QAAQ,CAAC,EAAE,QAAQ,CAAA;CAAE,GAAG,cAAc,CAAC,GACjG,CAAC;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,GAAG,OAAO,CAAC,GAC3B,CAAC;IAAE,IAAI,EAAE,IAAI,CAAA;CAAE,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,GACpC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,QAAQ,CAAC;IAAC,aAAa,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IAAC,QAAQ,CAAC,EAAE,UAAU,EAAE,CAAA;CAAE,GAC1G,CAAC;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GAAG,aAAa,CAAC,SAAS,CAAC,CAAC,GAClD;IAAE,IAAI,EAAE,IAAI,CAAC;IAAC,EAAE,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IAAC,IAAI,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;CAAE,CACvE,CAAC;AAEJ,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,EAAE,CAAC,EAAE,WAAW,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,aAAa,CAAC,SAAS,CAAC,CAAC;IACjC,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC;IACjC,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB;AAED;;;;GAIG;AACH,MAAM,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,YAAY,GAAG,OAAO,CAAC,GAAG;IACtG,KAAK,CAAC,EAAE,aAAa,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvC,CAAC;AAIF;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,SAAS,EAAE,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,CAM/E;AAQD,uGAAuG;AACvG,wBAAgB,MAAM,CAAC,CAAC,EAAE,CAAC,SAAS,SAAS,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,QAAQ,CAgBzE;AAgFD,qGAAqG;AAErG,KAAK,SAAS,GAAG,CAAC,CAAC,GAAG,EAAE,KAAK,KAAK,OAAO,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AA+CrE,eAAO,MAAM,mBAAmB,UAAkC,CAAC;AAWnE;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,CAAC,GAAG,OAAO,EAAE,CAAC,GAAG,SAAS,EACrD,KAAK,EAAE,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,QAAQ,EAC5B,UAAU,EAAE,UAAU,GACrB;IAAE,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAsOxB;AAQD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,SAAS,GAAG,SAAS,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,IAAI,CA+B/G;AA4OD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,UAAU,EAAE,UAAU,GAAG,gBAAgB,CA0GvE"}
|
package/dist/core/FlowSpec.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
import { FlowConfigurationError } from "../types/errors.js";
|
|
19
19
|
import { isDuration } from "../utils/duration.js";
|
|
20
20
|
import { splitPhrases } from "../utils/phrases.js";
|
|
21
|
-
import { toWireSchema } from "../utils/schema.js";
|
|
21
|
+
import { extractMode, toWireSchema } from "../utils/schema.js";
|
|
22
22
|
// ── fromSpec / toSpec ───────────────────────────────────────────────────
|
|
23
23
|
/**
|
|
24
24
|
* A spec as a typed flow. The slugs and names inside a spec are strings from
|
|
@@ -28,9 +28,7 @@ import { toWireSchema } from "../utils/schema.js";
|
|
|
28
28
|
*/
|
|
29
29
|
export function fromSpec(spec) {
|
|
30
30
|
const clean = stripNulls(spec);
|
|
31
|
-
|
|
32
|
-
throw problem(`flow "${clean.id}"`, "has no steps list", "Write steps as a list, even an empty one.");
|
|
33
|
-
}
|
|
31
|
+
checkShape(clean);
|
|
34
32
|
const { steps, ...rest } = clean;
|
|
35
33
|
const flow = { ...rest, steps: steps.map(fromStepSpec) };
|
|
36
34
|
return flow;
|
|
@@ -50,6 +48,7 @@ export function toSpec(flow) {
|
|
|
50
48
|
on: flow.on?.map((trigger, i) => triggerToSpec(trigger, at(`trigger #${i + 1}`))),
|
|
51
49
|
anchor: flow.anchor,
|
|
52
50
|
while: jsonPred(flow.while, at("while")),
|
|
51
|
+
collect: flow.collect,
|
|
53
52
|
clearOnStart: flow.clearOnStart,
|
|
54
53
|
steps: flow.steps.map((step) => stepToSpec(step, at(`step "${step.id}"`))),
|
|
55
54
|
onEnd: flow.onEnd,
|
|
@@ -97,11 +96,13 @@ function stepToSpec(step, at) {
|
|
|
97
96
|
instructions: step.instructions?.map((ins, i) => instructionToSpec(ins, `${at} instructions[${i}]`)),
|
|
98
97
|
};
|
|
99
98
|
if (step.collect !== undefined) {
|
|
100
|
-
return compact({ ...base, kind: "collect", collect: step.collect, prompt: step.prompt, ...talk });
|
|
99
|
+
return compact({ ...base, kind: "collect", collect: step.collect, prompt: step.prompt, question: step.question, ...talk });
|
|
101
100
|
}
|
|
102
101
|
if (step.prompt === undefined) {
|
|
103
102
|
throw problem(at, "has neither prompt nor collect", "A talk step needs a guideline, fields to collect, or both.");
|
|
104
103
|
}
|
|
104
|
+
if (step.question !== undefined)
|
|
105
|
+
throw questionWithoutCollect(at);
|
|
105
106
|
return compact({ ...base, kind: "prompt", prompt: step.prompt, ...talk });
|
|
106
107
|
}
|
|
107
108
|
/** `typeof step.wait` alone does not narrow the union for tsc; this does. */
|
|
@@ -117,12 +118,12 @@ function jsonPredRequired(pred, at) {
|
|
|
117
118
|
}
|
|
118
119
|
return pred;
|
|
119
120
|
}
|
|
120
|
-
const BUILT_IN_CONDITIONS = ["equals", "known", "silenced"];
|
|
121
|
+
export const BUILT_IN_CONDITIONS = ["equals", "known", "silenced"];
|
|
121
122
|
const DURATION_HINT = 'Write a number and a unit: "30s", "5m", "24h" or "3d".';
|
|
122
123
|
/** The four keys one of which makes an `on[]` entry a trigger. */
|
|
123
124
|
const TRIGGER_KINDS = ["message", "mention", "silence", "event"];
|
|
124
|
-
|
|
125
|
-
const
|
|
125
|
+
const ON_END = ["end", "stay", "reset"];
|
|
126
|
+
const INSTRUCTION_KINDS = ["must", "never", "should"];
|
|
126
127
|
/**
|
|
127
128
|
* Check a flow, typed or as a spec, against the agent's registries. Throws
|
|
128
129
|
* `FlowConfigurationError` on the first problem that would break at runtime;
|
|
@@ -131,16 +132,14 @@ const STEP_DOES = ["prompt", "collect", "say", "do", "wait", "if"];
|
|
|
131
132
|
export function validateFlow(input, registries) {
|
|
132
133
|
// Nulls mean "not set" in a spec; a typed flow has none, so one pass serves both forms.
|
|
133
134
|
const flow = stripNulls(input);
|
|
134
|
-
|
|
135
|
+
checkShape(flow);
|
|
136
|
+
const { fields, actions = {}, events = {}, tools = [] } = registries;
|
|
135
137
|
const toolIds = new Set(tools.map((tool) => tool.id));
|
|
136
138
|
const warnings = [];
|
|
137
139
|
if (typeof flow.id !== "string" || flow.id === "") {
|
|
138
140
|
throw problem("flow", "has no id", "Give the flow a short unique id.");
|
|
139
141
|
}
|
|
140
142
|
const flowAt = `flow "${flow.id}"`;
|
|
141
|
-
if (!Array.isArray(flow.steps)) {
|
|
142
|
-
throw problem(flowAt, "has no steps list", "Write steps as a list, even an empty one.");
|
|
143
|
-
}
|
|
144
143
|
const index = new Map();
|
|
145
144
|
flow.steps.forEach((step, i) => {
|
|
146
145
|
if (typeof step.id !== "string" || step.id === "") {
|
|
@@ -157,48 +156,14 @@ export function validateFlow(input, registries) {
|
|
|
157
156
|
if (flow.on?.length && flow.steps.length === 0) {
|
|
158
157
|
throw problem(flowAt, "has triggers but no steps", "Add at least one step or remove `on`.");
|
|
159
158
|
}
|
|
160
|
-
const slug = (name, at, where) =>
|
|
161
|
-
if (!own(fields, name)) {
|
|
162
|
-
throw problem(at, `unknown field "${name}" in ${where}`, "Add it to the agent's fields or fix the slug.");
|
|
163
|
-
}
|
|
164
|
-
};
|
|
159
|
+
const slug = (name, at, where) => checkSlug(fields, name, at, where);
|
|
165
160
|
const toolNames = (names, at) => {
|
|
166
161
|
for (const name of names ?? []) {
|
|
167
162
|
if (!toolIds.has(name))
|
|
168
163
|
throw problem(at, `unknown tool "${name}"`, "Register it in the agent's tools or fix the name.");
|
|
169
164
|
}
|
|
170
165
|
};
|
|
171
|
-
const pred = (value, at, where) =>
|
|
172
|
-
if (value === undefined || typeof value === "function")
|
|
173
|
-
return;
|
|
174
|
-
for (const [name, arg] of Object.entries(value)) {
|
|
175
|
-
if (name === "equals") {
|
|
176
|
-
if (arg === null || typeof arg !== "object" || Array.isArray(arg)) {
|
|
177
|
-
throw problem(at, `${where}.equals is not an object`, "Write equals as { field: value }.");
|
|
178
|
-
}
|
|
179
|
-
for (const [field, given] of Object.entries(arg)) {
|
|
180
|
-
slug(field, at, `${where}.equals`);
|
|
181
|
-
const def = fields[field];
|
|
182
|
-
if (!matches(def, given)) {
|
|
183
|
-
throw problem(at, `${where}.equals gives "${field}" a ${describe(given)}, but the field is a ${def.type}`, `Write a ${def.type}; values are not coerced.`);
|
|
184
|
-
}
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
else if (name === "known") {
|
|
188
|
-
if (!Array.isArray(arg))
|
|
189
|
-
throw problem(at, `${where}.known is not a list`, "Write known as [field, ...].");
|
|
190
|
-
for (const field of arg)
|
|
191
|
-
slug(String(field), at, `${where}.known`);
|
|
192
|
-
}
|
|
193
|
-
else if (name === "silenced") {
|
|
194
|
-
if (typeof arg !== "boolean")
|
|
195
|
-
throw problem(at, `${where}.silenced is not a boolean`, "Write true or false.");
|
|
196
|
-
}
|
|
197
|
-
else if (!own(conditions, name)) {
|
|
198
|
-
throw problem(at, `unknown condition "${name}" in ${where}`, `Register it in conditions or use ${BUILT_IN_CONDITIONS.join(", ")}.`);
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
};
|
|
166
|
+
const pred = (value, at, where) => checkPred(value, at, where, registries);
|
|
202
167
|
const duration = (value, at, where) => {
|
|
203
168
|
if (value !== undefined && !isDuration(value)) {
|
|
204
169
|
throw problem(at, `${where} has duration "${value}", which does not parse`, DURATION_HINT);
|
|
@@ -215,8 +180,16 @@ export function validateFlow(input, registries) {
|
|
|
215
180
|
}
|
|
216
181
|
return to;
|
|
217
182
|
}
|
|
218
|
-
if ("flow" in next)
|
|
183
|
+
if ("flow" in next) {
|
|
184
|
+
// A templated id resolves per run; only a literal one can be checked now. A warning, not a throw:
|
|
185
|
+
// a host that drops one bad row keeps the rest of its agent, and the Runner skips this move as flow-gone.
|
|
186
|
+
const known = registries.flows?.map((f) => f.id);
|
|
187
|
+
if (known && !next.flow.includes("{{") && !known.includes(next.flow)) {
|
|
188
|
+
const fix = known.length ? `Use one of ${known.map((id) => `"${id}"`).join(", ")}, or add the flow.` : "Add the flow to the agent.";
|
|
189
|
+
warnings.push(`${at}: ${where} names flow "${next.flow}", which this agent does not have; a run skips this move with flow-gone. ${fix}`);
|
|
190
|
+
}
|
|
219
191
|
return undefined;
|
|
192
|
+
}
|
|
220
193
|
const to = index.get(next.step);
|
|
221
194
|
if (to === undefined) {
|
|
222
195
|
throw problem(at, `${where} points at step "${next.step}", which does not exist`, 'Use an existing step id or "end".');
|
|
@@ -256,8 +229,18 @@ export function validateFlow(input, registries) {
|
|
|
256
229
|
}
|
|
257
230
|
}
|
|
258
231
|
};
|
|
232
|
+
for (const field of flow.collect ?? [])
|
|
233
|
+
slug(field, flowAt, "collect");
|
|
259
234
|
for (const field of flow.clearOnStart ?? [])
|
|
260
235
|
slug(field, flowAt, "clearOnStart");
|
|
236
|
+
// A field taken only from the answer to a step that asks it can never be filled when no step asks it.
|
|
237
|
+
const asked = new Set(flow.steps.flatMap((step) => step.collect ?? []));
|
|
238
|
+
for (const field of flow.collect ?? []) {
|
|
239
|
+
if (!asked.has(field) && extractMode(fields[field]) === "asked") {
|
|
240
|
+
warnings.push(`${flowAt}: collect lists "${field}", which is only taken from the answer to a step that asks it, and no ` +
|
|
241
|
+
"step does. Add it to a step's collect, or set extract: 'anywhere' on the field.");
|
|
242
|
+
}
|
|
243
|
+
}
|
|
261
244
|
pred(flow.while, flowAt, "while");
|
|
262
245
|
toolNames(flow.tools, flowAt);
|
|
263
246
|
flow.instructions?.forEach((ins, i) => pred(ins.if, flowAt, `instructions[${i}].if`));
|
|
@@ -293,13 +276,6 @@ export function validateFlow(input, registries) {
|
|
|
293
276
|
});
|
|
294
277
|
flow.steps.forEach((step, i) => {
|
|
295
278
|
const at = `${flowAt}, step "${step.id}"`;
|
|
296
|
-
// Same reasoning as the trigger above: a step that does none of the five
|
|
297
|
-
// things is a step the run walks straight past, silently. `kind` alone is
|
|
298
|
-
// not enough — the spec form drops it and keeps the body, so what counts
|
|
299
|
-
// is whether the body says what to do.
|
|
300
|
-
if (!STEP_DOES.some((key) => step[key] !== undefined)) {
|
|
301
|
-
throw problem(at, "does nothing", "A step talks (`prompt` / `collect`), says (`say`), acts (`do`), waits (`wait`) or forks (`if`).");
|
|
302
|
-
}
|
|
303
279
|
const thenTo = edge(i, step.then, at, "then");
|
|
304
280
|
edge(i, step.else, at, "else");
|
|
305
281
|
if (step.collect !== undefined || step.prompt !== undefined) {
|
|
@@ -307,8 +283,13 @@ export function validateFlow(input, registries) {
|
|
|
307
283
|
slug(field, at, "collect");
|
|
308
284
|
for (const field of Object.keys(step.ask ?? {}))
|
|
309
285
|
slug(field, at, "ask");
|
|
286
|
+
if (step.question !== undefined && !step.collect?.length)
|
|
287
|
+
throw questionWithoutCollect(at);
|
|
310
288
|
const fields_ = step.collect ?? [];
|
|
311
|
-
if (step.prompt === undefined &&
|
|
289
|
+
if (step.prompt === undefined &&
|
|
290
|
+
step.question === undefined &&
|
|
291
|
+
fields_.length > 0 &&
|
|
292
|
+
fields_.every((f) => !step.ask?.[f] && !fields[f].ask)) {
|
|
312
293
|
warnings.push(`${at}: collects ${fields_.map((f) => `"${f}"`).join(", ")} with no prompt and no ask; the AI has nothing ` +
|
|
313
294
|
"to go on. Add a prompt or an ask per field.");
|
|
314
295
|
}
|
|
@@ -318,6 +299,12 @@ export function validateFlow(input, registries) {
|
|
|
318
299
|
if (branch.when === undefined && branch.if === undefined) {
|
|
319
300
|
throw problem(at, `${where} has neither when nor if`, "Give the branch an AI condition (when) or a code one (if).");
|
|
320
301
|
}
|
|
302
|
+
// No understand call judges a wait, so an AI condition there never fires. A warning, not a throw: the
|
|
303
|
+
// flow still runs as it did, a reply goes to `else`, and editors that offered the branch keep their rows.
|
|
304
|
+
if (branch.when !== undefined && step.wait !== undefined) {
|
|
305
|
+
warnings.push(`${at}: ${where} is a "when" branch on a wait step, which no call judges, so a reply goes to else. ` +
|
|
306
|
+
'Use "if", or move the branch to a talk step.');
|
|
307
|
+
}
|
|
321
308
|
pred(branch.if, at, `${where}.if`);
|
|
322
309
|
edge(i, branch.then, at, `${where}.then`);
|
|
323
310
|
});
|
|
@@ -348,6 +335,232 @@ export function validateFlow(input, registries) {
|
|
|
348
335
|
});
|
|
349
336
|
return { warnings };
|
|
350
337
|
}
|
|
338
|
+
function checkSlug(fields, name, at, where) {
|
|
339
|
+
if (!own(fields, name)) {
|
|
340
|
+
throw problem(at, `unknown field "${name}" in ${where}`, "Add it to the agent's fields or fix the slug.");
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
/**
|
|
344
|
+
* A predicate's names against the registries: the fields `equals` and `known`
|
|
345
|
+
* read, and every other key as one of the agent's conditions. A function is
|
|
346
|
+
* code and passes as is. The agent runs this on its own instructions too.
|
|
347
|
+
*/
|
|
348
|
+
export function checkPred(value, at, where, registries) {
|
|
349
|
+
if (value === undefined || typeof value === "function")
|
|
350
|
+
return;
|
|
351
|
+
const { fields, conditions = {} } = registries;
|
|
352
|
+
for (const [name, arg] of Object.entries(value)) {
|
|
353
|
+
if (name === "equals") {
|
|
354
|
+
if (!isObject(arg)) {
|
|
355
|
+
throw problem(at, `${where}.equals is not an object`, "Write equals as { field: value }.");
|
|
356
|
+
}
|
|
357
|
+
for (const [field, given] of Object.entries(arg)) {
|
|
358
|
+
checkSlug(fields, field, at, `${where}.equals`);
|
|
359
|
+
const def = fields[field];
|
|
360
|
+
if (!matches(def, given)) {
|
|
361
|
+
const { listed, expected, got, fix } = mismatch(def, given);
|
|
362
|
+
throw listed
|
|
363
|
+
? problem(at, `${where}.equals gives "${field}" ${got}, which is not ${expected}`, fix)
|
|
364
|
+
: problem(at, `${where}.equals gives "${field}" ${article(got)} ${got}, but the field is ${expected}`, `Write ${expected}; values are not coerced.`);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
else if (name === "known") {
|
|
369
|
+
if (!Array.isArray(arg))
|
|
370
|
+
throw problem(at, `${where}.known is not a list`, "Write known as [field, ...].");
|
|
371
|
+
for (const field of arg)
|
|
372
|
+
checkSlug(fields, String(field), at, `${where}.known`);
|
|
373
|
+
}
|
|
374
|
+
else if (name === "silenced") {
|
|
375
|
+
if (typeof arg !== "boolean")
|
|
376
|
+
throw problem(at, `${where}.silenced is not a boolean`, "Write true or false.");
|
|
377
|
+
}
|
|
378
|
+
else if (!own(conditions, name)) {
|
|
379
|
+
throw problem(at, `unknown condition "${name}" in ${where}`, `Register it in conditions or use ${BUILT_IN_CONDITIONS.join(", ")}.`);
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
// ── Shape ───────────────────────────────────────────────────────────────
|
|
384
|
+
/**
|
|
385
|
+
* The JSON shape, checked before any name is. Stored rows and generated specs
|
|
386
|
+
* are untrusted: a string where a list belongs used to crash with a raw
|
|
387
|
+
* TypeError naming no flow, or pass and misbehave at run time (`collect:
|
|
388
|
+
* "nome"` read as the fields "n", "o", "m", "e").
|
|
389
|
+
*/
|
|
390
|
+
function checkShape(value) {
|
|
391
|
+
if (!isObject(value))
|
|
392
|
+
throw problem("flow", `is ${show(value)}, not an object`, "Pass the flow itself: { id, name, steps }.");
|
|
393
|
+
const flowAt = typeof value.id === "string" ? `flow "${value.id}"` : "flow";
|
|
394
|
+
if (!Array.isArray(value.steps)) {
|
|
395
|
+
throw problem(flowAt, "has no steps list", "Write steps as a list, even an empty one.");
|
|
396
|
+
}
|
|
397
|
+
text(value, ["description", "anchor"], flowAt);
|
|
398
|
+
for (const key of ["collect", "clearOnStart", "tools"])
|
|
399
|
+
listOf(value[key], key, flowAt, "string");
|
|
400
|
+
oneOf(value.onEnd, "onEnd", ON_END, flowAt);
|
|
401
|
+
predShape(value.while, "while", flowAt);
|
|
402
|
+
instructionsShape(value.instructions, flowAt);
|
|
403
|
+
listOf(value.on, "on", flowAt, "object").forEach((trigger, i) => {
|
|
404
|
+
const at = `${flowAt}, trigger #${i + 1}`;
|
|
405
|
+
if (!isObject(trigger))
|
|
406
|
+
return;
|
|
407
|
+
listOf(trigger.message, "message", at, "string");
|
|
408
|
+
listOf(trigger.mention, "mention", at, "string");
|
|
409
|
+
predShape(trigger.if, "if", at);
|
|
410
|
+
const { repeat } = trigger;
|
|
411
|
+
if (repeat !== undefined && repeat !== "once" && repeat !== "always" && !(isObject(repeat) && typeof repeat.cooldown === "string")) {
|
|
412
|
+
throw problem(at, `repeat is ${show(repeat)}`, 'Use "once", "always" or { cooldown: "24h" }.');
|
|
413
|
+
}
|
|
414
|
+
});
|
|
415
|
+
listOf(value.steps, "steps", flowAt, "object").forEach((step, i) => {
|
|
416
|
+
if (!isObject(step))
|
|
417
|
+
return;
|
|
418
|
+
const at = typeof step.id === "string" ? `${flowAt}, step "${step.id}"` : `${flowAt}, step #${i + 1}`;
|
|
419
|
+
stepShape(step, at);
|
|
420
|
+
});
|
|
421
|
+
}
|
|
422
|
+
/** One step: what it does, and every value the right kind of thing. */
|
|
423
|
+
function stepShape(step, at) {
|
|
424
|
+
// A step that does none of the five things is one the run walks straight
|
|
425
|
+
// past; one that does two runs only the first, and the other never happens.
|
|
426
|
+
const kinds = bodyKinds(step);
|
|
427
|
+
if (kinds.length === 0) {
|
|
428
|
+
throw problem(at, "does nothing", "A step talks (`prompt` / `collect`), says (`say`), acts (`do`), waits (`wait`) or forks (`if`).");
|
|
429
|
+
}
|
|
430
|
+
if (kinds.length > 1) {
|
|
431
|
+
throw problem(at, `mixes ${and(kinds.map((k) => `"${k}"`))}`, "A step does one thing. Split it into one step per kind.");
|
|
432
|
+
}
|
|
433
|
+
// The spec's `kind` must say what the body does; the Runner reads the body.
|
|
434
|
+
if (step.kind !== undefined && step.kind !== kinds[0]) {
|
|
435
|
+
throw problem(at, `has kind ${show(step.kind)}, but its body is a "${kinds[0]}" step`, `Set kind to "${kinds[0]}", or change the body to match.`);
|
|
436
|
+
}
|
|
437
|
+
text(step, ["say", "prompt", "question"], at);
|
|
438
|
+
listOf(step.collect, "collect", at, "string");
|
|
439
|
+
listOf(step.tools, "tools", at, "string");
|
|
440
|
+
if (step.ask !== undefined && !isObject(step.ask)) {
|
|
441
|
+
throw problem(at, `ask is ${show(step.ask)}, not an object`, 'Write ask as { field: "how to ask" }.');
|
|
442
|
+
}
|
|
443
|
+
if (step.with !== undefined && !isObject(step.with)) {
|
|
444
|
+
throw problem(at, `with is ${show(step.with)}, not an object`, "Write with as { parameter: value }.");
|
|
445
|
+
}
|
|
446
|
+
const { maxAsks } = step;
|
|
447
|
+
if (maxAsks !== undefined && !(typeof maxAsks === "number" && Number.isInteger(maxAsks) && maxAsks >= 1)) {
|
|
448
|
+
throw problem(at, `maxAsks is ${show(maxAsks)}, not a whole number of 1 or more`, "Write a number like 3.");
|
|
449
|
+
}
|
|
450
|
+
if (isObject(step.wait) && typeof step.wait.event !== "string") {
|
|
451
|
+
throw problem(at, "wait has no event", 'Write wait: { event: "name" } to wait for an event, or a duration like "1h".');
|
|
452
|
+
}
|
|
453
|
+
predShape(step.if, "if", at);
|
|
454
|
+
for (const key of ["then", "else", "onFail"])
|
|
455
|
+
nextShape(step[key], key, at);
|
|
456
|
+
instructionsShape(step.instructions, at);
|
|
457
|
+
listOf(step.branches, "branches", at, "object").forEach((branch, j) => {
|
|
458
|
+
if (!isObject(branch))
|
|
459
|
+
return;
|
|
460
|
+
const where = `branches[${j}]`;
|
|
461
|
+
if (branch.when !== undefined && typeof branch.when !== "string") {
|
|
462
|
+
throw problem(at, `${where}.when is ${show(branch.when)}, not text`, "Write the condition as one sentence.");
|
|
463
|
+
}
|
|
464
|
+
predShape(branch.if, `${where}.if`, at);
|
|
465
|
+
nextShape(branch.then, `${where}.then`, at);
|
|
466
|
+
});
|
|
467
|
+
}
|
|
468
|
+
/** The kinds a step's body carries, by its keys. A talk step is `collect` with a list, `prompt` with a guideline alone. */
|
|
469
|
+
function bodyKinds(step) {
|
|
470
|
+
const kinds = [];
|
|
471
|
+
if (step.collect !== undefined)
|
|
472
|
+
kinds.push("collect");
|
|
473
|
+
else if (step.prompt !== undefined)
|
|
474
|
+
kinds.push("prompt");
|
|
475
|
+
if (step.say !== undefined)
|
|
476
|
+
kinds.push("say");
|
|
477
|
+
if (step.do !== undefined)
|
|
478
|
+
kinds.push("do");
|
|
479
|
+
if (step.wait !== undefined)
|
|
480
|
+
kinds.push(typeof step.wait === "string" ? "wait" : "waitEvent");
|
|
481
|
+
if (step.if !== undefined)
|
|
482
|
+
kinds.push("if");
|
|
483
|
+
return kinds;
|
|
484
|
+
}
|
|
485
|
+
function instructionsShape(value, at) {
|
|
486
|
+
listOf(value, "instructions", at, "object").forEach((ins, i) => {
|
|
487
|
+
if (!isObject(ins))
|
|
488
|
+
return;
|
|
489
|
+
const where = `instructions[${i}]`;
|
|
490
|
+
oneOf(ins.kind, `${where}.kind`, INSTRUCTION_KINDS, at);
|
|
491
|
+
if (typeof ins.prompt !== "string") {
|
|
492
|
+
throw problem(at, `${where}.prompt is ${show(ins.prompt)}, not text`, "Write the rule as a sentence.");
|
|
493
|
+
}
|
|
494
|
+
if (ins.when !== undefined && typeof ins.when !== "string")
|
|
495
|
+
listOf(ins.when, `${where}.when`, at, "string");
|
|
496
|
+
predShape(ins.if, `${where}.if`, at);
|
|
497
|
+
});
|
|
498
|
+
}
|
|
499
|
+
/** A step id, `"end"`, `{ step, clear? }` or `{ flow, input? }`. */
|
|
500
|
+
function nextShape(value, where, at) {
|
|
501
|
+
if (value === undefined || typeof value === "string")
|
|
502
|
+
return;
|
|
503
|
+
if (isObject(value) && (typeof value.step === "string" || typeof value.flow === "string")) {
|
|
504
|
+
listOf(value.clear, `${where}.clear`, at, "string");
|
|
505
|
+
return;
|
|
506
|
+
}
|
|
507
|
+
throw problem(at, `${where} is ${show(value)}, not a step id or a target`, 'Write a step id, "end", { step: "id" } or { flow: "id" }.');
|
|
508
|
+
}
|
|
509
|
+
/** A condition object, or code on a typed flow. */
|
|
510
|
+
function predShape(value, where, at) {
|
|
511
|
+
if (value === undefined || typeof value === "function" || isObject(value))
|
|
512
|
+
return;
|
|
513
|
+
throw problem(at, `${where} is ${show(value)}, not a condition`, 'Write it as an object, e.g. { known: ["nome"] }.');
|
|
514
|
+
}
|
|
515
|
+
/** Each named key, when set, must be text. */
|
|
516
|
+
function text(owner, keys, at) {
|
|
517
|
+
for (const key of keys) {
|
|
518
|
+
const value = owner[key];
|
|
519
|
+
if (value !== undefined && typeof value !== "string") {
|
|
520
|
+
throw problem(at, `${key} is ${show(value)}, not text`, `Write ${key} as a string.`);
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
function oneOf(value, where, allowed, at) {
|
|
525
|
+
if (value === undefined || (typeof value === "string" && allowed.includes(value)))
|
|
526
|
+
return;
|
|
527
|
+
throw problem(at, `${where} is ${show(value)}, which is not one of ${allowed.map((v) => `"${v}"`).join(", ")}`, "Use one of them.");
|
|
528
|
+
}
|
|
529
|
+
/** A list whose items are all strings or all objects; absent reads as empty. */
|
|
530
|
+
function listOf(value, where, at, item) {
|
|
531
|
+
if (value === undefined)
|
|
532
|
+
return [];
|
|
533
|
+
if (!Array.isArray(value)) {
|
|
534
|
+
const example = item === "string" && typeof value === "string" ? `${where}: ${JSON.stringify([value])}` : `${where} as a list`;
|
|
535
|
+
throw problem(at, `${where} is ${show(value)}, not a list`, `Write ${example}.`);
|
|
536
|
+
}
|
|
537
|
+
value.forEach((entry, i) => {
|
|
538
|
+
if (item === "string" ? typeof entry !== "string" : !isObject(entry)) {
|
|
539
|
+
throw problem(at, `${where}[${i}] is ${show(entry)}, not ${item === "string" ? "text" : "an object"}`, `Write each entry of ${where} as ${item === "string" ? "a string" : "an object"}.`);
|
|
540
|
+
}
|
|
541
|
+
});
|
|
542
|
+
return value;
|
|
543
|
+
}
|
|
544
|
+
/** A plain object: not null, not a list, not a function. */
|
|
545
|
+
function isObject(value) {
|
|
546
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
547
|
+
}
|
|
548
|
+
/** A wrong value as an error names it: short scalars verbatim, anything else by kind. */
|
|
549
|
+
function show(value) {
|
|
550
|
+
if (typeof value === "string")
|
|
551
|
+
return JSON.stringify(value.length > 40 ? `${value.slice(0, 37)}...` : value);
|
|
552
|
+
if (typeof value === "number" || typeof value === "boolean")
|
|
553
|
+
return String(value);
|
|
554
|
+
if (value === undefined)
|
|
555
|
+
return "missing";
|
|
556
|
+
if (value === null)
|
|
557
|
+
return "null";
|
|
558
|
+
return Array.isArray(value) ? "a list" : typeof value === "function" ? "a function" : "an object";
|
|
559
|
+
}
|
|
560
|
+
/** `"a"`, `"a" and "b"`, `"a", "b" and "c"`. */
|
|
561
|
+
function and(items) {
|
|
562
|
+
return items.length < 2 ? items.join("") : `${items.slice(0, -1).join(", ")} and ${items.at(-1)}`;
|
|
563
|
+
}
|
|
351
564
|
function matchesParam(def, value) {
|
|
352
565
|
if (def.type === "array")
|
|
353
566
|
return Array.isArray(value) && value.every((item) => matches(def.items, item));
|
|
@@ -378,10 +591,10 @@ function mismatch(def, value) {
|
|
|
378
591
|
const items = def.type === "array" && Array.isArray(value) ? value : [value];
|
|
379
592
|
const off = allowed ? items.findIndex((item) => matches(typeOnly, item) && !matches(scalar, item)) : -1;
|
|
380
593
|
if (!allowed || off === -1) {
|
|
381
|
-
return { expected: describeDef(def), got: describe(value), fix: "Values are not coerced; write the right type." };
|
|
594
|
+
return { listed: false, expected: describeDef(def), got: describe(value), fix: "Values are not coerced; write the right type." };
|
|
382
595
|
}
|
|
383
596
|
const list = (v) => JSON.stringify(v);
|
|
384
|
-
return { expected: `one of ${allowed.map(list).join(", ")}`, got: list(items[off]), fix: "Use one of the listed values." };
|
|
597
|
+
return { listed: true, expected: `one of ${allowed.map(list).join(", ")}`, got: list(items[off]), fix: "Use one of the listed values." };
|
|
385
598
|
}
|
|
386
599
|
function describe(value) {
|
|
387
600
|
return Array.isArray(value) ? "list" : value === null ? "null" : typeof value;
|
|
@@ -449,6 +662,8 @@ export function flowSpecSchema(registries) {
|
|
|
449
662
|
: undefined,
|
|
450
663
|
]);
|
|
451
664
|
const branches = orNull(list(union([closed({ when: STRING, then: next }), closed({ if: condition, then: next })]), "Exits judged while the step asks"));
|
|
665
|
+
// No understand call judges a wait, so its branches are code only.
|
|
666
|
+
const waitBranches = orNull(list(closed({ if: condition, then: next }), "Exits checked by code when the lead replies before the wait ends"));
|
|
452
667
|
const stepBase = { id: STRING, label: orNull(STRING), then: nextOrNull };
|
|
453
668
|
const step = union([
|
|
454
669
|
closed({ ...stepBase, kind: enumOf(["prompt"]), prompt: { type: "string", description: "Guideline for the AI's next message" }, branches }),
|
|
@@ -458,6 +673,7 @@ export function flowSpecSchema(registries) {
|
|
|
458
673
|
kind: enumOf(["collect"]),
|
|
459
674
|
collect: { ...slugList, description: "Fields the AI asks for until they are known" },
|
|
460
675
|
prompt: orNull(STRING),
|
|
676
|
+
question: orNull({ type: "string", description: "A fixed first question, sent word for word; later asks are the AI's" }),
|
|
461
677
|
maxAsks: orNull({ ...INTEGER, description: "Times a field may be asked before it is skipped; default 3" }),
|
|
462
678
|
branches,
|
|
463
679
|
}),
|
|
@@ -475,7 +691,7 @@ export function flowSpecSchema(registries) {
|
|
|
475
691
|
wait: { ...duration, description: "Park this long; then = time passed, else = the lead replied" },
|
|
476
692
|
businessHours: orNull(BOOLEAN),
|
|
477
693
|
else: nextOrNull,
|
|
478
|
-
branches,
|
|
694
|
+
branches: waitBranches,
|
|
479
695
|
}),
|
|
480
696
|
eventNames.length
|
|
481
697
|
? closed({
|
|
@@ -500,9 +716,10 @@ export function flowSpecSchema(registries) {
|
|
|
500
716
|
on: orNull(list(trigger, "What starts a run; null = started by hand")),
|
|
501
717
|
anchor: orNull({ type: "string", description: "'session' (default) or a host anchor such as 'lead'" }),
|
|
502
718
|
while: orNull({ ...condition, description: "The run ends when this stops holding" }),
|
|
719
|
+
collect: slugList && orNull({ ...slugList, description: "The data this flow needs; its steps ask for it in order, and any of it the lead gives is noted" }),
|
|
503
720
|
clearOnStart: slugList && orNull({ ...slugList, description: "Fields to forget when a run starts" }),
|
|
504
721
|
steps: list(step, "In order; a run moves to the next step unless `then` says otherwise"),
|
|
505
|
-
onEnd: orNull(enumOf(["end", "stay", "reset"], "After the last step: end the run, stay on it, or reset to the first")),
|
|
722
|
+
onEnd: orNull(enumOf(["end", "stay", "reset"], "After the last step: end the run, stay on the last talk step it took answering every message, or reset to the first")),
|
|
506
723
|
instructions: orNull(list(instruction, "Rules that apply only inside this flow")),
|
|
507
724
|
});
|
|
508
725
|
}
|
|
@@ -543,6 +760,9 @@ function orNull(schema) {
|
|
|
543
760
|
return typeof schema.type === "string" ? { ...schema, type: [schema.type, "null"] } : { anyOf: [schema, NULL] };
|
|
544
761
|
}
|
|
545
762
|
// ── Shared helpers ──────────────────────────────────────────────────────
|
|
763
|
+
function questionWithoutCollect(at) {
|
|
764
|
+
return problem(at, "has a question but collects nothing", "A fixed question asks for fields: add collect, or send the text with a say step.");
|
|
765
|
+
}
|
|
546
766
|
function problem(at, what, fix) {
|
|
547
767
|
return new FlowConfigurationError(`[FlowConfigurationError] ${at}: ${what}. ${fix}`);
|
|
548
768
|
}
|