@modelrelay/sdk 0.7.0 → 0.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -82,11 +82,87 @@ const stream = await mr.chat.completions.create(
82
82
  );
83
83
  ```
84
84
 
85
- ### Typed models, providers, and stop reasons
85
+ ### Typed models and stop reasons
86
86
 
87
- - Models and providers use string literal unions with an `Other` escape hatch: pass `{ other: "my-provider" }` or `{ other: "custom/model-x" }` to preserve custom IDs while benefiting from autocomplete on known values (e.g., `Models.OpenAIGpt4o`, `Providers.Anthropic`).
87
+ - Models are plain strings (e.g., `"gpt-4o"`), so new models do not require SDK updates.
88
88
  - Stop reasons are parsed into the `StopReason` union (e.g., `StopReasons.EndTurn`); unknown values surface as `{ other: "<raw>" }`.
89
- - Usage backfills `totalTokens` when providers omit it, ensuring consistent accounting.
89
+ - Usage backfills `totalTokens` when the backend omits it, ensuring consistent accounting.
90
+
91
+ ### Structured outputs (`response_format`)
92
+
93
+ Request structured JSON instead of free-form text when the backend supports it:
94
+
95
+ ```ts
96
+ import { ModelRelay, type ResponseFormat } from "@modelrelay/sdk";
97
+
98
+ const mr = new ModelRelay({ key: "mr_sk_..." });
99
+
100
+ const format: ResponseFormat = {
101
+ type: "json_schema",
102
+ json_schema: {
103
+ name: "summary",
104
+ schema: {
105
+ type: "object",
106
+ properties: { headline: { type: "string" } },
107
+ additionalProperties: false,
108
+ },
109
+ strict: true,
110
+ },
111
+ };
112
+
113
+ const completion = await mr.chat.completions.create(
114
+ {
115
+ model: "gpt-4o-mini",
116
+ messages: [{ role: "user", content: "Summarize ModelRelay" }],
117
+ responseFormat: format,
118
+ stream: false,
119
+ },
120
+ { stream: false },
121
+ );
122
+
123
+ console.log(completion.content[0]); // JSON string matching your schema
124
+ ```
125
+
126
+ ### Structured streaming (NDJSON + response_format)
127
+
128
+ Use the structured streaming contract for `/llm/proxy` to stream schema-valid
129
+ JSON payloads over NDJSON:
130
+
131
+ ```ts
132
+ type Item = { id: string; label: string };
133
+ type RecommendationPayload = { items: Item[] };
134
+
135
+ const format: ResponseFormat = {
136
+ type: "json_schema",
137
+ json_schema: {
138
+ name: "recommendations",
139
+ schema: {
140
+ type: "object",
141
+ properties: { items: { type: "array", items: { type: "object" } } },
142
+ },
143
+ },
144
+ };
145
+
146
+ const stream = await mr.chat.completions.streamJSON<RecommendationPayload>({
147
+ model: "grok-4-1-fast",
148
+ messages: [{ role: "user", content: "Recommend items for my user" }],
149
+ responseFormat: format,
150
+ });
151
+
152
+ for await (const evt of stream) {
153
+ if (evt.type === "update") {
154
+ // Progressive UI: evt.payload is a partial but schema-valid payload.
155
+ renderPartial(evt.payload.items);
156
+ }
157
+ if (evt.type === "completion") {
158
+ renderFinal(evt.payload.items);
159
+ }
160
+ }
161
+
162
+ // Prefer a single blocking result but still want structured validation?
163
+ const final = await stream.collect();
164
+ console.log(final.items.length);
165
+ ```
90
166
 
91
167
  ### Telemetry & metrics hooks
92
168