@inflexa-ai/harness 0.14.1 → 0.14.2

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/index.d.ts CHANGED
@@ -39,7 +39,7 @@ export type { AgentSession, RequestSession, RunSession, Identity, Scope, Credent
39
39
  export { makeLocalAuth } from "./auth/local-auth-context.js";
40
40
  export { createAnthropicProvider } from "./providers/anthropic.js";
41
41
  export type { AnthropicProviderDeps } from "./providers/anthropic.js";
42
- export { createConfiguredAiSdkProvider } from "./providers/ai-sdk.js";
42
+ export { createConfiguredAiSdkProvider, DEFAULT_MAX_OUTPUT_TOKENS } from "./providers/ai-sdk.js";
43
43
  export type { AiSdkProviderConfig, ConfiguredAiSdkProviderDeps } from "./providers/ai-sdk.js";
44
44
  export { createEmbeddingProvider } from "./providers/embedding.js";
45
45
  export type { EmbeddingProviderDeps } from "./providers/embedding.js";
package/dist/index.js CHANGED
@@ -48,7 +48,7 @@ export { createAnthropicProvider } from "./providers/anthropic.js";
48
48
  // union discriminated over the `anthropic` and `openai-compatible` kinds — with
49
49
  // `ConfiguredAiSdkProviderDeps` as its argument shape. `createAnthropicProvider`
50
50
  // above is a convenience over this union's `anthropic` arm.
51
- export { createConfiguredAiSdkProvider } from "./providers/ai-sdk.js";
51
+ export { createConfiguredAiSdkProvider, DEFAULT_MAX_OUTPUT_TOKENS } from "./providers/ai-sdk.js";
52
52
  export { createEmbeddingProvider } from "./providers/embedding.js";
53
53
  // Prompt caching. `PromptCachePolicy` is the harness's vendor-neutral cache
54
54
  // directive; a composition root sets it per run via `RunAgentOptions.promptCache`
@@ -13,11 +13,25 @@ export declare const RETRY_MAX_RETRIES = 10;
13
13
  export declare const RETRY_INITIAL_DELAY_MS = 2000;
14
14
  export declare const RETRY_BACKOFF_FACTOR = 2;
15
15
  export declare const RETRY_MAX_DELAY_MS = 30000;
16
+ /**
17
+ * Output-token ceiling requested when a config names none — a floor against a
18
+ * provider default, not a target. `@ai-sdk/anthropic` resolves an unset value
19
+ * from a capability table that lags Anthropic's releases and falls back to 4096
20
+ * for ids it does not know, so the newest models silently truncate mid
21
+ * tool-call. The SDK clamps this down per known model (opus-4-x to 32k,
22
+ * claude-3-haiku to 4096), so it cannot over-request one it recognizes.
23
+ *
24
+ * Lower it per-config for servers that validate `prompt + max_tokens <= context`
25
+ * (vLLM and similar) against a small-context model.
26
+ */
27
+ export declare const DEFAULT_MAX_OUTPUT_TOKENS = 64000;
16
28
  export interface AiSdkProviderDeps {
17
29
  readonly model: LanguageModel;
18
30
  readonly resolveBilling: ResolveBilling;
19
31
  readonly capabilities?: Partial<ProviderCapabilities>;
20
32
  readonly logger?: Logger;
33
+ /** Output-token ceiling per request. Defaults to {@link DEFAULT_MAX_OUTPUT_TOKENS}. */
34
+ readonly maxOutputTokens?: number;
21
35
  }
22
36
  /**
23
37
  * Connection + model configuration for one `ChatProvider`, discriminated by
@@ -36,6 +50,8 @@ export type AiSdkProviderConfig = {
36
50
  readonly model: string;
37
51
  readonly fetch?: FetchLike;
38
52
  readonly capabilities?: Partial<ProviderCapabilities>;
53
+ /** Output-token ceiling per request. Defaults to {@link DEFAULT_MAX_OUTPUT_TOKENS}. */
54
+ readonly maxOutputTokens?: number;
39
55
  } | {
40
56
  readonly kind: "openai-compatible";
41
57
  readonly name: string;
@@ -44,6 +60,8 @@ export type AiSdkProviderConfig = {
44
60
  readonly model: string;
45
61
  readonly fetch?: FetchLike;
46
62
  readonly capabilities?: Partial<ProviderCapabilities>;
63
+ /** Output-token ceiling per request. Defaults to {@link DEFAULT_MAX_OUTPUT_TOKENS}. */
64
+ readonly maxOutputTokens?: number;
47
65
  };
48
66
  export interface ConfiguredAiSdkProviderDeps {
49
67
  readonly config: AiSdkProviderConfig;
@@ -18,6 +18,38 @@ export const RETRY_MAX_RETRIES = 10;
18
18
  export const RETRY_INITIAL_DELAY_MS = 2_000;
19
19
  export const RETRY_BACKOFF_FACTOR = 2;
20
20
  export const RETRY_MAX_DELAY_MS = 30_000;
21
+ /**
22
+ * Output-token ceiling requested when a config names none — a floor against a
23
+ * provider default, not a target. `@ai-sdk/anthropic` resolves an unset value
24
+ * from a capability table that lags Anthropic's releases and falls back to 4096
25
+ * for ids it does not know, so the newest models silently truncate mid
26
+ * tool-call. The SDK clamps this down per known model (opus-4-x to 32k,
27
+ * claude-3-haiku to 4096), so it cannot over-request one it recognizes.
28
+ *
29
+ * Lower it per-config for servers that validate `prompt + max_tokens <= context`
30
+ * (vLLM and similar) against a small-context model.
31
+ */
32
+ export const DEFAULT_MAX_OUTPUT_TOKENS = 64_000;
33
+ /**
34
+ * Point the AI SDK's warning logger at the harness `Logger`.
35
+ *
36
+ * The SDK writes warnings itself — `process.emitWarning`, else `console.warn` —
37
+ * and offers only this process-global hook to redirect them. Left alone it
38
+ * bypasses the Logger seam entirely and lands on the stdout a TUI host owns;
39
+ * `maxOutputTokens` makes that routine, since the SDK warns on every request
40
+ * whose ceiling it clamps. Installed once: the handler is global, and every
41
+ * provider over a boot shares one sink.
42
+ */
43
+ function routeSdkWarningsTo(logger) {
44
+ const g = globalThis;
45
+ if (g.AI_SDK_LOG_WARNINGS !== undefined)
46
+ return;
47
+ g.AI_SDK_LOG_WARNINGS = (options) => {
48
+ for (const warning of options.warnings) {
49
+ logger.warn("ai sdk warning", { provider: options.provider, model: options.model, warning });
50
+ }
51
+ };
52
+ }
21
53
  function workloadOf(session) {
22
54
  return `${session.scope.kind}:${scopeWorkloadId(session.scope)}`;
23
55
  }
@@ -246,6 +278,8 @@ function sanitizeMessages(messages) {
246
278
  export function createAiSdkProvider(deps) {
247
279
  const capabilities = { toolCalling: deps.capabilities?.toolCalling ?? true };
248
280
  const logger = (deps.logger ?? createNoopLogger()).named("providers.ai-sdk");
281
+ const maxOutputTokens = deps.maxOutputTokens ?? DEFAULT_MAX_OUTPUT_TOKENS;
282
+ routeSdkWarningsTo(logger);
249
283
  function chat(req, session, signal) {
250
284
  const run = async () => {
251
285
  const retry = createRetry(signal, logger);
@@ -260,6 +294,7 @@ export function createAiSdkProvider(deps) {
260
294
  messages: sanitizeMessages(req.messages),
261
295
  tools: req.tools,
262
296
  toolChoice: req.toolChoice ?? "auto",
297
+ maxOutputTokens,
263
298
  stopWhen: [],
264
299
  // The harness envelope owns retries; leaving the SDK default in
265
300
  // place would multiply attempts (10 outer × 3 inner).
@@ -298,6 +333,7 @@ export function createAiSdkProvider(deps) {
298
333
  messages: sanitizeMessages(req.messages),
299
334
  tools: req.tools,
300
335
  toolChoice: req.toolChoice ?? "auto",
336
+ maxOutputTokens,
301
337
  stopWhen: [],
302
338
  maxRetries: 0,
303
339
  headers,
@@ -372,6 +408,7 @@ export function createConfiguredAiSdkProvider(deps) {
372
408
  resolveBilling: deps.resolveBilling,
373
409
  capabilities: config.capabilities,
374
410
  logger: deps.logger,
411
+ ...(config.maxOutputTokens !== undefined ? { maxOutputTokens: config.maxOutputTokens } : {}),
375
412
  });
376
413
  }
377
414
  const provider = createOpenAICompatible({
@@ -385,5 +422,6 @@ export function createConfiguredAiSdkProvider(deps) {
385
422
  resolveBilling: deps.resolveBilling,
386
423
  capabilities: config.capabilities,
387
424
  logger: deps.logger,
425
+ ...(config.maxOutputTokens !== undefined ? { maxOutputTokens: config.maxOutputTokens } : {}),
388
426
  });
389
427
  }
@@ -14,6 +14,8 @@ export interface AnthropicProviderDeps {
14
14
  readonly resolveBilling: ResolveBilling;
15
15
  readonly fetch?: FetchLike;
16
16
  readonly logger?: Logger;
17
+ /** Output-token ceiling per request. Defaults to `DEFAULT_MAX_OUTPUT_TOKENS`. */
18
+ readonly maxOutputTokens?: number;
17
19
  }
18
20
  /**
19
21
  * Convenience over the `anthropic` arm of the public `AiSdkProviderConfig`
@@ -22,6 +22,7 @@ export function createAnthropicProvider(deps) {
22
22
  model: deps.model,
23
23
  fetch: deps.fetch,
24
24
  capabilities: { toolCalling: true },
25
+ ...(deps.maxOutputTokens !== undefined ? { maxOutputTokens: deps.maxOutputTokens } : {}),
25
26
  },
26
27
  });
27
28
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inflexa-ai/harness",
3
- "version": "0.14.1",
3
+ "version": "0.14.2",
4
4
  "description": "Host-agnostic bioinformatics agent harness \u2014 hand-rolled agent loop, DBOS-durable workflows, sandboxed compute.",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -44,7 +44,7 @@
44
44
  "typecheck": "tsc --noEmit"
45
45
  },
46
46
  "dependencies": {
47
- "@ai-sdk/anthropic": "^4.0.15",
47
+ "@ai-sdk/anthropic": "^4.0.20",
48
48
  "@ai-sdk/openai-compatible": "^3.0.10",
49
49
  "@ai-sdk/provider": "^4.0.3",
50
50
  "@ai-sdk/provider-utils": "5.0.10",