@sapiom/agent
Advanced tools
+12
-0
| # @sapiom/orchestration | ||
| ## 0.9.0 | ||
| ### Minor Changes | ||
| - c8072cd: Make the agent input contract first-class: `defineAgent({ inputSchema })`. | ||
| `defineAgent` now accepts an optional agent-level `inputSchema` — one obvious place to declare "what this agent takes". When the entry step declares no `inputSchema` of its own, `defineAgent` folds the agent-level schema onto it, so the built manifest's entry step carries the JSON Schema (and the dashboard renders its fields) without any downstream change. Declaring a _different_ schema at both the agent level and on the entry step is now a build error with a clear message; declaring the identical schema object in both places is allowed. | ||
| The schema is typed `ZodType<TInput>`, so the `defineAgent<TInput>` generic (hence the `run(def, input)` call site) is inferred from the same runtime schema that becomes the contract — the TS annotation and the runtime validation can no longer drift apart (SAP-2226). | ||
| Existing agents that declare the schema on the entry step keep working unchanged. | ||
| ## 0.8.0 | ||
@@ -4,0 +16,0 @@ |
@@ -0,1 +1,2 @@ | ||
| import type { ZodType } from 'zod/v4'; | ||
| import type { StepDefinition } from './step.js'; | ||
@@ -7,2 +8,3 @@ export declare const AGENT_DEFINITION_BRAND: unique symbol; | ||
| readonly entry: string; | ||
| readonly inputSchema?: ZodType<TInput>; | ||
| readonly steps: Readonly<Record<string, StepDefinition<TShared>>>; | ||
@@ -9,0 +11,0 @@ readonly __inputType?: TInput; |
+13
-0
@@ -38,2 +38,15 @@ "use strict"; | ||
| } | ||
| if (def.inputSchema) { | ||
| const entryStep = def.steps[def.entry]; | ||
| if (entryStep.inputSchema && entryStep.inputSchema !== def.inputSchema) { | ||
| throw new Error(`Agent '${def.name}' declares a different inputSchema at the agent level and on its entry step '${def.entry}'. ` + | ||
| `Declare the input contract once and reference that single schema object in both places (or remove one).`); | ||
| } | ||
| if (!entryStep.inputSchema) { | ||
| def.steps = { | ||
| ...def.steps, | ||
| [def.entry]: { ...entryStep, inputSchema: def.inputSchema }, | ||
| }; | ||
| } | ||
| } | ||
| Object.defineProperty(def, exports.AGENT_DEFINITION_BRAND, { | ||
@@ -40,0 +53,0 @@ value: 1, |
@@ -0,1 +1,2 @@ | ||
| import type { ZodType } from 'zod/v4'; | ||
| import type { StepDefinition } from './step.js'; | ||
@@ -7,2 +8,3 @@ export declare const AGENT_DEFINITION_BRAND: unique symbol; | ||
| readonly entry: string; | ||
| readonly inputSchema?: ZodType<TInput>; | ||
| readonly steps: Readonly<Record<string, StepDefinition<TShared>>>; | ||
@@ -9,0 +11,0 @@ readonly __inputType?: TInput; |
+13
-0
@@ -32,2 +32,15 @@ import { UnknownStepError } from './errors.js'; | ||
| } | ||
| if (def.inputSchema) { | ||
| const entryStep = def.steps[def.entry]; | ||
| if (entryStep.inputSchema && entryStep.inputSchema !== def.inputSchema) { | ||
| throw new Error(`Agent '${def.name}' declares a different inputSchema at the agent level and on its entry step '${def.entry}'. ` + | ||
| `Declare the input contract once and reference that single schema object in both places (or remove one).`); | ||
| } | ||
| if (!entryStep.inputSchema) { | ||
| def.steps = { | ||
| ...def.steps, | ||
| [def.entry]: { ...entryStep, inputSchema: def.inputSchema }, | ||
| }; | ||
| } | ||
| } | ||
| Object.defineProperty(def, AGENT_DEFINITION_BRAND, { | ||
@@ -34,0 +47,0 @@ value: 1, |
+1
-1
| { | ||
| "name": "@sapiom/agent", | ||
| "version": "0.8.0", | ||
| "version": "0.9.0", | ||
| "description": "Versioned public contract for authoring Sapiom agents: types, directive constructors/guards, defineAgent, defineStep, InMemoryContextStore. Shared by customer agent definitions, the sandbox step-runner, and the engine.", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
+29
-0
@@ -59,2 +59,31 @@ # @sapiom/agent | ||
| ## The entry input contract | ||
| A step's `inputSchema` (a zod schema, imported from `zod/v4`) types and validates that | ||
| step's input. The **entry step's `inputSchema` is special — it is the agent's public API**: | ||
| the dashboard Run form, the trigger snippet, and the engine's pre-dispatch validation are | ||
| all derived from it. Declare it on the entry step, with a `.default()` on each field so a | ||
| zero-input run still validates: | ||
| ```ts | ||
| import { defineStep, terminate } from "@sapiom/agent"; | ||
| import { z } from "zod/v4"; | ||
| const start = defineStep({ | ||
| name: "start", | ||
| next: [], | ||
| terminal: true, | ||
| inputSchema: z.object({ | ||
| repo: z.string().default("sapiom/sapiom"), | ||
| }), | ||
| // `input` is inferred + validated from inputSchema: { repo: string } | ||
| async run(input) { | ||
| return terminate({ scanned: input.repo }); | ||
| }, | ||
| }); | ||
| ``` | ||
| `inputSchema` on a non-entry step types that step's inbound payload the same way — including | ||
| a **resumed** step's signal payload, shown next. | ||
| ## Pausing on a long-running capability | ||
@@ -61,0 +90,0 @@ |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
196956
1.77%1662
1.84%160
22.14%