You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: CHANGELOG.md
+5Lines changed: 5 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,5 +1,10 @@
1
1
# Changelog
2
2
3
+
## [Unreleased]
4
+
5
+
### Breaking Changes
6
+
*`ResilientLLM.chat()` now always returns a consistent envelope object: `{ content, toolCalls?, metadata }` (metadata is no longer gated by `returnOperationMetadata`).
@@ -92,6 +92,37 @@ import { ProviderRegistry } from 'resilient-llm';
92
92
93
93
See the [full API reference](./docs/reference.md) for complete documentation.
94
94
95
+
## Structured output (JSON + schema)
96
+
97
+
Use `llm.chat(..., { responseFormat })` when you need the assistant to return **machine-readable JSON**, optionally matching a **specific JSON Schema**.
// If the model returns invalid JSON or fails schema validation,
121
+
// `llm.chat(...)` throws a StructuredOutputError with `code` and `validation` details.
122
+
```
123
+
124
+
For all supported shapes (including plain schema objects) and parsing/validation behavior, see [`responseFormat` docs](./docs/reference.md#responseformat-json-mode--schema-mode).
125
+
95
126
## Supported LLM Providers
96
127
97
128
ResilientLLM comes with built-in support for all text models provided by **OpenAI**, **Anthropic**, **Google/Gemini**, **Ollama** API, etc.
@@ -52,7 +52,6 @@ new ResilientLLM(options?: ResilientLLMOptions)
52
52
|`backoffFactor`|`number`| No |`2`| Exponential backoff multiplier between retries |
53
53
|`onRateLimitUpdate`|`Function`| No |`undefined`| Callback function called when rate limit information is updated |
54
54
|`onError`|`Function`| No |`undefined`| Currently not used (reserved for future use) |
55
-
|`returnOperationMetadata`|`boolean`| No |`false`| When `true`, `chat()` returns a [ChatResponse](#chatresponse) with `metadata` populated instead of a plain string (see [OperationMetadata](#operationmetadata)) |
56
55
57
56
**RateLimitConfig:**
58
57
@@ -79,12 +78,6 @@ const llm = new ResilientLLM({
79
78
80
79
---
81
80
82
-
### ResilientLLM Static Properties
83
-
84
-
_No static properties currently available. Use `ProviderRegistry.getDefaultModels()` to get default models for all providers._
85
-
86
-
---
87
-
88
81
### ResilientLLM Instance Methods
89
82
90
83
#### `chat(conversationHistory, llmOptions?)`
@@ -93,7 +86,7 @@ Sends a chat completion request to the configured LLM provider.
|`apiKey`|`string`| Override API key for this request (takes precedence over ProviderRegistry) |
126
119
|`tools`|`Tool[]`| Array of tool definitions for function calling |
127
-
|`responseFormat`|`Object`| Response format specification (e.g., `{ type: "json_object" }`) |
128
-
|`returnOperationMetadata`|`boolean`| When `true`, this request returns a [ChatResponse](#chatresponse) with `metadata`; overrides the constructor default for this call only |
120
+
|`responseFormat`|`Object \| string`| Response format specification (`json_object`/`json_schema` object shapes, plain schema-like object, or JSON aliases: `"json"`, `"object"`, `"json_object"`) |
121
+
|`outputConfig`|`Object`|**Legacy/migration support**. Anthropic-style alternative structured-output input shape, normalized internally via `responseFormat`. _Prefer `responseFormat` for all new usage._|
122
+
|`response_format`|`Object \| string`|**Legacy/migration support**. Snake_case alias for `responseFormat`; passthrough-friendly for provider-native payloads. _Prefer `responseFormat` for all new usage._|
123
+
|`output_config`|`Object`|**Legacy/migration support**. Snake_case alias for `outputConfig`; passed through as-is when provided. _Prefer `responseFormat` for all new usage._|
124
+
125
+
Use one naming style per field to avoid ambiguity:
126
+
- Prefer camelCase (`responseFormat` or its alias `outputConfig`) in app code.
127
+
- Prefer snake_case (`response_format`, `output_config`) when reusing raw provider payload snippets.
128
+
- Do not send both aliases for the same field in one request; conflicting info may result in error.
|`function.parameters`|`Object`| Function parameters schema (OpenAI format) |
139
139
|`function.input_schema`|`Object`| Function input schema (Anthropic format) |
140
140
141
-
**Returns:**`Promise<string | ChatResponse>`
141
+
**Returns:**`Promise<ChatResponse>`
142
142
143
-
-If `tools` are provided, returns `ChatResponse` with `content` and `toolCalls`; otherwise returns a `string` (the assistant's reply).
144
-
- If `returnOperationMetadata` is set to `true` (constructor or `llmOptions`): Returns a `ChatResponse` with `content` and `metadata` ([OperationMetadata](#operationmetadata))
145
-
- Otherwise: Returns `string` containing
146
-
the assistant's response.
143
+
-Always returns a predictable envelope:
144
+
-`response.content` is the assistant output (string in text mode, parsed object in JSON/schema mode)
145
+
-`response.toolCalls` is included when tool calls are returned
146
+
-`response.metadata` is always included
147
147
148
148
**ChatResponse:**
149
149
150
150
| Property | Type | Description |
151
151
|----------|------|-------------|
152
-
|`content`|`string \| null`| The text content of the response|
152
+
|`content`|`string \| Object \| null`| The assistant content (text by default, normalized JSON object in JSON modes)|
153
153
|`toolCalls`|`Array`| Array of tool call objects (if tools were used) |
154
-
|`metadata`|`OperationMetadata`|Present when `returnOperationMetadata` is `true` (request id, config, timing, retries, rate limiting, usage, etc.) |
- API keys can be provided via `llmOptions.apiKey`, `ProviderRegistry.configure()`, or environment variables
166
169
- The implementation uses `ProviderRegistry` to manage providers and their configurations
167
170
- Response parsing is handled generically using provider-specific `chatConfig` settings
171
+
- For schema mode, validation checks top-level required fields and primitive types (`string`, `number`, `boolean`, `integer`). Schema mismatch errors include a `validation` object with `missingFields`, `extraFields`, and `typeMismatches` arrays
168
172
169
173
**Example:**
170
174
```javascript
@@ -173,8 +177,8 @@ const conversationHistory = [
173
177
{ role:'user', content:'What is the capital of France?' }
174
178
];
175
179
176
-
constresponse=awaitllm.chat(conversationHistory);
177
-
console.log(response); // "The capital of France is Paris."
| `llmOptions` | `ChatOptions` | No | LLM options for the request |
442
445
443
-
**Returns:**`Promise<string | ChatResponse>` - Response from the alternate service
446
+
**Returns:** `Promise<ChatResponse>` - Response from the alternate service
444
447
445
448
**Throws:**
446
449
@@ -507,25 +510,32 @@ interface Message {
507
510
508
511
### ChatResponse
509
512
510
-
Response object returned by `chat()` when tools are used and/or `returnOperationMetadata` is `true`. Otherwise `chat()` returns a plain `string`.
513
+
Response envelope returned by `chat()` on every call.
514
+
515
+
- `content` is the assistant output:
516
+
- text mode -> `string`
517
+
- JSON/schema mode -> parsed JS object
518
+
- `toolCalls` is present when tool calls were returned
519
+
- `metadata` is always included
511
520
512
521
```typescript
513
522
interface ChatResponse {
514
-
content:string|null;
523
+
content: string |Object|null;
515
524
toolCalls?:Array<any>;
516
-
metadata?:OperationMetadata;// present when returnOperationMetadata is true
525
+
metadata: OperationMetadata;
517
526
}
518
527
```
519
528
520
529
### OperationMetadata
521
530
522
-
Operation metadata attached to `ChatResponse.metadata`when `returnOperationMetadata` is `true` (constructor or per-call). Used for observability, logging, and debugging.
531
+
Operation metadata attached to `ChatResponse.metadata`on every call. Used for observability, logging, and debugging.
Use `responseFormat` when you need the assistant response as **JSON**, optionally matching a **particular schema**.
634
+
635
+
- **JSON mode (no schema)**: ensures the reply is a single JSON object (library parses it for you).
636
+
- **Schema mode**: provides a JSON Schema so the library can validate the parsed object and throw `SCHEMA_MISMATCH` when required keys/types don’t match.
637
+
638
+
**Supplying a schema**
639
+
640
+
You can supply a schema in any of these equivalent shapes (pick one and stick to it):
641
+
642
+
- **OpenAI-style wrapper** (recommended when you want to be explicit):
// `result.content` is a parsed JS object when `responseFormat` requests JSON/schema mode.
710
+
```
711
+
712
+
**Validation scope (important)**
713
+
714
+
The built-in validator is intentionally lightweight: it checks **required keys**, **extra keys**, and **primitive types** at the top level (`string`, `number`, `boolean`, `integer`).
715
+
716
+
- Extra keys are enforced only when your schema sets `additionalProperties:false` (and the schema has `properties`).
717
+
- For deeper validation needs (nested objects, enums, regex, oneOf/anyOf, etc.), run your own schema validator after the call.
0 commit comments