@@ -137,20 +137,31 @@ void _loadPrompt(
137137 final config = metadata.config;
138138 final tools = metadata.tools;
139139
140+ // Named schemas registered via `defineSchema`. Picoschema may reference these
141+ // by name (e.g. `schema: MyAddress`), so they are passed through to the
142+ // converter to resolve, mirroring what `_resolveMetadata` does internally.
143+ // `listValues` keys are registry paths (`/schema/<name>`); Picoschema looks
144+ // schemas up by bare name, so strip the prefix.
145+ final schemas = {
146+ for (final entry
147+ in registry.listValues <Map <String , dynamic >>('schema' ).entries)
148+ entry.key.split ('/' ).last: entry.value,
149+ };
150+
140151 // Build the input schema from the frontmatter `input.schema`. The raw
141152 // metadata from `parse` is not schema-resolved, so Picoschema is converted
142153 // to JSON Schema here (mirroring what `renderMetadata` does internally).
143154 // Without this the action has no input schema, so the Developer UI cannot
144155 // render an input form for the prompt.
145- final inputSchema = _toInputSchema (metadata.input? .schema);
156+ final inputSchema = _toInputSchema (metadata.input? .schema, schemas );
146157
147158 // Build output config from parsed metadata. As with the input schema, the
148159 // output schema may be Picoschema and must be converted to JSON Schema
149160 // before it reaches the model, otherwise the raw Picoschema is sent as the
150161 // response schema and the request fails or is ignored.
151162 GenerateActionOutputConfig ? outputConfig;
152163 if (metadata.output != null ) {
153- final outputSchema = _toJsonSchema (metadata.output! .schema);
164+ final outputSchema = _toJsonSchema (metadata.output! .schema, schemas );
154165 outputConfig = GenerateActionOutputConfig .fromJson ({
155166 'format' : ? metadata.output! .format,
156167 'jsonSchema' : ? outputSchema,
@@ -210,10 +221,16 @@ String _registryDefinitionKey(String name, String? variant, String? ns) {
210221/// not recognize the `type, description` form (e.g. `name: string, the person
211222/// to greet`) that the docs and examples use. [_isJsonSchema] is used instead
212223/// so that form is converted rather than passed through raw.
213- Map <String , dynamic >? _toJsonSchema (Map <String , dynamic >? schema) {
224+ ///
225+ /// [schemas] holds named schemas registered via `defineSchema` , so Picoschema
226+ /// references to them by name can be resolved during conversion.
227+ Map <String , dynamic >? _toJsonSchema (
228+ Map <String , dynamic >? schema,
229+ Map <String , Map <String , dynamic >> schemas,
230+ ) {
214231 if (schema == null ) return null ;
215232 if (_isJsonSchema (schema)) return schema;
216- return Picoschema .toJsonSchema (schema);
233+ return Picoschema .toJsonSchema (schema, schemas : schemas );
217234}
218235
219236/// Whether [schema] is already a JSON Schema (as opposed to Picoschema).
@@ -255,10 +272,14 @@ bool _isJsonSchema(Map<String, dynamic> schema) {
255272///
256273/// Returns `null` when no input schema is declared, in which case the prompt
257274/// accepts free-form input as before.
275+ ///
276+ /// [schemas] holds named schemas registered via `defineSchema` , so Picoschema
277+ /// references to them by name can be resolved during conversion.
258278SchemanticType <Map <String , dynamic >>? _toInputSchema (
259279 Map <String , dynamic >? schema,
280+ Map <String , Map <String , dynamic >> schemas,
260281) {
261- final jsonSchema = _toJsonSchema (schema);
282+ final jsonSchema = _toJsonSchema (schema, schemas );
262283 if (jsonSchema == null ) return null ;
263284 return SchemanticType .from <Map <String , dynamic >>(
264285 jsonSchema: jsonSchema,
0 commit comments