Anonymous View
Skip to content

Commit 7451cac

Browse files
committed
feat: add support for lazy schema
1 parent 70d035a commit 7451cac

3 files changed

Lines changed: 46 additions & 1 deletion

File tree

packages/core/src/agent/inferAgentInternal.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ const SYSTEM_PROMPT = `You answer using programming language called AgentScript.
2727
- can't use regexes
2828
- can't use complex computation
2929
- can only use predefined functions and nothing else
30-
- to iterate over arrays always use \`map\` function
30+
- to iterate over arrays always use \`array.map()\` function
3131
- never assume array in non-empty
3232
- each function call or code block requires a comment briefly explaining the step
3333

packages/core/src/modules/renderType.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,3 +679,27 @@ describe('union', () => {
679679
expect(ctx.code).toEqual('');
680680
});
681681
});
682+
683+
describe('lazy', () => {
684+
test('basic object', () => {
685+
const inner = s.object({ props: { name: s.string() } });
686+
const schema = s.lazy(() => inner);
687+
const ctx = createRenderContext();
688+
const type = renderType({ schema, ctx });
689+
690+
expect(type).toEqual('{\n name: string;\n}');
691+
expect(ctx.code).toEqual('');
692+
});
693+
694+
test('nullable object', () => {
695+
const inner = s.object({ props: { name: s.string() } });
696+
const schema = s.lazy({
697+
of: () => inner,
698+
nullable: true,
699+
});
700+
const ctx = createRenderContext();
701+
const type = renderType({ schema: s.nullable(schema), ctx });
702+
703+
expect(type).toEqual('{\n name: string;\n} | null');
704+
});
705+
});

packages/core/src/modules/renderType.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ function renderTypeInternal(
9797
return renderUnion(schema as s.UnionSchema, ctx, skipUndefined);
9898
case s.record:
9999
return renderRecord(schema as s.RecordSchema, ctx, skipUndefined);
100+
case s.lazy:
101+
return renderLazy(schema as s.LazySchema, ctx, skipUndefined);
100102
default:
101103
throw new Error(`Unsupported schema ${schema.type.name}`);
102104
}
@@ -158,6 +160,12 @@ function renderRecord(schema: s.RecordSchema, ctx: RenderContext, skipUndefined?
158160
return wrapType(schema, type, skipUndefined);
159161
}
160162

163+
function renderLazy(schema: s.LazySchema, ctx: RenderContext, skipUndefined?: boolean) {
164+
const unwrapped = unwrapLazy(schema);
165+
const type = renderTypeInternal(unwrapped, ctx, skipUndefined);
166+
return wrapType(unwrapped, type, skipUndefined);
167+
}
168+
161169
function renderEnum(schema: s.EnumSchema, skipUndefined?: boolean) {
162170
const type = schema.values.map(option => `"${option}"`).join(' | ');
163171
return wrapType(schema, type, skipUndefined);
@@ -186,3 +194,16 @@ function findUniqueName(name: string, ctx: RenderContext) {
186194

187195
return uniqueName;
188196
}
197+
198+
function unwrapLazy(schema: s.LazySchema) {
199+
const inner = schema.of();
200+
201+
const unwrapped: Partial<s.LazySchema> = schema;
202+
delete unwrapped.of;
203+
204+
for (const key in inner) {
205+
(unwrapped as Record<string, unknown>)[key] = inner[key as keyof typeof inner];
206+
}
207+
208+
return unwrapped as s.Schema;
209+
}

0 commit comments

Comments
 (0)