Forráskód Böngészése

refactor: drop unused tool schema defaults

Tianyi Cui 2 hónapja
szülő
commit
f1373cd7ab

+ 0 - 2
docs/core-data-structures/tools.md

@@ -57,8 +57,6 @@ interface SchemaProp {
   description?: string
   /** Enum of allowed values (strings only). */
   enum?: string[]
-  /** Default value. */
-  default?: unknown
   /** Nested properties for type: 'object'. */
   properties?: SchemaSpec
   /** Items schema for type: 'array'. */

+ 1 - 1
packages/core/tools/README.md

@@ -77,7 +77,7 @@ ctx.tools.register(defineTool({
 
 The helper converts the author-facing `SchemaSpec` (with `required: true` as a per-property boolean) to standard JSON Schema for the wire format and uses the same typed spec for execute/presentation validation. Raw JSON-Schema tool definitions (from MCP servers) are still accepted by the registry directly.
 
-A `defineTool` tool also **validates the model-generated arguments against its `SchemaSpec` before `execute` runs** (`validateArgs`). The model's JSON is untrusted — `InferArgs<S>` is a compile-time claim, not a runtime guarantee — so on a mismatch (missing required key, wrong primitive, bad enum member, nested violation) the tool throws a `ToolArgsError` (`code: 'INVALID_ARGS'`); the registry turns it into an `isError` result whose text lists the violations, which the model sees and self-corrects from. Validation mirrors the JSON Schema conversion exactly: extra keys are allowed, `default` is not applied, and an `object`/`array` prop without `properties`/`items` only type-checks. Raw-registered tools (MCP) are **not** validated by the harness — they validate their own input.
+A `defineTool` tool also **validates the model-generated arguments against its `SchemaSpec` before `execute` runs** (`validateArgs`). The model's JSON is untrusted — `InferArgs<S>` is a compile-time claim, not a runtime guarantee — so on a mismatch (missing required key, wrong primitive, bad enum member, nested violation) the tool throws a `ToolArgsError` (`code: 'INVALID_ARGS'`); the registry turns it into an `isError` result whose text lists the violations, which the model sees and self-corrects from. Validation mirrors the JSON Schema conversion exactly: extra keys are allowed, and an `object`/`array` prop without `properties`/`items` only type-checks. Raw-registered tools (MCP) are **not** validated by the harness — they validate their own input.
 
 See `defineTool`, `validateArgs`, `ToolArgsError`, `SchemaSpec`, `InferArgs`, and `schemaSpecToJsonSchema` in the public API for details.
 

+ 0 - 10
packages/core/tools/src/schema.ts

@@ -39,15 +39,6 @@ export interface SchemaProp {
   description?: string
   /** Enum of allowed values (strings only). */
   enum?: string[]
-  /**
-   * Default value, emitted into the JSON Schema only (validation never applies
-   * it — see the validator note below).
-   *
-   * XXX(unused-default): no tool definition in the repo sets `default`; it rides
-   * into the wire schema for a model that no tool surfaces it to. Drop the field
-   * and its converter line unless a real tool needs a model-visible default.
-   */
-  default?: unknown
   /** Nested properties for type: 'object'. */
   properties?: SchemaSpec
   /** Items schema for type: 'array'. */
@@ -123,7 +114,6 @@ function propToJsonSchema(prop: SchemaProp): { schema: Record<string, unknown>;
   const result: Record<string, unknown> = { type: prop.type }
   if (prop.description) result.description = prop.description
   if (prop.enum) result.enum = prop.enum
-  if (prop.default !== undefined) result.default = prop.default
 
   const required = prop.required === true
 

+ 2 - 35
packages/core/tools/tests/tools.spec.ts

@@ -904,17 +904,6 @@ describe('schema DSL edge cases', () => {
     })
   })
 
-  it('emits default value in JSON Schema property', () => {
-    const spec = {
-      limit: { type: 'number', default: 25 },
-    } satisfies SchemaSpec
-    const jsonSchema = schemaSpecToJsonSchema(spec)
-    expect(jsonSchema.properties['limit']).toMatchObject({
-      type: 'number',
-      default: 25,
-    })
-  })
-
   it('handles array items without nested properties (plain type array)', () => {
     const spec = {
       tags: { type: 'array', items: { type: 'string' } },
@@ -926,28 +915,12 @@ describe('schema DSL edge cases', () => {
     })
   })
 
-  it('handles enum and default together in one property', () => {
-    const spec = {
-      level: { type: 'string', enum: ['low', 'high'], default: 'low' },
-    } satisfies SchemaSpec
-    const jsonSchema = schemaSpecToJsonSchema(spec)
-    expect(jsonSchema.properties['level']).toMatchObject({
-      type: 'string',
-      enum: ['low', 'high'],
-      default: 'low',
-    })
-  })
-
-  it('omits description, enum, default keys when not specified', () => {
+  it('emits only the type when optional fields are omitted', () => {
     const spec = {
       bare: { type: 'string' },
     } satisfies SchemaSpec
     const jsonSchema = schemaSpecToJsonSchema(spec)
-    const prop = jsonSchema.properties['bare'] as Record<string, unknown>
-    expect(prop).toEqual({ type: 'string' })
-    expect('description' in prop).toBe(false)
-    expect('enum' in prop).toBe(false)
-    expect('default' in prop).toBe(false)
+    expect(jsonSchema.properties['bare']).toEqual({ type: 'string' })
   })
 
   it('handles array with no items (items omitted)', () => {
@@ -1137,12 +1110,6 @@ describe('validateArgs (the runtime-validation RFC, part 1)', () => {
     expect(validateArgs(spec, { path: '/tmp', extra: 1 })).toEqual([])
   })
 
-  it('does not apply defaults (validation only)', () => {
-    const spec = { limit: { type: 'number', default: 25 } } satisfies SchemaSpec
-    // absent optional is valid, and validation does not synthesize the default
-    expect(validateArgs(spec, {})).toEqual([])
-  })
-
   it('type-checks primitives', () => {
     const spec = {
       s: { type: 'string' },