@steve31415/baselib 3.39.1 → 3.40.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.
@@ -83,6 +83,7 @@ export async function llmComplete(request) {
83
83
  continue;
84
84
  }
85
85
  const provider = providers[modelEntry.provider];
86
+ const attemptStartedAt = Date.now();
86
87
  try {
87
88
  const result = await provider.complete({
88
89
  apiModelId: modelEntry.apiModelId,
@@ -124,6 +125,7 @@ export async function llmComplete(request) {
124
125
  fallbackModel: modelName,
125
126
  fallbackProvider: modelEntry.provider,
126
127
  attemptsBeforeSuccess: failedAttempts.length,
128
+ ...(request.callSite ? { callSite: request.callSite } : {}),
127
129
  });
128
130
  }
129
131
  return {
@@ -162,6 +164,12 @@ export async function llmComplete(request) {
162
164
  declined: err instanceof LLMError && err.declined === true,
163
165
  attemptNumber: failedAttempts.length,
164
166
  nextModel: modelsToTry[failedAttempts.length] ?? 'none',
167
+ // Which caller, and whether it ran out its own deadline: a timeout tail is a
168
+ // headroom question for that call site, an HTTP error is not (reader task 58b65ec9).
169
+ ...(request.callSite ? { callSite: request.callSite } : {}),
170
+ timedOut: err instanceof LLMError && err.timedOut === true,
171
+ timeoutMs,
172
+ attemptMs: Date.now() - attemptStartedAt,
165
173
  });
166
174
  }
167
175
  }
@@ -140,6 +140,7 @@ export const anthropicProvider = {
140
140
  provider: 'anthropic',
141
141
  model: request.apiModelId,
142
142
  isRetryable: true,
143
+ timedOut: err instanceof Error && err.name === 'AbortError',
143
144
  });
144
145
  }
145
146
  finally {
@@ -125,6 +125,7 @@ export const geminiProvider = {
125
125
  provider: 'gemini',
126
126
  model: request.apiModelId,
127
127
  isRetryable: true,
128
+ timedOut: err instanceof Error && err.name === 'AbortError',
128
129
  });
129
130
  }
130
131
  finally {
@@ -149,6 +149,7 @@ export const openaiProvider = {
149
149
  provider: 'openai',
150
150
  model: request.apiModelId,
151
151
  isRetryable: true,
152
+ timedOut: err instanceof Error && err.name === 'AbortError',
152
153
  });
153
154
  }
154
155
  finally {
@@ -155,6 +155,8 @@ export declare class LLMError extends Error {
155
155
  * not a defect.
156
156
  */
157
157
  declined: boolean;
158
+ /** True when the attempt hit its per-provider `timeoutMs` deadline. */
159
+ timedOut: boolean;
158
160
  constructor(opts: {
159
161
  message: string;
160
162
  provider: ProviderName;
@@ -162,6 +164,7 @@ export declare class LLMError extends Error {
162
164
  statusCode?: number;
163
165
  isRetryable: boolean;
164
166
  declined?: boolean;
167
+ timedOut?: boolean;
165
168
  });
166
169
  }
167
170
  export interface ProviderAdapter {
package/dist/llm/types.js CHANGED
@@ -20,6 +20,8 @@ export class LLMError extends Error {
20
20
  * not a defect.
21
21
  */
22
22
  declined;
23
+ /** True when the attempt hit its per-provider `timeoutMs` deadline. */
24
+ timedOut;
23
25
  constructor(opts) {
24
26
  super(opts.message);
25
27
  this.name = 'LLMError';
@@ -28,5 +30,6 @@ export class LLMError extends Error {
28
30
  this.statusCode = opts.statusCode;
29
31
  this.isRetryable = opts.isRetryable;
30
32
  this.declined = opts.declined ?? false;
33
+ this.timedOut = opts.timedOut ?? false;
31
34
  }
32
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@steve31415/baselib",
3
- "version": "3.39.1",
3
+ "version": "3.40.0",
4
4
  "description": "Plasticine new-world shared platform library: logging, auth, service-to-service auth, db, HTTP, sync, app updates",
5
5
  "type": "module",
6
6
  "license": "MIT",