@devopsplaybook.io/common-utils 1.5.0-beta.14.dd2303d → 1.6.0-beta.15.02b378d

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/dist/src/LLM.d.ts CHANGED
@@ -38,6 +38,13 @@ export interface LLMRequestOptions {
38
38
  jsonMode?: boolean;
39
39
  /** Override the configured model for this call */
40
40
  model?: string;
41
+ /**
42
+ * Override the configured timeout for this call, in milliseconds.
43
+ * Set `0` to disable the timeout entirely, for slow models or very large
44
+ * completions that legitimately exceed the client-level timeout.
45
+ * When omitted, the client-level `timeoutMs` applies.
46
+ */
47
+ timeoutMs?: number;
41
48
  }
42
49
  /**
43
50
  * Normalized response from a chat completion call.
@@ -96,7 +103,8 @@ export declare class LLMClient {
96
103
  * Send a chat completion request.
97
104
  *
98
105
  * @param messages The chat messages to send.
99
- * @param options Optional per-request overrides (JSON mode, model).
106
+ * @param options Optional per-request overrides (JSON mode, model,
107
+ * timeout). `timeoutMs: 0` disables the request timeout.
100
108
  * @returns The first choice content and total token usage.
101
109
  * @throws When the client is disabled, the provider returns an error, or
102
110
  * the response has no choices.
package/dist/src/LLM.js CHANGED
@@ -75,7 +75,8 @@ class LLMClient {
75
75
  * Send a chat completion request.
76
76
  *
77
77
  * @param messages The chat messages to send.
78
- * @param options Optional per-request overrides (JSON mode, model).
78
+ * @param options Optional per-request overrides (JSON mode, model,
79
+ * timeout). `timeoutMs: 0` disables the request timeout.
79
80
  * @returns The first choice content and total token usage.
80
81
  * @throws When the client is disabled, the provider returns an error, or
81
82
  * the response has no choices.
@@ -96,7 +97,9 @@ class LLMClient {
96
97
  body.response_format = { type: "json_object" };
97
98
  }
98
99
  try {
99
- const response = await this.client.post("", body);
100
+ const response = (options === null || options === void 0 ? void 0 : options.timeoutMs) !== undefined
101
+ ? await this.client.post("", body, { timeout: options.timeoutMs })
102
+ : await this.client.post("", body);
100
103
  const choice = (_b = (_a = response.data) === null || _a === void 0 ? void 0 : _a.choices) === null || _b === void 0 ? void 0 : _b[0];
101
104
  if (!choice) {
102
105
  throw new Error("LLM response has no choices");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@devopsplaybook.io/common-utils",
3
- "version": "1.5.0-beta.14.dd2303d",
3
+ "version": "1.6.0-beta.15.02b378d",
4
4
  "description": "Shared utility modules for devopsplaybook.io projects (DB, Config, OTel context, auth/users, notifications, LLM, system helpers)",
5
5
  "keywords": [
6
6
  "Open Telemetry",
package/src/LLM.spec.ts CHANGED
@@ -197,6 +197,61 @@ describe("LLMClient", () => {
197
197
  );
198
198
  });
199
199
 
200
+ it("should override the timeout per request", async () => {
201
+ mockPost.mockResolvedValue({
202
+ data: {
203
+ choices: [{ message: { content: "ok" } }],
204
+ usage: { total_tokens: 1 },
205
+ },
206
+ });
207
+ const client = createEnabledClient();
208
+
209
+ await client.request([{ role: "user", content: "hello" }], {
210
+ timeoutMs: 600000,
211
+ });
212
+
213
+ expect(mockPost).toHaveBeenCalledWith(
214
+ "",
215
+ expect.anything(),
216
+ expect.objectContaining({ timeout: 600000 }),
217
+ );
218
+ });
219
+
220
+ it("should disable the timeout when timeoutMs is 0", async () => {
221
+ mockPost.mockResolvedValue({
222
+ data: {
223
+ choices: [{ message: { content: "ok" } }],
224
+ usage: { total_tokens: 1 },
225
+ },
226
+ });
227
+ const client = createEnabledClient();
228
+
229
+ await client.request([{ role: "user", content: "hello" }], {
230
+ timeoutMs: 0,
231
+ });
232
+
233
+ expect(mockPost).toHaveBeenCalledWith(
234
+ "",
235
+ expect.anything(),
236
+ expect.objectContaining({ timeout: 0 }),
237
+ );
238
+ });
239
+
240
+ it("should not pass a request config when no timeout override is given", async () => {
241
+ mockPost.mockResolvedValue({
242
+ data: {
243
+ choices: [{ message: { content: "ok" } }],
244
+ usage: { total_tokens: 1 },
245
+ },
246
+ });
247
+ const client = createEnabledClient();
248
+
249
+ await client.request([{ role: "user", content: "hello" }]);
250
+
251
+ expect(mockPost).toHaveBeenCalledTimes(1);
252
+ expect(mockPost.mock.calls[0]).toHaveLength(2);
253
+ });
254
+
200
255
  it("should default totalTokens to 0 and content to empty string", async () => {
201
256
  mockPost.mockResolvedValue({
202
257
  data: { choices: [{ message: { content: null } }] },
package/src/LLM.ts CHANGED
@@ -43,6 +43,13 @@ export interface LLMRequestOptions {
43
43
  jsonMode?: boolean;
44
44
  /** Override the configured model for this call */
45
45
  model?: string;
46
+ /**
47
+ * Override the configured timeout for this call, in milliseconds.
48
+ * Set `0` to disable the timeout entirely, for slow models or very large
49
+ * completions that legitimately exceed the client-level timeout.
50
+ * When omitted, the client-level `timeoutMs` applies.
51
+ */
52
+ timeoutMs?: number;
46
53
  }
47
54
 
48
55
  /**
@@ -135,7 +142,8 @@ export class LLMClient {
135
142
  * Send a chat completion request.
136
143
  *
137
144
  * @param messages The chat messages to send.
138
- * @param options Optional per-request overrides (JSON mode, model).
145
+ * @param options Optional per-request overrides (JSON mode, model,
146
+ * timeout). `timeoutMs: 0` disables the request timeout.
139
147
  * @returns The first choice content and total token usage.
140
148
  * @throws When the client is disabled, the provider returns an error, or
141
149
  * the response has no choices.
@@ -162,7 +170,10 @@ export class LLMClient {
162
170
  }
163
171
 
164
172
  try {
165
- const response = await this.client.post("", body);
173
+ const response =
174
+ options?.timeoutMs !== undefined
175
+ ? await this.client.post("", body, { timeout: options.timeoutMs })
176
+ : await this.client.post("", body);
166
177
  const choice = response.data?.choices?.[0];
167
178
  if (!choice) {
168
179
  throw new Error("LLM response has no choices");