Skip to content

Arrays and unions of types are not compatible in chain structured output schemas #1

@DexterStorey

Description

@DexterStorey

given the below nodes (blocks, actions, etc):

export const blocks = {
	renderString: createBlock({
		schema: { input: { text: z.string() }, output: z.string() },
		render: ({ text }) => text,
		description: 'Render a string'
	}),
	renderString2: createBlock({
		schema: { input: { text: z.string() }, output: z.string() },
		render: ({ text }) => text,
		description: 'Render a string'
	}),
	concatenate: createBlock({
		schema: { input: { children: z.array(z.string()) }, output: z.string() },
		render: ({ children }) => children.join(''),
		description: 'Concatenate a list of strings'
	})
}

you would expect concatenate to accept an array of strings and nodes that return string. Essentially, concatenate should accept z.union([z.string(), renderStringDef, renderString2Def]) (pseudocode)

Instead, we get this structured out:

const schema = {
  type: 'json_schema',
  name: 'chain',
  strict: true,
  schema: {
    '$schema': 'https://json-schema.org/draft/2020-12/schema',
    type: 'object',
    properties: {
      chain: {
        anyOf: [
          { '$ref': '#/$defs/renderString' },
          { '$ref': '#/$defs/renderString2' },
          { '$ref': '#/$defs/concatenate' }
        ]
      }
    },
    required: [ 'chain' ],
    additionalProperties: false,
    '$defs': {
      renderString: {
        type: 'object',
        properties: {
          node: { type: 'string', const: 'renderString' },
          input: {
            type: 'object',
            properties: { text: { '$ref': '#/$defs/"string"' } },
            required: [ 'text' ],
            additionalProperties: false
          }
        },
        required: [ 'node', 'input' ],
        additionalProperties: false,
        id: 'renderString'
      },
      '"string"': {
        anyOf: [
          { '$ref': '#/$defs/renderString' },
          { '$ref': '#/$defs/renderString2' },
          { '$ref': '#/$defs/concatenate' },
          { type: 'string' }
        ],
        id: '"string"'
      },
      renderString2: {
        type: 'object',
        properties: {
          node: { type: 'string', const: 'renderString2' },
          input: {
            type: 'object',
            properties: {
              text: {
                anyOf: [
                  { '$ref': '#/$defs/renderString' },
                  { '$ref': '#/$defs/renderString2' },
                  { '$ref': '#/$defs/concatenate' },
                  { type: 'string' }
                ]
              }
            },
            required: [ 'text' ],
            additionalProperties: false
          }
        },
        required: [ 'node', 'input' ],
        additionalProperties: false,
        id: 'renderString2'
      },
      concatenate: {
        type: 'object',
        properties: {
          node: { type: 'string', const: 'concatenate' },
          input: {
            type: 'object',
            properties: { children: { '$ref': '#/$defs/["string"]' } },
            required: [ 'children' ],
            additionalProperties: false
          }
        },
        required: [ 'node', 'input' ],
        additionalProperties: false,
        id: 'concatenate'
      },
      // THE BUG 👇
      '["string"]': { anyOf: [], id: '["string"]' }
    }
  }
}

The chaining comparabilities are only excepting perfect matches for input object values.

This bug also applies to unions and nested objects.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions