@sapiom/agent-core
Advanced tools
| export declare const VERSION_FALLBACK: { | ||
| readonly agent: "0.9.0"; | ||
| readonly tools: "0.24.0"; | ||
| }; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.VERSION_FALLBACK = void 0; | ||
| exports.VERSION_FALLBACK = { | ||
| agent: "0.9.0", | ||
| tools: "0.24.0", | ||
| }; |
| export declare const VERSION_FALLBACK: { | ||
| readonly agent: "0.9.0"; | ||
| readonly tools: "0.24.0"; | ||
| }; |
| export const VERSION_FALLBACK = { | ||
| agent: "0.9.0", | ||
| tools: "0.24.0", | ||
| }; |
+8
-0
| # @sapiom/orchestration-core | ||
| ## 0.9.13 | ||
| ### Patch Changes | ||
| - Updated dependencies [c8072cd] | ||
| - @sapiom/agent@0.9.0 | ||
| - @sapiom/agent-runtime@0.4.3 | ||
| ## 0.9.12 | ||
@@ -4,0 +12,0 @@ |
@@ -11,2 +11,9 @@ export interface CheckOptions { | ||
| } | ||
| export interface EntryContractManifest { | ||
| entry: string; | ||
| steps: Record<string, { | ||
| inputSchema: Record<string, unknown> | null; | ||
| } | undefined>; | ||
| } | ||
| export declare function entryInputSchemaWarning(manifest: EntryContractManifest): string | null; | ||
| export declare function check(opts: CheckOptions): Promise<CheckResult>; |
+11
-0
@@ -39,2 +39,3 @@ "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| exports.entryInputSchemaWarning = entryInputSchemaWarning; | ||
| exports.check = check; | ||
@@ -69,2 +70,9 @@ const node_child_process_1 = require("node:child_process"); | ||
| const LOCAL_SDK_VERSION = '0.0.0-local'; | ||
| function entryInputSchemaWarning(manifest) { | ||
| const entryStep = manifest.steps[manifest.entry]; | ||
| if (entryStep && entryStep.inputSchema === null) { | ||
| return `entry step '${manifest.entry}' declares no inputSchema — the dashboard Run form, the trigger snippet, and engine validation all read it as the agent's public input contract. Declare one with zod (from 'zod/v4') so callers know what the agent takes.`; | ||
| } | ||
| return null; | ||
| } | ||
| async function check(opts) { | ||
@@ -151,2 +159,5 @@ const { sourceDir } = opts; | ||
| } | ||
| const entryWarning = entryInputSchemaWarning(manifest); | ||
| if (entryWarning) | ||
| warnings.push(entryWarning); | ||
| const steps = manifest.steps; | ||
@@ -153,0 +164,0 @@ const stepCount = Array.isArray(steps) ? steps.length : Object.keys(steps ?? {}).length; |
@@ -17,2 +17,3 @@ "use strict"; | ||
| const errors_js_1 = require("./errors.js"); | ||
| const version_fallback_generated_js_1 = require("./version-fallback.generated.js"); | ||
| function resolveModuleDir() { | ||
@@ -39,6 +40,2 @@ if (typeof __dirname !== "undefined") | ||
| const DEFAULT_REGISTRY = "https://registry.npmjs.org"; | ||
| const VERSION_FALLBACK = { | ||
| agent: "0.8.0", | ||
| tools: "0.24.0", | ||
| }; | ||
| const ZOD_VERSION = "4.1.12"; | ||
@@ -73,4 +70,4 @@ function registryFor(pkg) { | ||
| return { | ||
| agent: agent ?? VERSION_FALLBACK.agent, | ||
| tools: tools ?? VERSION_FALLBACK.tools, | ||
| agent: agent ?? version_fallback_generated_js_1.VERSION_FALLBACK.agent, | ||
| tools: tools ?? version_fallback_generated_js_1.VERSION_FALLBACK.tools, | ||
| zod: ZOD_VERSION, | ||
@@ -77,0 +74,0 @@ }; |
@@ -11,2 +11,9 @@ export interface CheckOptions { | ||
| } | ||
| export interface EntryContractManifest { | ||
| entry: string; | ||
| steps: Record<string, { | ||
| inputSchema: Record<string, unknown> | null; | ||
| } | undefined>; | ||
| } | ||
| export declare function entryInputSchemaWarning(manifest: EntryContractManifest): string | null; | ||
| export declare function check(opts: CheckOptions): Promise<CheckResult>; |
+10
-0
@@ -29,2 +29,9 @@ import { execFileSync } from 'node:child_process'; | ||
| const LOCAL_SDK_VERSION = '0.0.0-local'; | ||
| export function entryInputSchemaWarning(manifest) { | ||
| const entryStep = manifest.steps[manifest.entry]; | ||
| if (entryStep && entryStep.inputSchema === null) { | ||
| return `entry step '${manifest.entry}' declares no inputSchema — the dashboard Run form, the trigger snippet, and engine validation all read it as the agent's public input contract. Declare one with zod (from 'zod/v4') so callers know what the agent takes.`; | ||
| } | ||
| return null; | ||
| } | ||
| export async function check(opts) { | ||
@@ -111,2 +118,5 @@ const { sourceDir } = opts; | ||
| } | ||
| const entryWarning = entryInputSchemaWarning(manifest); | ||
| if (entryWarning) | ||
| warnings.push(entryWarning); | ||
| const steps = manifest.steps; | ||
@@ -113,0 +123,0 @@ const stepCount = Array.isArray(steps) ? steps.length : Object.keys(steps ?? {}).length; |
@@ -6,2 +6,3 @@ import { execFileSync } from "node:child_process"; | ||
| import { AgentOperationError } from "./errors.js"; | ||
| import { VERSION_FALLBACK } from "./version-fallback.generated.js"; | ||
| function resolveModuleDir() { | ||
@@ -28,6 +29,2 @@ if (typeof __dirname !== "undefined") | ||
| const DEFAULT_REGISTRY = "https://registry.npmjs.org"; | ||
| const VERSION_FALLBACK = { | ||
| agent: "0.8.0", | ||
| tools: "0.24.0", | ||
| }; | ||
| const ZOD_VERSION = "4.1.12"; | ||
@@ -34,0 +31,0 @@ export function registryFor(pkg) { |
+4
-3
| { | ||
| "name": "@sapiom/agent-core", | ||
| "version": "0.9.12", | ||
| "version": "0.9.13", | ||
| "description": "Pure, stateless core functions for scaffolding, validating, and operating Sapiom agents — shared by the CLI and MCP packages.", | ||
@@ -40,4 +40,4 @@ "license": "MIT", | ||
| "esbuild": "^0.28.1", | ||
| "@sapiom/agent": "^0.8.0", | ||
| "@sapiom/agent-runtime": "^0.4.2", | ||
| "@sapiom/agent": "^0.9.0", | ||
| "@sapiom/agent-runtime": "^0.4.3", | ||
| "@sapiom/analytics-core": "^0.2.1", | ||
@@ -64,2 +64,3 @@ "@sapiom/tools": "^0.24.0" | ||
| "scripts": { | ||
| "prebuild": "node scripts/gen-version-fallback.mjs", | ||
| "build": "pnpm run build:cjs && pnpm run build:esm && pnpm run build:esm-pkg", | ||
@@ -66,0 +67,0 @@ "build:cjs": "tsc --project tsconfig.cjs.json", |
@@ -114,3 +114,3 @@ --- | ||
| | `pause` | `{ signal, resumeStep }` | no | Required when returning `pauseUntilSignal(...)` | | ||
| | `inputSchema` | `ZodType` | no | Zod schema validating this step's input | | ||
| | `inputSchema` | `ZodType` | no | Zod schema validating this step's input. On the **entry** step it is the agent's public API (see [The Entry Input Contract](#the-entry-input-contract--your-agents-public-api)) | | ||
| | `timeoutMs` | `number` | no | Per-step timeout; no automatic retry cap | | ||
@@ -165,2 +165,51 @@ | `run(input, ctx)` | `async function` | yes | Returns a directive | | ||
| ## The Entry Input Contract — your agent's public API | ||
| The **entry step's `inputSchema` is the agent's public API** — the one schema the platform | ||
| reads to describe what the agent accepts. It drives every input surface: | ||
| - the **dashboard Run form** (fields, types, and defaults are generated from it) and the | ||
| copy-paste **trigger snippet**; | ||
| - **engine-side validation** — the engine parses each run's input against it before the | ||
| entry step dispatches, so a malformed payload is rejected up front, not mid-run. | ||
| Declare it on the entry step even when the agent looks input-free: an entry step with **no** | ||
| `inputSchema` tells the platform the agent takes *no* input, so the dashboard renders an | ||
| empty Run form and callers have nothing to fill in (and `check` warns). Give every field a | ||
| `.default()` so a zero-input run — the dashboard "Run" button with an empty form — still | ||
| validates: | ||
| ```typescript | ||
| import { defineAgent, defineStep, terminate } from "@sapiom/agent"; | ||
| import { z } from "zod/v4"; | ||
| const start = defineStep({ | ||
| name: "start", | ||
| next: [], | ||
| terminal: true, | ||
| // This schema IS the agent's public input contract. A `.default()` on every field | ||
| // means a run with `{}` (the empty Run form) still validates. | ||
| inputSchema: z.object({ | ||
| repo: z.string().default("sapiom/sapiom"), | ||
| window: z.enum(["day", "week", "month"]).default("week"), | ||
| }), | ||
| // `input` is inferred + validated from inputSchema — no annotation needed: | ||
| // { repo: string; window: "day" | "week" | "month" } | ||
| async run(input, ctx) { | ||
| ctx.logger.info("scanning", { repo: input.repo, window: input.window }); | ||
| return terminate({ scanned: input.repo }); | ||
| }, | ||
| }); | ||
| export const agent = defineAgent({ | ||
| name: "repo-scan", | ||
| entry: "start", | ||
| steps: { start }, | ||
| }); | ||
| ``` | ||
| `inputSchema` on a **non-entry** step still validates that step's inbound `goto` payload (or | ||
| a resumed signal payload) — but only the **entry** step's schema is read as the agent's | ||
| public contract by the dashboard, trigger, and engine. | ||
| ## Cross-Step State with `ctx.shared` | ||
@@ -167,0 +216,0 @@ |
@@ -114,3 +114,3 @@ --- | ||
| | `pause` | `{ signal, resumeStep }` | no | Required when returning `pauseUntilSignal(...)` | | ||
| | `inputSchema` | `ZodType` | no | Zod schema validating this step's input | | ||
| | `inputSchema` | `ZodType` | no | Zod schema validating this step's input. On the **entry** step it is the agent's public API (see [The Entry Input Contract](#the-entry-input-contract--your-agents-public-api)) | | ||
| | `timeoutMs` | `number` | no | Per-step timeout; no automatic retry cap | | ||
@@ -165,2 +165,51 @@ | `run(input, ctx)` | `async function` | yes | Returns a directive | | ||
| ## The Entry Input Contract — your agent's public API | ||
| The **entry step's `inputSchema` is the agent's public API** — the one schema the platform | ||
| reads to describe what the agent accepts. It drives every input surface: | ||
| - the **dashboard Run form** (fields, types, and defaults are generated from it) and the | ||
| copy-paste **trigger snippet**; | ||
| - **engine-side validation** — the engine parses each run's input against it before the | ||
| entry step dispatches, so a malformed payload is rejected up front, not mid-run. | ||
| Declare it on the entry step even when the agent looks input-free: an entry step with **no** | ||
| `inputSchema` tells the platform the agent takes *no* input, so the dashboard renders an | ||
| empty Run form and callers have nothing to fill in (and `check` warns). Give every field a | ||
| `.default()` so a zero-input run — the dashboard "Run" button with an empty form — still | ||
| validates: | ||
| ```typescript | ||
| import { defineAgent, defineStep, terminate } from "@sapiom/agent"; | ||
| import { z } from "zod/v4"; | ||
| const start = defineStep({ | ||
| name: "start", | ||
| next: [], | ||
| terminal: true, | ||
| // This schema IS the agent's public input contract. A `.default()` on every field | ||
| // means a run with `{}` (the empty Run form) still validates. | ||
| inputSchema: z.object({ | ||
| repo: z.string().default("sapiom/sapiom"), | ||
| window: z.enum(["day", "week", "month"]).default("week"), | ||
| }), | ||
| // `input` is inferred + validated from inputSchema — no annotation needed: | ||
| // { repo: string; window: "day" | "week" | "month" } | ||
| async run(input, ctx) { | ||
| ctx.logger.info("scanning", { repo: input.repo, window: input.window }); | ||
| return terminate({ scanned: input.repo }); | ||
| }, | ||
| }); | ||
| export const agent = defineAgent({ | ||
| name: "repo-scan", | ||
| entry: "start", | ||
| steps: { start }, | ||
| }); | ||
| ``` | ||
| `inputSchema` on a **non-entry** step still validates that step's inbound `goto` payload (or | ||
| a resumed signal payload) — but only the **entry** step's schema is read as the agent's | ||
| public contract by the dashboard, trigger, and engine. | ||
| ## Cross-Step State with `ctx.shared` | ||
@@ -167,0 +216,0 @@ |
@@ -12,2 +12,26 @@ # Working in this agent project | ||
| ## The entry input contract | ||
| The **entry step's `inputSchema` is this agent's public API** — the dashboard Run form, the trigger snippet, and engine-side validation are all generated from it. Declare it (with `zod` from `zod/v4`) even when the agent looks input-free, and give every field a `.default()` so a zero-input run (the empty Run form) still validates. An entry step with no `inputSchema` tells the platform the agent takes no input — the Run form renders empty and `check` warns. | ||
| ```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"), | ||
| window: z.enum(["day", "week", "month"]).default("week"), | ||
| }), | ||
| async run(input, ctx) { // input: { repo: string; window: "day" | "week" | "month" } | ||
| return terminate({ scanned: input.repo }); | ||
| }, | ||
| }); | ||
| ``` | ||
| `inputSchema` on a non-entry step validates that step's inbound payload — but only the entry step's schema is read as the agent's public contract. | ||
| ## Validating | ||
@@ -14,0 +38,0 @@ |
@@ -10,4 +10,22 @@ import { | ||
| import { CODING_RESULT_SIGNAL, type CodingResultPayload } from "@sapiom/tools"; | ||
| import { z } from "zod/v4"; | ||
| /** | ||
| * The entry contract — your agent's PUBLIC API. This schema is what the Sapiom | ||
| * dashboard's "Run once" form renders its fields from (one labelled field per | ||
| * property, using its `.describe(...)`), and every run's input is validated | ||
| * against it before `prepare` runs. The `.default(...)` is the same value the | ||
| * code sees on a zero-input run, so the template runs as-is and stays editable. | ||
| */ | ||
| const entryInput = z.object({ | ||
| task: z | ||
| .string() | ||
| .default( | ||
| "Make a small, self-contained change to this repository and commit it.", | ||
| ) | ||
| .describe("What the coding agent should do in the cloned repository."), | ||
| }); | ||
| type EntryInput = z.infer<typeof entryInput>; | ||
| /** | ||
| * __PROJECT_NAME__ — a non-blocking coding-agent workflow. | ||
@@ -34,2 +52,4 @@ * | ||
| cloneUrl: string; | ||
| /** The coding instruction, stashed by `prepare` so `kickoff` can launch it. */ | ||
| task: string; | ||
| } | ||
@@ -41,3 +61,5 @@ | ||
| next: ["kickoff"], | ||
| async run(_input, ctx) { | ||
| inputSchema: entryInput, | ||
| async run(input: EntryInput, ctx) { | ||
| ctx.shared.set("task", input.task); | ||
| const existing = await ctx.sapiom.repositories.list(); | ||
@@ -64,3 +86,3 @@ const repo = | ||
| const run = await ctx.sapiom.models.coding.launch({ | ||
| task: "Make a small, self-contained change to this repository and commit it.", | ||
| task: ctx.shared.get("task") as string, | ||
| gitRepository: repo, // auto-cloned into the sandbox at /workspace/<slug> | ||
@@ -109,3 +131,3 @@ }); | ||
| export const agent = defineAgent<unknown, Shared>({ | ||
| export const agent = defineAgent<EntryInput, Shared>({ | ||
| name: "__PROJECT_NAME__", | ||
@@ -112,0 +134,0 @@ entry: "prepare", |
@@ -114,3 +114,3 @@ --- | ||
| | `pause` | `{ signal, resumeStep }` | no | Required when returning `pauseUntilSignal(...)` | | ||
| | `inputSchema` | `ZodType` | no | Zod schema validating this step's input | | ||
| | `inputSchema` | `ZodType` | no | Zod schema validating this step's input. On the **entry** step it is the agent's public API (see [The Entry Input Contract](#the-entry-input-contract--your-agents-public-api)) | | ||
| | `timeoutMs` | `number` | no | Per-step timeout; no automatic retry cap | | ||
@@ -165,2 +165,51 @@ | `run(input, ctx)` | `async function` | yes | Returns a directive | | ||
| ## The Entry Input Contract — your agent's public API | ||
| The **entry step's `inputSchema` is the agent's public API** — the one schema the platform | ||
| reads to describe what the agent accepts. It drives every input surface: | ||
| - the **dashboard Run form** (fields, types, and defaults are generated from it) and the | ||
| copy-paste **trigger snippet**; | ||
| - **engine-side validation** — the engine parses each run's input against it before the | ||
| entry step dispatches, so a malformed payload is rejected up front, not mid-run. | ||
| Declare it on the entry step even when the agent looks input-free: an entry step with **no** | ||
| `inputSchema` tells the platform the agent takes *no* input, so the dashboard renders an | ||
| empty Run form and callers have nothing to fill in (and `check` warns). Give every field a | ||
| `.default()` so a zero-input run — the dashboard "Run" button with an empty form — still | ||
| validates: | ||
| ```typescript | ||
| import { defineAgent, defineStep, terminate } from "@sapiom/agent"; | ||
| import { z } from "zod/v4"; | ||
| const start = defineStep({ | ||
| name: "start", | ||
| next: [], | ||
| terminal: true, | ||
| // This schema IS the agent's public input contract. A `.default()` on every field | ||
| // means a run with `{}` (the empty Run form) still validates. | ||
| inputSchema: z.object({ | ||
| repo: z.string().default("sapiom/sapiom"), | ||
| window: z.enum(["day", "week", "month"]).default("week"), | ||
| }), | ||
| // `input` is inferred + validated from inputSchema — no annotation needed: | ||
| // { repo: string; window: "day" | "week" | "month" } | ||
| async run(input, ctx) { | ||
| ctx.logger.info("scanning", { repo: input.repo, window: input.window }); | ||
| return terminate({ scanned: input.repo }); | ||
| }, | ||
| }); | ||
| export const agent = defineAgent({ | ||
| name: "repo-scan", | ||
| entry: "start", | ||
| steps: { start }, | ||
| }); | ||
| ``` | ||
| `inputSchema` on a **non-entry** step still validates that step's inbound `goto` payload (or | ||
| a resumed signal payload) — but only the **entry** step's schema is read as the agent's | ||
| public contract by the dashboard, trigger, and engine. | ||
| ## Cross-Step State with `ctx.shared` | ||
@@ -167,0 +216,0 @@ |
@@ -12,2 +12,26 @@ # Working in this agent project | ||
| ## The entry input contract | ||
| The **entry step's `inputSchema` is this agent's public API** — the dashboard Run form, the trigger snippet, and engine-side validation are all generated from it. Declare it (with `zod` from `zod/v4`) even when the agent looks input-free, and give every field a `.default()` so a zero-input run (the empty Run form) still validates. An entry step with no `inputSchema` tells the platform the agent takes no input — the Run form renders empty and `check` warns. | ||
| ```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"), | ||
| window: z.enum(["day", "week", "month"]).default("week"), | ||
| }), | ||
| async run(input, ctx) { // input: { repo: string; window: "day" | "week" | "month" } | ||
| return terminate({ scanned: input.repo }); | ||
| }, | ||
| }); | ||
| ``` | ||
| `inputSchema` on a non-entry step validates that step's inbound payload — but only the entry step's schema is read as the agent's public contract. | ||
| ## Validating | ||
@@ -14,0 +38,0 @@ |
| import { defineAgent, defineStep, goto, terminate } from '@sapiom/agent'; | ||
| import { z } from 'zod/v4'; | ||
| /** | ||
| * The entry contract — your agent's PUBLIC API. This schema is what the Sapiom | ||
| * dashboard's "Run once" form renders its fields from (one labelled field per | ||
| * property, using its `.describe(...)`), and every run's input is validated | ||
| * against it before `start` runs. Give a field a `.default(...)` so a zero-input | ||
| * run still works and the declared default is the same value the code sees. | ||
| * Replace `name` with your agent's real input. | ||
| */ | ||
| const entryInput = z.object({ | ||
| name: z | ||
| .string() | ||
| .default('world') | ||
| .describe('Who to greet — the sample field this scaffold ships with.'), | ||
| }); | ||
| const start = defineStep({ | ||
| name: 'start', | ||
| next: ['finish'], | ||
| inputSchema: entryInput, | ||
| async run(input, ctx) { | ||
| ctx.logger.info('starting', { input }); | ||
| // Sapiom capabilities: ctx.sapiom.sandboxes.create(), ctx.sapiom.repositories.create() | ||
| return goto('finish', { greeting: 'hello from Sapiom' }); | ||
| return goto('finish', { greeting: `hello from Sapiom, ${input.name}` }); | ||
| }, | ||
@@ -11,0 +28,0 @@ }); |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
462200
2.92%126
3.28%5410
1.6%- Removed
Updated
Updated