🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

@sapiom/agent-core

Package Overview
Dependencies
Maintainers
3
Versions
22
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@sapiom/agent-core - npm Package Compare versions

Comparing version
0.9.12
to
0.9.13
+4
dist/cjs/version-fallback.generated.d.ts
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>;

@@ -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;

+3
-6

@@ -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>;

@@ -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) {

{
"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