@noetic-tools/types 3.1.0 → 3.2.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/dist/index.d.ts CHANGED
@@ -23,6 +23,7 @@ export * from './types/items.js';
23
23
  export * from './types/observability.js';
24
24
  export * from './types/output-codec.js';
25
25
  export * from './types/runtime.js';
26
+ export * from './types/schema.js';
26
27
  export * from './types/shell-adapter.js';
27
28
  export * from './types/steering.js';
28
29
  export * from './types/step.js';
package/dist/index.js CHANGED
@@ -23,6 +23,7 @@ export * from './types/items.js';
23
23
  export * from './types/observability.js';
24
24
  export * from './types/output-codec.js';
25
25
  export * from './types/runtime.js';
26
+ export * from './types/schema.js';
26
27
  export * from './types/shell-adapter.js';
27
28
  export * from './types/steering.js';
28
29
  export * from './types/step.js';
@@ -1,4 +1,4 @@
1
- import type { ZodType } from 'zod';
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
2
  import type { ItemSchemaRegistry } from '../schemas/item.js';
3
3
  import type { Channel, ChannelHandle, ExternalChannel } from './channel.js';
4
4
  import type { LLMResponse, ModelParams, StepMeta, TokenUsage } from './common.js';
@@ -41,7 +41,9 @@ interface ContextCallModelRequestBase {
41
41
  items: ReadonlyArray<import('./items.js').Item>;
42
42
  instructions?: string;
43
43
  params?: ModelParams;
44
- outputSchema?: ZodType;
44
+ outputSchema?: StandardSchemaV1;
45
+ /** Explicit non-Zod override/fallback after StandardJSONSchemaV1 conversion. */
46
+ outputJsonSchema?: Record<string, unknown>;
45
47
  emit?: boolean | ((eventType: string, data: Record<string, unknown>) => boolean);
46
48
  signal?: AbortSignal;
47
49
  }
