Context
Downstream work for PhenoML/phenoml_console#451.
extract-code-examples already puts the SDK call shape in code-examples.json: each endpoint has a callTemplate and field templates, and the manifest has primitive/list renderRules. However, that is not yet enough for a consumer to render a complete SDK snippet without knowing TypeScript-, Python-, and Java-specific conventions.
The console still hardcodes:
- SDK imports, client construction, base-URL placement, and whole-program wrapping
- whether a call is awaited/terminated and the Java
main-class postamble
- Java imports and helper code, selected by inspecting the rendered call for
mapOf( and ArrayList
- recursive object/map literals, object-key syntax, and Java collection behavior
Those are fixed properties of the generated SDKs and should be emitted by this action rather than reimplemented by every consumer.
Proposed changes
1. Emit a complete snippet-wrapper contract
Add manifest data that can wrap a rendered call into a complete snippet using explicit slots such as {{baseUrl}} and {{__call__}}. It must cover, for all three supported languages:
- imports
- package/client symbol and client construction
- environment-variable credentials
- base URL
- language-specific call prefix/suffix (
await, semicolon, etc.)
- Java class/
main scaffolding and postamble
The contract may be manifest-wide where the content is invariant, but endpoint-dependent requirements must be represented explicitly per example (or through equivalent structured data). In particular, a consumer must not need to substring-match rendered Java code to decide which imports or support helpers to include.
2. Make renderRules sufficient for arbitrary runtime JSON values
Extend RenderRules so one language-agnostic recursive renderer can handle untyped objects/maps and nested collections, not only primitives and lists. The contract needs to encode:
- empty and non-empty object/map literals
- object entry/key/value templates and separators
- language-specific key quoting/identifier behavior, or an unambiguous rule the consumer can apply generically
- empty and nested lists/objects
- Java's mutable list form where the SDK expects it
- Java maps with more than ten entries
- Java maps containing null values, including the required null-safe helper/imports
Keep string escaping behavior explicit so the consumer only supplies escaped runtime text and does not need language-specific quoting logic.
3. Document and test the expanded schema
- Update the TypeScript manifest types and
extract-code-examples/README.md with the new fields and generic rendering algorithm.
- Add fixture/unit coverage for TypeScript, Python, and Java full snippets.
- Cover empty values, nested maps/lists, object keys that are and are not identifiers, Java arrays, Java maps over ten entries, and nested null-valued Java maps.
- Assert that required imports/helpers are selected structurally from the render schema rather than inferred from rendered text.
Acceptance criteria
- Given a manifest entry, runtime body/path values, and a base URL, a consumer can produce a complete TypeScript, Python, or Java SDK snippet using one generic substitution/rendering algorithm.
- The consumer does not encode SDK package names, client constructors, imports, Java helper selection, or per-language object/map syntax.
- Existing endpoint call-template behavior remains covered, including passthrough bodies, nested typed objects, enums, query parameters, and TypeScript request-body wrappers.
- The emitted schema and migration expectations are documented for downstream consumers.
Out of scope
- Console-side adoption/removal of its current renderers; tracked in PhenoML/phenoml_console#451.
- cURL generation, OpenAPI control metadata, runtime value selection/merging, and product-specific multi-step recipes.
- Spec/example drift detection.
Context
Downstream work for PhenoML/phenoml_console#451.
extract-code-examplesalready puts the SDK call shape incode-examples.json: each endpoint has acallTemplateand field templates, and the manifest has primitive/listrenderRules. However, that is not yet enough for a consumer to render a complete SDK snippet without knowing TypeScript-, Python-, and Java-specific conventions.The console still hardcodes:
main-class postamblemapOf(andArrayListThose are fixed properties of the generated SDKs and should be emitted by this action rather than reimplemented by every consumer.
Proposed changes
1. Emit a complete snippet-wrapper contract
Add manifest data that can wrap a rendered call into a complete snippet using explicit slots such as
{{baseUrl}}and{{__call__}}. It must cover, for all three supported languages:await, semicolon, etc.)mainscaffolding and postambleThe contract may be manifest-wide where the content is invariant, but endpoint-dependent requirements must be represented explicitly per example (or through equivalent structured data). In particular, a consumer must not need to substring-match rendered Java code to decide which imports or support helpers to include.
2. Make
renderRulessufficient for arbitrary runtime JSON valuesExtend
RenderRulesso one language-agnostic recursive renderer can handle untyped objects/maps and nested collections, not only primitives and lists. The contract needs to encode:Keep string escaping behavior explicit so the consumer only supplies escaped runtime text and does not need language-specific quoting logic.
3. Document and test the expanded schema
extract-code-examples/README.mdwith the new fields and generic rendering algorithm.Acceptance criteria
Out of scope