Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 16 additions & 21 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -1,34 +1,29 @@
version: 2
updates:
- package-ecosystem: npm
directory: /
multi-ecosystem-groups:
dependencies:
schedule:
interval: weekly
day: monday
time: "09:00"
timezone: America/Chicago
open-pull-requests-limit: 10
commit-message:
prefix: chore
labels:
- dependencies
updates:
- package-ecosystem: npm
directory: /
patterns: ["*"]
multi-ecosystem-group: dependencies
ignore:
# tsup's declaration bundler requires the TypeScript 6 compiler API.
- dependency-name: typescript
versions: [">=7"]
groups:
npm-dependencies:
patterns:
- "*"
npm-security:
applies-to: security-updates
patterns: ["*"]
- package-ecosystem: github-actions
directory: /
schedule:
interval: weekly
day: monday
time: "09:15"
timezone: America/Chicago
open-pull-requests-limit: 5
commit-message:
prefix: chore
labels:
- dependencies
groups:
github-actions:
patterns:
- "*"
patterns: ["*"]
multi-ecosystem-group: dependencies
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
with:
filter: tree:0
fetch-depth: 0
- uses: pnpm/action-setup@v6.0.9
- uses: pnpm/action-setup@v6.0.10
name: Install pnpm
with:
run_install: false
Expand All @@ -49,7 +49,7 @@ jobs:
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm exec nx run-many -t release-policy-check lint test typecheck build skills-validate package-audit --projects=foundry-ai --outputStyle=static
- name: Verify AI SDK 7 compatibility
- name: Verify AI SDK 6 and 7 compatibility
run: |
compatibility_dir="$RUNNER_TEMP/foundry-ai-sdk-7"
mkdir -p "$compatibility_dir"
Expand All @@ -61,6 +61,9 @@ jobs:
npm install ./nyrra-foundry-ai-*.tgz ai@^7.0.0 @ai-sdk/anthropic@^4.0.0 @ai-sdk/google@^4.0.0 @ai-sdk/openai@^4.0.0 @types/json-schema @types/node tsx typescript
npx tsc --ignoreConfig --noEmit --module nodenext --moduleResolution nodenext --strict --target es2022 --types node check-ai-sdk-compatibility.ts
npx tsx check-ai-sdk-compatibility.ts v4
npm install ai@6.0.224 @ai-sdk/anthropic@3.0.96 @ai-sdk/google@3.0.91 @ai-sdk/openai@3.0.84
npx tsc --ignoreConfig --noEmit --module nodenext --moduleResolution nodenext --strict --target es2022 --types node check-ai-sdk-compatibility.ts
npx tsx check-ai-sdk-compatibility.ts v3
npm install ai@7.0.0-beta.187 @ai-sdk/anthropic@4.0.0-beta.69 @ai-sdk/google@4.0.0-beta.85 @ai-sdk/openai@4.0.0-beta.77
npx tsc --ignoreConfig --noEmit --module nodenext --moduleResolution nodenext --strict --target es2022 --types node check-ai-sdk-compatibility.ts
npx tsx check-ai-sdk-compatibility.ts v4
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
with:
ref: main
fetch-depth: 0
- uses: pnpm/action-setup@v6.0.9
- uses: pnpm/action-setup@v6.0.10
with:
run_install: false
- uses: actions/setup-node@v7
Expand Down Expand Up @@ -88,7 +88,7 @@ jobs:
with:
ref: main
fetch-depth: 0
- uses: pnpm/action-setup@v6.0.9
- uses: pnpm/action-setup@v6.0.10
with:
run_install: false
- uses: actions/setup-node@v7
Expand Down
2 changes: 1 addition & 1 deletion biome.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/2.5.3/schema.json",
"$schema": "https://biomejs.dev/schemas/2.5.13/schema.json",
"vcs": {
"enabled": true,
"clientKind": "git",
Expand Down
4 changes: 2 additions & 2 deletions examples/advanced/tool-calling-parallel-devtools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,10 @@ function summarizeTool(toolName: string, input: unknown, output?: unknown): Tool

function summarizeUsage(usage: LanguageModelUsage): UsageSummary {
return {
cachedInputTokens: usage.inputTokenDetails.cacheReadTokens ?? usage.cachedInputTokens,
cachedInputTokens: usage.inputTokenDetails.cacheReadTokens,
inputTokens: usage.inputTokens,
outputTokens: usage.outputTokens,
reasoningTokens: usage.outputTokenDetails.reasoningTokens ?? usage.reasoningTokens,
reasoningTokens: usage.outputTokenDetails.reasoningTokens,
totalTokens: usage.totalTokens,
};
}
Expand Down
37 changes: 19 additions & 18 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,32 +38,33 @@
"lodash@4": "4.18.0",
"picomatch": ">=4.0.4",
"minimatch@<10": ">=10.0.0",
"qs@6": "6.15.2",
"vite@6": "6.4.3"
"qs@6": "6.15.2"
}
},
"devDependencies": {
"@ai-sdk/devtools": "0.0.24",
"@ai-sdk/anthropic": "3.0.96",
"@ai-sdk/google": "3.0.91",
"@ai-sdk/openai": "3.0.84",
"@biomejs/biome": "2.5.3",
"@ai-sdk/anthropic": "4.0.52",
"@ai-sdk/devtools": "1.0.18",
"@ai-sdk/google": "4.0.67",
"@ai-sdk/openai": "4.0.65",
"@ai-sdk/otel": "1.0.97",
"@biomejs/biome": "2.5.13",
"@exalabs/ai-sdk": "2.1.0",
"@nx/js": "22.7.7",
"@swc-node/register": "~1.11.1",
"@swc/core": "~1.15.43",
"@nx/js": "23.2.1",
"@opentelemetry/api": "1.9.1",
"@swc-node/register": "~1.12.1",
"@swc/core": "~1.16.2",
"@swc/helpers": "~0.5.23",
"@tanstack/intent": "0.0.44",
"@types/node": "25.9.5",
"ai": "6.0.224",
"nx": "22.7.7",
"@tanstack/intent": "0.4.0",
"@types/node": "26.5.1",
"ai": "7.0.97",
"nx": "23.2.1",
"tslib": "2.8.1",
"tsup": "8.5.1",
"tsx": "4.23.0",
"tsx": "4.23.13",
"typescript": "6.0.3",
"vite": "6.4.3",
"vitest": "4.1.10",
"vite": "8.3.0",
"vitest": "5.0.0",
"yaml": "2.9.0",
"zod": "4.4.3"
"zod": "4.6.2"
}
}
6 changes: 5 additions & 1 deletion packages/foundry-ai/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,11 @@
"access": "public"
},
"devDependencies": {
"@tanstack/intent": "0.0.44"
"@ai-sdk/anthropic": "4.0.52",
"@ai-sdk/google": "4.0.67",
"@ai-sdk/openai": "4.0.65",
"@tanstack/intent": "0.4.0",
"ai": "7.0.97"
},
"peerDependencies": {
"ai": "^6.0.141 || ^7.0.0-beta.187",
Expand Down
54 changes: 31 additions & 23 deletions packages/foundry-ai/src/__tests__/helpers/live-capabilities.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { readFileSync } from 'node:fs';
import { mkdir, writeFile } from 'node:fs/promises';
import { join, resolve } from 'node:path';
import process from 'node:process';
import type { TelemetrySettings } from 'ai';
import { OpenTelemetry } from '@ai-sdk/otel';
import { type Context, trace } from '@opentelemetry/api';
import type { Telemetry, TelemetryOptions } from 'ai';
import { MODEL_CATALOG, resolveKnownModelMetadata, resolveModelRid } from '../../models/catalog.js';
import { loadLiveFoundryConfig } from './live-foundry.js';

Expand Down Expand Up @@ -344,40 +346,46 @@ export class LiveCapabilityRecorder {
capability: string,
provider: LiveProvider,
modelId: string,
): TelemetrySettings {
): TelemetryOptions {
const integration = {
onStart: (event: unknown) => this.recordEvent(caseKey, 'onStart', event),
onStepStart: (event: unknown) => this.recordEvent(caseKey, 'onStepStart', event),
onToolCallStart: (event: unknown) => this.recordEvent(caseKey, 'onToolCallStart', event),
onToolCallFinish: (event: unknown) => this.recordEvent(caseKey, 'onToolCallFinish', event),
onStepFinish: (event: unknown) => this.recordEvent(caseKey, 'onStepFinish', event),
onFinish: (event: unknown) => this.recordEvent(caseKey, 'onFinish', event),
};
onToolExecutionStart: (event: unknown) => this.recordEvent(caseKey, 'onToolCallStart', event),
onToolExecutionEnd: (event: unknown) => this.recordEvent(caseKey, 'onToolCallFinish', event),
onStepEnd: (event: unknown) => this.recordEvent(caseKey, 'onStepFinish', event),
onEnd: (event: unknown) => this.recordEvent(caseKey, 'onFinish', event),
} satisfies Telemetry;
const tracer = new LocalFileTracer(caseKey, this);

return {
isEnabled: true,
functionId: `${provider}.${capability}`,
integrations: integration,
metadata: {
capability,
caseKey,
gitSha: this.record.gitSha,
modelId,
provider,
runId: this.record.runId,
testFile: 'packages/foundry-ai/src/__tests__/foundry.live.test.ts',
testName: caseKey,
},
integrations: [
integration,
new OpenTelemetry({
tracer: tracer as unknown as NonNullable<
ConstructorParameters<typeof OpenTelemetry>[0]
>['tracer'],
enrichSpan: () => ({
capability,
caseKey,
gitSha: this.record.gitSha,
modelId,
provider,
runId: this.record.runId,
testFile: 'packages/foundry-ai/src/__tests__/foundry.live.test.ts',
testName: caseKey,
}),
}),
],
recordInputs: true,
recordOutputs: true,
tracer: tracer as unknown as TelemetrySettings['tracer'],
} satisfies TelemetrySettings;
} satisfies TelemetryOptions;
}