@@ -112,7 +114,7 @@ export type ContextStep<TContext = ContextData, I = unknown, O = unknown> = {
112
114
  } | {
113
115
  readonly kind: 'llm';
114
116
  readonly id: string;
115
- readonly output?: ZodType<O>;
117
+ readonly output?: StandardSchemaV1<unknown, O>;
116
118
  } | {
117
119
  readonly kind: 'loop';
118
120
  readonly id: string;
@@ -1,4 +1,5 @@
1
- import type { ZodError, ZodType } from 'zod';
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
+ import type { ZodError } from 'zod';
2
3
  /** @public Discriminated union of all structured error kinds raised by the runtime. */
3
4
  export type NoeticError = {
4
5
  kind: 'step_failed';
@@ -13,7 +14,8 @@ export type NoeticError = {
13
14
  kind: 'llm_parse_error';
14
15
  stepId: string;
15
16
  raw: string;
16
- schema: ZodType;
17
+ schema: StandardSchemaV1;
18
+ /** Real `ZodError` for Zod schemas; synthetic `custom` issues adapted from the vendor's Standard Schema issues otherwise. */
17
19
  zodError: ZodError;
18
20
  } | {
19
21
  kind: 'llm_rate_limit';
@@ -1,4 +1,4 @@
1
- import type { ZodType } from 'zod';
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
2
  import type { Channel, ChannelHandle, ExternalChannel } from './channel.js';
3
3
  import type { LLMResponse, ModelParams, ServerToolSpec } from './common.js';
4
4
  import type { Context, CwdState, RestoreContextOptions } from './context.js';
@@ -54,7 +54,12 @@ interface CallModelRequestBase {
54
54
  instructions?: string;
55
55
  params?: ModelParams;
56
56
  /** When provided, the harness sends a JSON Schema constraint to the model so it returns structured JSON. */
57
- outputSchema?: ZodType;
57
+ outputSchema?: StandardSchemaV1;
58
+ /**
59
+ * Explicit raw JSON Schema override for the structured-output constraint.
60
+ * For non-Zod schemas, it takes precedence over StandardJSONSchemaV1 conversion.
61
+ */
62
+ outputJsonSchema?: Record<string, unknown>;
58
63
  /** Controls framework event emission. Defaults to `true`. Passed through from `StepLLM.emit`. */
59
64
  emit?: boolean | ((eventType: string, data: Record<string, unknown>) => boolean);
60
65
  /**
@@ -0,0 +1,62 @@
1
+ import type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';
2
+ import type { ZodTypeAny, z } from 'zod';
3
+ import { ZodError } from 'zod';
4
+ export type { StandardJSONSchemaV1, StandardSchemaV1 } from '@standard-schema/spec';
5
+ /**
6
+ * Input type inferred from any Standard Schema. Zod schemas keep their exact
7
+ * `z.input` inference; other vendors use `StandardSchemaV1.InferInput`.
8
+ * @public
9
+ */
10
+ export type InferSchemaInput<S extends StandardSchemaV1> = S extends ZodTypeAny ? z.input<S> : StandardSchemaV1.InferInput<S>;
11
+ /**
12
+ * Output type inferred from any Standard Schema. Zod schemas keep their exact
13
+ * `z.output` inference; other vendors use `StandardSchemaV1.InferOutput`.
14
+ * @public
15
+ */
16
+ export type InferSchemaOutput<S extends StandardSchemaV1> = S extends ZodTypeAny ? z.output<S> : StandardSchemaV1.InferOutput<S>;
17
+ /**
18
+ * JSON Schema configuration for a tool input schema. Zod and Standard JSON
19
+ * Schema implementations can derive their wire schema; validation-only
20
+ * Standard Schemas require an explicit fallback.
21
+ * @public
22
+ */
23
+ export type InputSchemaConfig<S extends StandardSchemaV1> = StandardSchemaV1 extends S ? {
24
+ inputJsonSchema?: Record<string, unknown>;
25
+ } : S extends ZodTypeAny | StandardJSONSchemaV1 ? {
26
+ inputJsonSchema?: Record<string, unknown>;
27
+ } : {
28
+ inputJsonSchema: Record<string, unknown>;
29
+ };
30
+ /** @public Type guard for Zod schemas (detected via the `_zod` internals marker). */
31
+ export declare function isZodSchema(schema: StandardSchemaV1): schema is ZodTypeAny;
32
+ /** @public Type guard for schemas implementing the Standard JSON Schema v1 companion spec. */
33
+ export declare function isStandardJsonSchema(schema: StandardSchemaV1): schema is StandardSchemaV1 & StandardJSONSchemaV1;
34
+ /** @public Successful result of `validateSchema` — carries the parsed/transformed value. */
35
+ export interface SchemaValidationSuccess<T> {
36
+ success: true;
37
+ value: T;
38
+ }
39
+ /**
40
+ * Failed result of `validateSchema`. `issues` are the vendor's issues in
41
+ * Standard Schema form; `zodError` adapts them into a `ZodError` (the
42
+ * original error for Zod schemas, synthetic `custom` issues otherwise) so
43
+ * consumers like `llm_parse_error` keep a single error surface.
44
+ * @public
45
+ */
46
+ export interface SchemaValidationFailure {
47
+ success: false;
48
+ issues: readonly StandardSchemaV1.Issue[];
49
+ zodError: ZodError;
50
+ }
51
+ /** @public Result of `validateSchema`. */
52
+ export type SchemaValidationResult<T> = SchemaValidationSuccess<T> | SchemaValidationFailure;
53
+ /** @public Adapt Standard Schema issues into a synthetic `ZodError` of `custom` issues. */
54
+ export declare function standardIssuesToZodError(issues: readonly StandardSchemaV1.Issue[]): ZodError;
55
+ /**
56
+ * Validates a value against any Standard Schema. Zod schemas take the
57
+ * `safeParse` fast path; other vendors run `schema['~standard'].validate`,
58
+ * awaiting sync or Promise results. The returned success value is the
59
+ * parsed/transformed output.
60
+ * @public
61
+ */
62
+ export declare function validateSchema<S extends StandardSchemaV1>(schema: S, value: unknown): Promise<SchemaValidationResult<InferSchemaOutput<S>>>;
@@ -0,0 +1,63 @@
1
+ import { ZodError } from 'zod';
2
+ import { frameworkCast } from '../util/framework-cast.js';
3
+ /** @public Type guard for Zod schemas (detected via the `_zod` internals marker). */
4
+ export function isZodSchema(schema) {
5
+ return '_zod' in schema;
6
+ }
7
+ /** @public Type guard for schemas implementing the Standard JSON Schema v1 companion spec. */
8
+ export function isStandardJsonSchema(schema) {
9
+ const standard = frameworkCast(schema['~standard']);
10
+ return typeof standard.jsonSchema?.input === 'function';
11
+ }
12
+ function issuePathToPropertyKeys(path) {
13
+ if (!path) {
14
+ return [];
15
+ }
16
+ return path.map((segment) => typeof segment === 'object' && segment !== null && 'key' in segment ? segment.key : segment);
17
+ }
18
+ /** @public Adapt Standard Schema issues into a synthetic `ZodError` of `custom` issues. */
19
+ export function standardIssuesToZodError(issues) {
20
+ return new ZodError(issues.map((issue) => ({
21
+ code: 'custom',
22
+ message: issue.message,
23
+ path: issuePathToPropertyKeys(issue.path),
24
+ })));
25
+ }
26
+ /**
27
+ * Validates a value against any Standard Schema. Zod schemas take the
28
+ * `safeParse` fast path; other vendors run `schema['~standard'].validate`,
29
+ * awaiting sync or Promise results. The returned success value is the
30
+ * parsed/transformed output.
31
+ * @public
32
+ */
33
+ export async function validateSchema(schema, value) {
34
+ if (isZodSchema(schema)) {
35
+ const result = schema.safeParse(value);
36
+ if (result.success) {
37
+ return {
38
+ success: true,
39
+ value: frameworkCast(result.data),
40
+ };
41
+ }
42
+ return {
43
+ success: false,
44
+ issues: result.error.issues.map((issue) => ({
45
+ message: issue.message,
46
+ path: issue.path,
47
+ })),
48
+ zodError: result.error,
49
+ };
50
+ }
51
+ const result = await schema['~standard'].validate(value);
52
+ if (result.issues) {
53
+ return {
54
+ success: false,
55
+ issues: result.issues,
56
+ zodError: standardIssuesToZodError(result.issues),
57
+ };
58
+ }
59
+ return {
60
+ success: true,
61
+ value: frameworkCast(result.value),
62
+ };
63
+ }
@@ -1,4 +1,4 @@
1
- import type { ZodType } from 'zod';
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
2
  import type { Channel } from './channel.js';
3
3
  import type { ModelParams, RetryPolicy, ServerToolSpec, StepMeta } from './common.js';
4
4
  import type { Context } from './context.js';
@@ -104,11 +104,17 @@ export interface StepLLM<TContext = ContextData, _I = unknown, O = unknown> {
104
104
  */
105
105
  tools?: Lazy<(Tool | ServerToolSpec)[] | undefined, TContext>;
106
106
  /**
107
- * Structured output: a Zod schema (assistant text is JSON-parsed and
107
+ * Structured output: a Standard Schema (assistant text is JSON-parsed and
108
108
  * validated) or a streaming `OutputCodec` (fed each text delta, produces
109
- * the typed value at turn end).
109
+ * the typed value at turn end). Non-Zod schemas can derive the model
110
+ * constraint through StandardJSONSchemaV1 or provide `outputJsonSchema`.
110
111
  */
111
- output?: ZodType<O> | OutputCodec<O>;
112
+ output?: StandardSchemaV1<unknown, O> | OutputCodec<O>;
113
+ /**
114
+ * Explicit raw JSON Schema override sent to the model. For non-Zod schemas,
115
+ * it takes precedence over StandardJSONSchemaV1 conversion.
116
+ */
117
+ outputJsonSchema?: Record<string, unknown>;
112
118
  params?: ModelParams;
113
119
  /** Controls framework event emission for this step. Defaults to `true`. Set `false` to suppress all framework events. A filter function receives `(eventType, data)` and returns `boolean`. */
114
120
  emit?: boolean | ((eventType: string, data: Record<string, unknown>) => boolean);
@@ -138,8 +144,8 @@ export interface StepSubHarness<TContext = ContextData, _I = unknown, O = unknow
138
144
  settings?: SubHarnessSettings;
139
145
  /** System instructions applied on the first message of a fresh session. */
140
146
  instructions?: Lazy<string | undefined, TContext>;
141
- /** When set, the assistant text is JSON-parsed and validated against this schema. */
142
- output?: ZodType<O>;
147
+ /** When set, the assistant text is JSON-parsed and validated against this Standard Schema. */
148
+ output?: StandardSchemaV1<unknown, O>;
143
149
  /** Session reuse + teardown policy across steps. */
144
150
  session?: SubHarnessSessionPolicy;
145
151
  /** Controls framework event emission for this step. Defaults to `true`. */
@@ -149,7 +155,7 @@ export interface StepSubHarness<TContext = ContextData, _I = unknown, O = unknow
149
155
  export interface StepTool<_TContext = ContextData, I = unknown, O = unknown> {
150
156
  kind: 'tool';
151
157
  id: string;
152
- tool: Tool<ZodType<I>, ZodType<O>>;
158
+ tool: Tool<StandardSchemaV1<unknown, I>, StandardSchemaV1<unknown, O>>;
153
159
  args?: Partial<I>;
154
160
  }
155
161
  /** @public A step that dynamically selects and executes one of several possible sub-steps. */
@@ -1,6 +1,7 @@
1
- import type { ZodTypeAny, z } from 'zod';
1
+ import type { StandardSchemaV1 } from '@standard-schema/spec';
2
2
  import type { FunctionCallItem, FunctionCallOutputItem, Item, ItemSchemaExtensions, ToolResultExtensionItem } from './items.js';
3
- type ToolExecutionResult<O extends ZodTypeAny> = Promise<z.infer<O>> | AsyncGenerator<unknown, z.infer<O>>;
3
+ import type { InferSchemaOutput } from './schema.js';
4
+ type ToolExecutionResult<O extends StandardSchemaV1> = Promise<InferSchemaOutput<O>> | AsyncGenerator<unknown, InferSchemaOutput<O>>;
4
5
  /**
5
6
  * Declares tool-owned state that the runtime materializes into a ContextLayer.
6
7
  * @public
@@ -39,44 +40,55 @@ export interface UiFragment {
39
40
  * `tool()` builder and runtime consume.
40
41
  * @public
41
42
  */
42
- export interface ToolUiDeclaration<I extends ZodTypeAny = ZodTypeAny, O extends ZodTypeAny = ZodTypeAny, E = unknown> {
43
+ export interface ToolUiDeclaration<I extends StandardSchemaV1 = StandardSchemaV1, O extends StandardSchemaV1 = StandardSchemaV1, E = unknown> {
43
44
  /** Rendered as soon as the call streams in — args may be partial. */
44
- call?(args: Partial<z.infer<I>>): UiFragment | null;
45
+ call?(args: Partial<InferSchemaOutput<I>>): UiFragment | null;
45
46
  /** Re-rendered on each event an AsyncGenerator `execute` yields. Receives all events so far. */
46
47
  progress?(events: E[]): UiFragment | null;
47
48
  /** Replaces the tool's region on successful completion. */
48
- result?(output: z.infer<O>, args: z.infer<I>): UiFragment | null;
49
+ result?(output: InferSchemaOutput<O>, args: InferSchemaOutput<I>): UiFragment | null;
49
50
  /** Replaces the tool's region when execution throws. */
50
- error?(err: unknown, args: z.infer<I>): UiFragment | null;
51
+ error?(err: unknown, args: InferSchemaOutput<I>): UiFragment | null;
51
52
  }
52
53
  /**
53
54
  * A tool definition that an LLM can invoke during execution.
54
55
  *
56
+ * Input and output schemas accept any Standard Schema v1 implementation
57
+ * (Zod, Valibot, ArkType, …). Zod remains the fast path; other validators
58
+ * can provide JSON Schema through the Standard JSON Schema v1 companion
59
+ * trait or an explicit `inputJsonSchema` override.
60
+ *
55
61
  * The runtime passes a `ToolExecutionContext` (from `./tool-context`) as
56
62
  * the second argument to `execute`. Callers that need the concrete type
57
63
  * should import `Tool` from the package root (`@noetic-tools/core`), which
58
64
  * re-exports it with `ToolExecutionContext` substituted in.
59
65
  * @public
60
66
  */
61
- export interface Tool<I extends ZodTypeAny = ZodTypeAny, O extends ZodTypeAny = ZodTypeAny> {
67
+ export interface Tool<I extends StandardSchemaV1 = StandardSchemaV1, O extends StandardSchemaV1 = StandardSchemaV1> {
62
68
  /** Unique tool name used by the LLM for selection. */
63
69
  name: string;
64
70
  /** Human-readable description shown to the LLM. */
65
71
  description: string;
66
- /** Zod schema validating tool input arguments. */
72
+ /** Schema validating tool input arguments (any Standard Schema v1). */
67
73
  input: I;
68
- /** Zod schema validating tool return value. */
74
+ /** Schema validating tool return value (any Standard Schema v1). */
69
75
  output: O;
70
- /** Optional Zod schema validating streaming events yielded during execution. */
71
- event?: ZodTypeAny;
76
+ /**
77
+ * Explicit raw JSON Schema for the tool input, sent to the LLM wire format.
78
+ * For non-Zod schemas, overrides StandardJSONSchemaV1 conversion and serves
79
+ * as the required fallback for validation-only schemas.
80
+ */
81
+ inputJsonSchema?: Record<string, unknown>;
82
+ /** Optional schema validating streaming events yielded during execution. */
83
+ event?: StandardSchemaV1;
72
84
  /** Optional item schemas contributed by this tool for tool call/result extensions. */
73
85
  itemSchemas?: Pick<ItemSchemaExtensions, 'toolCalls' | 'toolResults' | 'items'>;
74
86
  /** Decorate the harness-created tool result item before it is appended/emitted. */
75
87
  decorateResultItem?(params: {
76
88
  baseItem: FunctionCallOutputItem;
77
89
  callItem: FunctionCallItem;
78
- args: z.infer<I>;
79
- result: z.infer<O> | undefined;
90
+ args: InferSchemaOutput<I>;
91
+ result: InferSchemaOutput<O> | undefined;
80
92
  output: string;
81
93
  error?: boolean;
82
94
  }): Item | ToolResultExtensionItem;
@@ -86,7 +98,7 @@ export interface Tool<I extends ZodTypeAny = ZodTypeAny, O extends ZodTypeAny =
86
98
  * this type a dependency leaf. Use `tool()` from `builders/` or cast at
87
99
  * the call site to get a typed handle.
88
100
  */
89
- execute(args: z.infer<I>, toolCtx: unknown): ToolExecutionResult<O>;
101
+ execute(args: InferSchemaOutput<I>, toolCtx: unknown): ToolExecutionResult<O>;
90
102
  /** When true, execution pauses for human approval before running. */
91
103
  needsApproval?: boolean;
92
104
  /** Optional context declaration — the runtime generates a ContextLayer from this. */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noetic-tools/types",
3
- "version": "3.1.0",
3
+ "version": "3.2.0",
4
4
  "type": "module",
5
5
  "description": "Foundational type contracts and primitives shared across the Noetic framework (items, LLM config, adapters, steering, errors).",
6
6
  "license": "Apache-2.0",
@@ -55,6 +55,7 @@
55
55
  },
56
56
  "dependencies": {
57
57
  "@openrouter/agent": "^0.6.0",
58
+ "@standard-schema/spec": "1.1.0",
58
59
  "zod": "^4.0.0"
59
60
  },
60
61
  "scripts": {