async runCase<T>(
spec: CapabilityCaseSpec,
fn: (telemetry: TelemetrySettings, caseKey: string) => Promise<T>,
fn: (telemetry: TelemetryOptions, caseKey: string) => Promise<T>,
): Promise<T | undefined> {
const startedAt = Date.now();
const caseKey = createCaseKey(spec.provider, spec.modelId, spec.capability);
Expand Down Expand Up @@ -623,8 +631,8 @@ class LocalFileTracer {
}
}

startSpan(name: string, options?: { attributes?: Record<string, unknown> }) {
const parent = this.activeSpans.at(-1);
startSpan(name: string, options?: { attributes?: Record<string, unknown> }, context?: Context) {
const parent = context ? trace.getSpanContext(context) : this.activeSpans.at(-1)?.spanContext();
const span = new LocalSpanRecord({
attributes: options?.attributes,
caseKey: this.caseKey,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { OpenAILanguageModelResponsesOptions } from '@ai-sdk/openai';
import { tool } from 'ai';
import { type Tool, tool } from 'ai';
import { z } from 'zod';
import { resolveModelRid } from '../../models/catalog.js';
import { isKnownOpenAIReasoningTarget } from '../../models/openai-models.js';
Expand All @@ -24,16 +24,17 @@ export const structuredToolSchema = z.object({
summary: z.string().min(1),
});

export const regulatorySignalTool = tool({
description: 'Returns a deterministic regulatory status for testing tool loops.',
inputSchema: z.object({
topic: z.string().min(1),
}),
execute: async ({ topic }) => ({
status: 'verified',
topic,
}),
});
export const regulatorySignalTool: Tool<{ topic: string }, { status: string; topic: string }> =
tool({
description: 'Returns a deterministic regulatory status for testing tool loops.',
inputSchema: z.object({
topic: z.string().min(1),
}),
execute: async ({ topic }) => ({
status: 'verified',
topic,
}),
});

export function createMessageHistoryFixture() {
return [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import type { wrapLanguageModel } from 'ai';

export type TestLanguageModel = Parameters<typeof wrapLanguageModel>[0]['model'];
export type TestLanguageModel = Extract<
Parameters<typeof wrapLanguageModel>[0]['model'],
{ specificationVersion: 'v3' }
>;
export type TestCallOptions = Parameters<TestLanguageModel['doGenerate']>[0];

interface TestLanguageModelState {
Expand Down
Loading
Loading