Update test framework: fix run_tests.py to support all test files, add auto-import-check for test files

This commit is contained in:
qiaoxinjiu
2026-05-09 15:11:30 +08:00
parent eb053a347f
commit eaba8328da
21739 changed files with 2236758 additions and 719 deletions

21
node_modules/mcp-evals/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 Matthew Lenhard
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

225
node_modules/mcp-evals/README.md generated vendored Normal file
View File

@@ -0,0 +1,225 @@
# MCP Evals
A Node.js package and GitHub Action for evaluating MCP (Model Context Protocol) tool implementations using LLM-based scoring, **with built-in observability support**. This helps ensure your MCP server's tools are working correctly, performing well, and are fully observable with integrated monitoring and metrics.
## Installation
### As a Node.js Package
```bash
npm install mcp-evals
```
### As a GitHub Action
Add the following to your workflow file:
```yaml
name: Run MCP Evaluations
on:
pull_request:
types: [opened, synchronize, reopened]
jobs:
evaluate:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
- name: Install dependencies
run: npm install
- name: Run MCP Evaluations
uses: mclenhard/mcp-evals@v1.0.9
with:
evals_path: 'src/evals/evals.ts' # Can also use .yaml files
server_path: 'src/index.ts'
openai_api_key: ${{ secrets.OPENAI_API_KEY }}
model: 'gpt-4' # Optional, defaults to gpt-4
```
## Usage -- Evals
### 1. Create Your Evaluation File
You can create evaluation configurations in either TypeScript or YAML format.
#### Option A: TypeScript Configuration
Create a file (e.g., `evals.ts`) that exports your evaluation configuration:
```typescript
import { EvalConfig } from 'mcp-evals';
import { openai } from "@ai-sdk/openai";
import { grade, EvalFunction} from "mcp-evals";
const weatherEval: EvalFunction = {
name: 'Weather Tool Evaluation',
description: 'Evaluates the accuracy and completeness of weather information retrieval',
run: async () => {
const result = await grade(openai("gpt-4"), "What is the weather in New York?");
return JSON.parse(result);
}
};
const config: EvalConfig = {
model: openai("gpt-4"),
evals: [weatherEval]
};
export default config;
export const evals = [
weatherEval,
// add other evals here
];
```
#### Option B: YAML Configuration
For simpler configuration, you can use YAML format (e.g., `evals.yaml`):
```yaml
# Model configuration
model:
provider: openai # 'openai' or 'anthropic'
name: gpt-4o # Model name
# api_key: sk-... # Optional, uses OPENAI_API_KEY env var by default
# List of evaluations to run
evals:
- name: weather_query_basic
description: Test basic weather information retrieval
prompt: "What is the current weather in San Francisco?"
expected_result: "Should return current weather data for San Francisco including temperature, conditions, etc."
- name: weather_forecast
description: Test weather forecast functionality
prompt: "Can you give me the 3-day weather forecast for Seattle?"
expected_result: "Should return a multi-day forecast for Seattle"
- name: invalid_location
description: Test handling of invalid location requests
prompt: "What's the weather in Atlantis?"
expected_result: "Should handle invalid location gracefully with appropriate error message"
```
### 2. Run the Evaluations
#### As a Node.js Package
You can run the evaluations using the CLI with either TypeScript or YAML files:
```bash
# Using TypeScript configuration
npx mcp-eval path/to/your/evals.ts path/to/your/server.ts
# Using YAML configuration
npx mcp-eval path/to/your/evals.yaml path/to/your/server.ts
```
#### As a GitHub Action
The action will automatically:
1. Run your evaluations
2. Post the results as a comment on the PR
3. Update the comment if the PR is updated
## Evaluation Results
Each evaluation returns an object with the following structure:
```typescript
interface EvalResult {
accuracy: number; // Score from 1-5
completeness: number; // Score from 1-5
relevance: number; // Score from 1-5
clarity: number; // Score from 1-5
reasoning: number; // Score from 1-5
overall_comments: string; // Summary of strengths and weaknesses
}
```
## Configuration
### Environment Variables
- `OPENAI_API_KEY`: Your OpenAI API key (required for OpenAI models)
- `ANTHROPIC_API_KEY`: Your Anthropic API key (required for Anthropic models)
> [!NOTE]
> If you're using this GitHub Action with open source software, enable data sharing in the OpenAI billing dashboard to claim 2.5 million free GPT-4o mini tokens per day, making this Action effectively free to use.
### Evaluation Configuration
#### TypeScript Configuration
The `EvalConfig` interface requires:
- `model`: The language model to use for evaluation (e.g., GPT-4)
- `evals`: Array of evaluation functions to run
Each evaluation function must implement:
- `name`: Name of the evaluation
- `description`: Description of what the evaluation tests
- `run`: Async function that takes a model and returns an `EvalResult`
#### YAML Configuration
YAML configuration files support:
**Model Configuration:**
- `provider`: Either 'openai' or 'anthropic'
- `name`: Model name (e.g., 'gpt-4o', 'claude-3-opus-20240229')
- `api_key`: Optional API key (uses environment variables by default)
**Evaluation Configuration:**
- `name`: Name of the evaluation (required)
- `description`: Description of what the evaluation tests (required)
- `prompt`: The prompt to send to your MCP server (required)
- `expected_result`: Optional description of expected behavior
**Supported File Extensions:** `.yaml`, `.yml`
## Usage -- Monitoring
> **Note:** The metrics functionality is still in alpha. Features and APIs may change, and breaking changes are possible.
1. Add the following to your application before you initilize the MCP server.
```typescript
import { metrics } from 'mcp-evals';
metrics.initialize(9090, { enableTracing: true, otelEndpoint: 'http://localhost:4318/v1/traces' });
```
2. Start the monitoring stack:
```bash
docker-compose up -d
```
3. Run your MCP server and it will automatically connect to the monitoring stack.
### Accessing the Dashboards
- **Prometheus**: http://localhost:9090
- **Grafana**: http://localhost:3000 (username: admin, password: admin)
- **Jaeger UI**: http://localhost:16686
## Metrics Available
- **Tool Calls**: Number of tool calls by tool name
- **Tool Errors**: Number of errors by tool name
- **Tool Latency**: Distribution of latency times by tool name
## License
MIT

3
node_modules/mcp-evals/dist/cli.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
#!/usr/bin/env node
export {};
//# sourceMappingURL=cli.d.ts.map

1
node_modules/mcp-evals/dist/cli.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}

66
node_modules/mcp-evals/dist/cli.js generated vendored Normal file
View File

@@ -0,0 +1,66 @@
#!/usr/bin/env node
import { runAllEvals } from './index.js';
import * as dotenv from 'dotenv';
import { loadYamlEvalConfig } from './yaml-loader.js';
import path from 'path';
import { createRequire } from 'module';
// Load .env file
dotenv.config();
// Register tsx as a loader
const require = createRequire(import.meta.url);
require('tsx');
async function main() {
const userEvalsPath = process.argv[2];
const userServerPath = process.argv[3];
if (!userEvalsPath) {
console.error('Please provide a path to your evals file');
console.error('Usage: npx mcp-eval <evals-path> <server-path>');
console.error(' <evals-path> can be a .ts/.js or .yaml/.yml file');
process.exit(1);
}
if (!userServerPath) {
console.error('Please provide a path to your server file');
console.error('Usage: npx mcp-eval <evals-path> <server-path>');
console.error(' <evals-path> can be a .ts/.js or .yaml/.yml file');
process.exit(1);
}
const absoluteEvalsPath = path.resolve(process.cwd(), userEvalsPath);
const absoluteServerPath = path.resolve(process.cwd(), userServerPath);
console.log('Running evals file:', absoluteEvalsPath);
console.log('Using server file:', absoluteServerPath);
try {
let config;
// Check file extension to determine how to load the config
const fileExtension = path.extname(absoluteEvalsPath).toLowerCase();
if (fileExtension === '.yaml' || fileExtension === '.yml') {
// Load YAML configuration
config = loadYamlEvalConfig(absoluteEvalsPath, absoluteServerPath);
}
else {
// Import the TypeScript/JavaScript file
const module = await import(absoluteEvalsPath);
config = module.default;
if (!config || !config.evals) {
console.error('Invalid config: must export a default config with evals array');
process.exit(1);
}
}
console.log('Running all evaluations...\n');
const results = await runAllEvals(config, absoluteServerPath);
console.log('\nEvaluation Results:');
for (const [name, result] of results.entries()) {
console.log(`\n${name}:`);
console.log(JSON.stringify(result, null, 2));
}
process.exit(0);
}
catch (error) {
console.error('Error running evaluations:', error);
process.exit(1);
}
}
main().catch(error => {
console.error('Error running evaluations:', error);
process.exit(1);
});
//# sourceMappingURL=cli.js.map

1
node_modules/mcp-evals/dist/cli.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,KAAK,MAAM,MAAM,QAAQ,CAAC;AAEjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AAEvC,iBAAiB;AACjB,MAAM,CAAC,MAAM,EAAE,CAAC;AAEhB,2BAA2B;AAC3B,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,OAAO,CAAC,KAAK,CAAC,CAAC;AAEf,KAAK,UAAU,IAAI;IACjB,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACtC,MAAM,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAEvC,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;QAC1D,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,2CAA2C,CAAC,CAAC;QAC3D,OAAO,CAAC,KAAK,CAAC,gDAAgD,CAAC,CAAC;QAChE,OAAO,CAAC,KAAK,CAAC,yDAAyD,CAAC,CAAC;QACzE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,MAAM,iBAAiB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,CAAC,CAAC;IACrE,MAAM,kBAAkB,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,cAAc,CAAC,CAAC;IAEvE,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,iBAAiB,CAAC,CAAC;IACtD,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,kBAAkB,CAAC,CAAC;IAEtD,IAAI,CAAC;QACH,IAAI,MAAkB,CAAC;QAEvB,2DAA2D;QAC3D,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,CAAC,WAAW,EAAE,CAAC;QAEpE,IAAI,aAAa,KAAK,OAAO,IAAI,aAAa,KAAK,MAAM,EAAE,CAAC;YAC1D,0BAA0B;YAC1B,MAAM,GAAG,kBAAkB,CAAC,iBAAiB,EAAE,kBAAkB,CAAC,CAAC;QACrE,CAAC;aAAM,CAAC;YACN,yCAAyC;YACzC,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,iBAAiB,CAAC,CAAC;YAC/C,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC;YAExB,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;gBAC7B,OAAO,CAAC,KAAK,CAAC,+DAA+D,CAAC,CAAC;gBAC/E,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;QAE9D,OAAO,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACrC,KAAK,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,CAAC;YAC1B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;QACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE;IACnB,OAAO,CAAC,KAAK,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}

9
node_modules/mcp-evals/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
import { type LanguageModel } from "ai";
import { EvalConfig } from './types.js';
export declare function runEvals(model: LanguageModel | undefined, prompt: string, serverPath: string): Promise<string>;
export declare function grade(model: LanguageModel | undefined, prompt: string, serverPath?: string): Promise<string>;
export declare function runAllEvals(config: EvalConfig, serverPath: string): Promise<Map<string, any>>;
export * from './types.js';
export { metrics } from './metrics.js';
export type { MetricsConfig } from './metrics.js';
//# sourceMappingURL=index.d.ts.map

1
node_modules/mcp-evals/dist/index.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,IAAI,CAAC;AAEZ,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAGxC,wBAAsB,QAAQ,CAAC,KAAK,EAAE,aAAa,YAAa,EAAE,MAAM,EAAE,MAAM,EAAC,UAAU,EAAE,MAAM,mBAuClG;AAED,wBAAsB,KAAK,CAAC,KAAK,EAAE,aAAa,YAAa,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,mBAwCjG;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,6BAiCvE;AAGD,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC"}

112
node_modules/mcp-evals/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,112 @@
import { Experimental_StdioMCPTransport } from "ai/mcp-stdio";
import { experimental_createMCPClient, streamText, } from "ai";
import { openai } from "@ai-sdk/openai";
const defaultModel = openai("gpt-4o");
export async function runEvals(model = defaultModel, prompt, serverPath) {
const transport = new Experimental_StdioMCPTransport({
command: "tsx",
args: [serverPath],
env: Object.fromEntries(Object.entries(process.env).filter(([_, v]) => v !== undefined))
});
const client = await experimental_createMCPClient({
transport,
});
const tools = await client.tools();
try {
const result = streamText({
model,
tools,
system: "You are an assistant responsible for evaluating the results of calling various tools. Given the user's query, use the tools available to you to answer the question.",
prompt,
maxRetries: 1,
maxSteps: 10,
onError: ({ error }) => {
console.error(error);
},
});
let fullText = '';
for await (const chunk of result.fullStream) {
if (chunk.type === 'text-delta') {
fullText += chunk.textDelta;
}
}
return fullText;
}
catch (error) {
console.error('Error in runEvals:', error);
throw error;
}
}
export async function grade(model = defaultModel, prompt, serverPath) {
const finalServerPath = serverPath || process.argv[3]; // Use provided serverPath or CLI args
if (!finalServerPath) {
throw new Error('Server path not provided');
}
const result = await runEvals(model, prompt, finalServerPath);
const evalSystemPromt = `You are an expert evaluator assessing how well an LLM answers a given question. Review the provided answer and score it from 1 to 5 in each of the following categories:
Accuracy Does the answer contain factual errors or hallucinations?
Completeness Does the answer fully address all parts of the question?
Relevance Is the information directly related to the question?
Clarity Is the explanation easy to understand and well-structured?
Reasoning Does the answer show logical thinking or provide evidence or rationale?
Return your evaluation as a JSON object in the format:
{
"accuracy": 1-5,
"completeness": 1-5,
"relevance": 1-5,
"clarity": 1-5,
"reasoning": 1-5,
"overall_comments": "A short paragraph summarizing the strengths and weaknesses of the answer."
}`;
const evalPromt = `Here is the user input: ${prompt}
Here is the LLM's answer: ${result}`;
const evalResult = streamText({
model,
maxRetries: 1,
maxSteps: 10,
system: evalSystemPromt,
prompt: evalPromt,
onError: ({ error }) => {
console.error(error);
},
});
for await (const _ of evalResult.fullStream) {
}
return await evalResult.text;
}
export async function runAllEvals(config, serverPath) {
const results = new Map();
let transport;
try {
transport = new Experimental_StdioMCPTransport({
command: "tsx",
args: [serverPath],
env: Object.fromEntries(Object.entries(process.env).filter(([_, v]) => v !== undefined))
});
const client = await experimental_createMCPClient({
transport,
});
for (const evaluation of config.evals) {
console.log(`Running ${evaluation.name}...`);
try {
const result = await evaluation.run(config.model);
results.set(evaluation.name, result);
}
catch (error) {
console.error(`Error running ${evaluation.name}:`, error);
results.set(evaluation.name, { error: error instanceof Error ? error.message : String(error) });
}
}
return results;
}
finally {
// Clean up the transport
if (transport) {
await transport.close?.();
}
}
}
// Export everything needed by consumers
export * from './types.js';
export { metrics } from './metrics.js';
//# sourceMappingURL=index.js.map

1
node_modules/mcp-evals/dist/index.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,8BAA8B,EAAE,MAAM,cAAc,CAAC;AAC9D,OAAO,EACL,4BAA4B,EAC5B,UAAU,GAEX,MAAM,IAAI,CAAC;AACZ,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAExC,MAAM,YAAY,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;AAEtC,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAqB,YAAY,EAAE,MAAc,EAAC,UAAkB;IACjG,MAAM,SAAS,GAAG,IAAI,8BAA8B,CAAC;QACnD,OAAO,EAAE,KAAK;QACd,IAAI,EAAE,CAAC,UAAU,CAAC;QAClB,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAA2B;KACnH,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAAC;QAChD,SAAS;KACV,CAAC,CAAC;IAEH,MAAM,KAAK,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAEnC,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,UAAU,CAAC;YACxB,KAAK;YACL,KAAK;YACL,MAAM,EACJ,sKAAsK;YACxK,MAAM;YACN,UAAU,EAAE,CAAC;YACb,QAAQ,EAAE,EAAE;YACZ,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;gBACrB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACvB,CAAC;SACF,CAAC,CAAC;QAEH,IAAI,QAAQ,GAAG,EAAE,CAAC;QAClB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YAC5C,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAChC,QAAQ,IAAI,KAAK,CAAC,SAAS,CAAC;YAC9B,CAAC;QACH,CAAC;QAED,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QAC3C,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,QAAqB,YAAY,EAAE,MAAc,EAAE,UAAmB;IAChG,MAAM,eAAe,GAAG,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,sCAAsC;IAC7F,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IAC9D,MAAM,eAAe,GAAG;;;;;;;;;;;;;;UAchB,CAAA;IACR,MAAM,SAAS,GAAG,2BAA2B,MAAM;8BACvB,MAAM,EAAE,CAAA;IACpC,MAAM,UAAU,GAAG,UAAU,CAAC;QACpB,KAAK;QACL,UAAU,EAAE,CAAC;QACb,QAAQ,EAAE,EAAE;QACZ,MAAM,EAAE,eAAe;QACvB,MAAM,EAAE,SAAS;QACjB,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE;YACrB,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;QACzB,CAAC;KACN,CAAC,CAAC;IAEH,IAAI,KAAK,EAAE,MAAM,CAAC,IAAI,UAAU,CAAC,UAAU,EAAE,CAAC;IAE9C,CAAC;IAED,OAAO,MAAM,UAAU,CAAC,IAAI,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,MAAkB,EAAE,UAAkB;IACtE,MAAM,OAAO,GAAG,IAAI,GAAG,EAAe,CAAC;IACvC,IAAI,SAAS,CAAC;IAEd,IAAI,CAAC;QACH,SAAS,GAAG,IAAI,8BAA8B,CAAC;YAC7C,OAAO,EAAE,KAAK;YACd,IAAI,EAAE,CAAC,UAAU,CAAC;YAClB,GAAG,EAAE,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAA2B;SACnH,CAAC,CAAC;QAEH,MAAM,MAAM,GAAG,MAAM,4BAA4B,CAAC;YAChD,SAAS;SACV,CAAC,CAAC;QAEH,KAAK,MAAM,UAAU,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACtC,OAAO,CAAC,GAAG,CAAC,WAAW,UAAU,CAAC,IAAI,KAAK,CAAC,CAAC;YAC7C,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBAClD,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACvC,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,iBAAiB,UAAU,CAAC,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC1D,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAClG,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;YAAS,CAAC;QACT,yBAAyB;QACzB,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,SAAS,CAAC,KAAK,EAAE,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;AACH,CAAC;AAED,wCAAwC;AACxC,cAAc,YAAY,CAAC;AAC3B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}

23
node_modules/mcp-evals/dist/metrics.d.ts generated vendored Normal file
View File

@@ -0,0 +1,23 @@
export interface MetricsConfig {
metricsPort?: number;
otelExporterUrl?: string;
serviceName?: string;
debug?: boolean;
enableTracing?: boolean;
otelEndpoint?: string;
}
declare class Metrics {
private static instance;
private sdk;
private tracer;
private registry;
private metrics;
private metricsServer;
private constructor();
static initialize(metricsPort?: number, options?: {}): Metrics;
}
export declare const metrics: {
initialize: (metricsPort?: number, options?: {}) => Metrics;
};
export {};
//# sourceMappingURL=metrics.d.ts.map

1
node_modules/mcp-evals/dist/metrics.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"metrics.d.ts","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAYA,MAAM,WAAW,aAAa;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAEH,cAAM,OAAO;IACX,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAU;IACjC,OAAO,CAAC,GAAG,CAAU;IACrB,OAAO,CAAC,MAAM,CAAM;IACpB,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,OAAO,CAIb;IACF,OAAO,CAAC,aAAa,CAAsB;IAE3C,OAAO;IAkEP,MAAM,CAAC,UAAU,CAAC,WAAW,SAAO,EAAE,OAAO,KAAK;CAkEnD;AAED,eAAO,MAAM,OAAO;;CAEnB,CAAC"}

142
node_modules/mcp-evals/dist/metrics.js generated vendored Normal file
View File

@@ -0,0 +1,142 @@
// @ts-nocheck
// metrics.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { NodeSDK } from '@opentelemetry/sdk-node';
import { resourceFromAttributes } from '@opentelemetry/resources';
import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions';
import { SimpleSpanProcessor } from '@opentelemetry/sdk-trace-base';
import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-http';
import { trace, SpanStatusCode } from '@opentelemetry/api';
import { Registry, Counter, Histogram } from 'prom-client';
import express from 'express';
class Metrics {
static instance;
sdk;
tracer;
registry;
metrics;
metricsServer;
constructor(options = {}) {
// Initialize OpenTelemetry if tracing is enabled
if (options.enableTracing) {
// Default to local collector endpoint if not specified
const otelEndpoint = options.otelEndpoint || 'http://localhost:4318/v1/traces';
console.log(`Configuring OpenTelemetry with endpoint: ${otelEndpoint}`);
const exporterOptions = {
url: otelEndpoint,
headers: {}, // Additional headers if needed
concurrencyLimit: 10
};
this.sdk = new NodeSDK({
resource: resourceFromAttributes({
[SemanticResourceAttributes.SERVICE_NAME]: options.serviceName || 'mcp-server',
}),
spanProcessor: new SimpleSpanProcessor(new OTLPTraceExporter(exporterOptions)),
});
// Start the SDK
try {
this.sdk.start();
console.log(`OpenTelemetry SDK started successfully, sending traces to ${otelEndpoint}`);
}
catch (error) {
console.error('Failed to start OpenTelemetry SDK:', error);
}
}
else {
console.log('OpenTelemetry tracing is disabled');
}
this.tracer = trace.getTracer('mcp-tracer');
// Initialize Prometheus metrics
this.registry = new Registry();
this.metrics = {
toolCalls: new Counter({
name: 'mcp_tool_calls_total',
help: 'Total number of tool calls',
labelNames: ['tool_name'],
registers: [this.registry]
}),
toolErrors: new Counter({
name: 'mcp_tool_errors_total',
help: 'Total number of tool errors',
labelNames: ['tool_name'],
registers: [this.registry]
}),
toolLatency: new Histogram({
name: 'mcp_tool_latency_seconds',
help: 'Tool call latency in seconds',
labelNames: ['tool_name'],
buckets: [0.1, 0.5, 1, 2, 5],
registers: [this.registry]
})
};
// Setup metrics server
this.metricsServer = express();
this.metricsServer.get('/metrics', async (req, res) => {
res.set('Content-Type', this.registry.contentType);
res.end(await this.registry.metrics());
});
}
static initialize(metricsPort = 9090, options = {}) {
if (!Metrics.instance) {
Metrics.instance = new Metrics(options);
// Patch the McpServer prototype to add instrumentation
const originalTool = McpServer.prototype.tool;
McpServer.prototype.tool = function (...args) {
// The tool method can be called with multiple signatures:
// (name, description, parameters, handler)
// (name, description, parameters, options, handler)
const name = args[0];
const description = args[1];
const parameters = args[2];
// Last arg is always the handler
const handler = args[args.length - 1];
// Check if options are present (second to last argument when length > 4)
const hasOptions = args.length > 4;
const options = hasOptions ? args[3] : undefined;
// Create new args array with wrapped handler
const newArgs = hasOptions
? [name, description, parameters, options]
: [name, description, parameters];
// Add wrapped handler that includes instrumentation
newArgs.push(async (...handlerArgs) => {
const span = Metrics.instance.tracer.startSpan(`tool.${name}`);
const startTime = process.hrtime();
try {
// Increment tool calls counter
Metrics.instance.metrics.toolCalls.inc({ tool_name: name });
const result = await handler(...handlerArgs);
span.setStatus({ code: SpanStatusCode.OK });
return result;
}
catch (error) {
// Increment error counter
Metrics.instance.metrics.toolErrors.inc({ tool_name: name });
span.setStatus({
code: SpanStatusCode.ERROR,
message: error instanceof Error ? error.message : String(error)
});
throw error;
}
finally {
// Record latency
const [seconds, nanoseconds] = process.hrtime(startTime);
const duration = seconds + nanoseconds / 1e9;
Metrics.instance.metrics.toolLatency.observe({ tool_name: name }, duration);
span.end();
}
});
// Call original tool method with new args
return originalTool.apply(this, newArgs);
};
// Start metrics server
Metrics.instance.metricsServer.listen(metricsPort, () => {
console.log(`Metrics server listening on port ${metricsPort}`);
});
}
return Metrics.instance;
}
}
export const metrics = {
initialize: (metricsPort = 9090, options = {}) => Metrics.initialize(metricsPort, options)
};
//# sourceMappingURL=metrics.js.map

1
node_modules/mcp-evals/dist/metrics.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../src/metrics.ts"],"names":[],"mappings":"AAAA,cAAc;AACd,aAAa;AACb,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,0BAA0B,EAAE,MAAM,qCAAqC,CAAC;AACjF,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAC5E,OAAO,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,OAAO,MAAM,SAAS,CAAC;AAW9B,MAAM,OAAO;IACH,MAAM,CAAC,QAAQ,CAAU;IACzB,GAAG,CAAU;IACb,MAAM,CAAM;IACZ,QAAQ,CAAW;IACnB,OAAO,CAIb;IACM,aAAa,CAAsB;IAE3C,YAAoB,OAAO,GAAG,EAAE;QAC9B,iDAAiD;QACjD,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC;YACxB,uDAAuD;YACvD,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,IAAI,iCAAiC,CAAC;YAC/E,OAAO,CAAC,GAAG,CAAC,4CAA4C,YAAY,EAAE,CAAC,CAAC;YAExE,MAAM,eAAe,GAAG;gBACpB,GAAG,EAAE,YAAY;gBACjB,OAAO,EAAE,EAAE,EAAE,+BAA+B;gBAC5C,gBAAgB,EAAE,EAAE;aACvB,CAAC;YAEF,IAAI,CAAC,GAAG,GAAG,IAAI,OAAO,CAAC;gBACnB,QAAQ,EAAE,sBAAsB,CAAC;oBAC7B,CAAC,0BAA0B,CAAC,YAAY,CAAC,EAAE,OAAO,CAAC,WAAW,IAAI,YAAY;iBACjF,CAAC;gBACF,aAAa,EAAE,IAAI,mBAAmB,CAAC,IAAI,iBAAiB,CAAC,eAAe,CAAC,CAAC;aACjF,CAAC,CAAC;YAEH,gBAAgB;YAChB,IAAI,CAAC;gBACD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;gBACjB,OAAO,CAAC,GAAG,CAAC,6DAA6D,YAAY,EAAE,CAAC,CAAC;YAC7F,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,KAAK,CAAC,CAAC;YAC/D,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,mCAAmC,CAAC,CAAC;QACrD,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAE5C,gCAAgC;QAChC,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,EAAE,CAAC;QAE/B,IAAI,CAAC,OAAO,GAAG;YACb,SAAS,EAAE,IAAI,OAAO,CAAC;gBACrB,IAAI,EAAE,sBAAsB;gBAC5B,IAAI,EAAE,4BAA4B;gBAClC,UAAU,EAAE,CAAC,WAAW,CAAC;gBACzB,SAAS,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC3B,CAAC;YACF,UAAU,EAAE,IAAI,OAAO,CAAC;gBACtB,IAAI,EAAE,uBAAuB;gBAC7B,IAAI,EAAE,6BAA6B;gBACnC,UAAU,EAAE,CAAC,WAAW,CAAC;gBACzB,SAAS,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC3B,CAAC;YACF,WAAW,EAAE,IAAI,SAAS,CAAC;gBACzB,IAAI,EAAE,0BAA0B;gBAChC,IAAI,EAAE,8BAA8B;gBACpC,UAAU,EAAE,CAAC,WAAW,CAAC;gBACzB,OAAO,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;gBAC5B,SAAS,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC;aAC3B,CAAC;SACH,CAAC;QAEF,uBAAuB;QACvB,IAAI,CAAC,aAAa,GAAG,OAAO,EAAE,CAAC;QAC/B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,UAAU,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;YACpD,GAAG,CAAC,GAAG,CAAC,cAAc,EAAE,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC;YACnD,GAAG,CAAC,GAAG,CAAC,MAAM,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC;QACzC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,WAAW,GAAG,IAAI,EAAE,OAAO,GAAG,EAAE;QAChD,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;YACtB,OAAO,CAAC,QAAQ,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;YAExC,uDAAuD;YACvD,MAAM,YAAY,GAAG,SAAS,CAAC,SAAS,CAAC,IAAI,CAAC;YAC9C,SAAS,CAAC,SAAS,CAAC,IAAI,GAAG,UAAS,GAAG,IAAI;gBACzC,0DAA0D;gBAC1D,2CAA2C;gBAC3C,oDAAoD;gBACpD,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBACrB,MAAM,WAAW,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;gBAE3B,iCAAiC;gBACjC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;gBAEtC,yEAAyE;gBACzE,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC;gBACnC,MAAM,OAAO,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;gBAEjD,6CAA6C;gBAC7C,MAAM,OAAO,GAAG,UAAU;oBACtB,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,OAAO,CAAC;oBAC1C,CAAC,CAAC,CAAC,IAAI,EAAE,WAAW,EAAE,UAAU,CAAC,CAAC;gBAEtC,oDAAoD;gBACpD,OAAO,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,WAAW,EAAE,EAAE;oBAClC,MAAM,IAAI,GAAG,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;oBAC/D,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;oBACnC,IAAI,CAAC;wBACD,+BAA+B;wBAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;wBAC5D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,GAAG,WAAW,CAAC,CAAC;wBAC7C,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC;wBAC5C,OAAO,MAAM,CAAC;oBAClB,CAAC;oBACD,OAAO,KAAK,EAAE,CAAC;wBACX,0BAA0B;wBAC1B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;wBAC7D,IAAI,CAAC,SAAS,CAAC;4BACX,IAAI,EAAE,cAAc,CAAC,KAAK;4BAC1B,OAAO,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;yBAClE,CAAC,CAAC;wBACH,MAAM,KAAK,CAAC;oBAChB,CAAC;4BACO,CAAC;wBACL,iBAAiB;wBACjB,MAAM,CAAC,OAAO,EAAE,WAAW,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;wBACzD,MAAM,QAAQ,GAAG,OAAO,GAAG,WAAW,GAAG,GAAG,CAAC;wBAC7C,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,CAAC;wBAC5E,IAAI,CAAC,GAAG,EAAE,CAAC;oBACf,CAAC;gBACL,CAAC,CAAC,CAAC;gBAEH,0CAA0C;gBAC1C,OAAO,YAAY,CAAC,KAAK,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC3C,CAAC,CAAC;YAEF,uBAAuB;YACvB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,WAAW,EAAE,GAAG,EAAE;gBACtD,OAAO,CAAC,GAAG,CAAC,oCAAoC,WAAW,EAAE,CAAC,CAAC;YACjE,CAAC,CAAC,CAAC;QACL,CAAC;QACD,OAAO,OAAO,CAAC,QAAQ,CAAC;IAC1B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,OAAO,GAAG;IACrB,UAAU,EAAE,CAAC,WAAW,GAAG,IAAI,EAAE,OAAO,GAAG,EAAE,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,OAAO,CAAC;CAC3F,CAAC"}

34
node_modules/mcp-evals/dist/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,34 @@
import { type LanguageModel } from 'ai';
export interface EvalResult {
accuracy: number;
completeness: number;
relevance: number;
clarity: number;
reasoning: number;
overall_comments: string;
}
export interface EvalFunction {
name: string;
description: string;
run: (model: LanguageModel) => Promise<EvalResult>;
}
export interface EvalConfig {
model: LanguageModel;
evals: EvalFunction[];
}
export interface YamlModelConfig {
provider: 'openai' | 'anthropic';
name: string;
api_key?: string;
}
export interface YamlEval {
name: string;
description: string;
prompt: string;
expected_result?: string;
}
export interface YamlEvalConfig {
model?: YamlModelConfig;
evals: YamlEval[];
}
//# sourceMappingURL=types.d.ts.map

1
node_modules/mcp-evals/dist/types.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,IAAI,CAAC;AAExC,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC;CACpD;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,aAAa,CAAC;IACrB,KAAK,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,QAAQ,GAAG,WAAW,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,QAAQ,EAAE,CAAC;CACnB"}

2
node_modules/mcp-evals/dist/types.js generated vendored Normal file
View File

@@ -0,0 +1,2 @@
export {};
//# sourceMappingURL=types.js.map

1
node_modules/mcp-evals/dist/types.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}

14
node_modules/mcp-evals/dist/yaml-loader.d.ts generated vendored Normal file
View File

@@ -0,0 +1,14 @@
import { YamlEvalConfig, EvalConfig } from './types.js';
/**
* Load and parse a YAML configuration file
*/
export declare function loadYamlConfig(filePath: string): YamlEvalConfig;
/**
* Convert a YAML configuration to an EvalConfig
*/
export declare function yamlConfigToEvalConfig(yamlConfig: YamlEvalConfig, serverPath: string): EvalConfig;
/**
* Load a YAML config file and convert it to an EvalConfig
*/
export declare function loadYamlEvalConfig(filePath: string, serverPath: string): EvalConfig;
//# sourceMappingURL=yaml-loader.d.ts.map

1
node_modules/mcp-evals/dist/yaml-loader.d.ts.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"yaml-loader.d.ts","sourceRoot":"","sources":["../src/yaml-loader.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,cAAc,EAAY,UAAU,EAAgB,MAAM,YAAY,CAAC;AAGhF;;GAEG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAwB/D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAkDjG;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,UAAU,CAGnF"}

96
node_modules/mcp-evals/dist/yaml-loader.js generated vendored Normal file
View File

@@ -0,0 +1,96 @@
import * as yaml from 'js-yaml';
import * as fs from 'fs';
import * as path from 'path';
import { openai } from "@ai-sdk/openai";
import { anthropic } from "@ai-sdk/anthropic";
import { grade } from './index.js';
/**
* Load and parse a YAML configuration file
*/
export function loadYamlConfig(filePath) {
try {
const absolutePath = path.resolve(filePath);
const fileContents = fs.readFileSync(absolutePath, 'utf8');
const config = yaml.load(fileContents);
if (!config || !config.evals || !Array.isArray(config.evals)) {
throw new Error('Invalid YAML config: must have an "evals" array');
}
// Validate each eval
for (const evalItem of config.evals) {
if (!evalItem.name || !evalItem.description || !evalItem.prompt) {
throw new Error(`Invalid eval: each eval must have "name", "description", and "prompt" fields`);
}
}
return config;
}
catch (error) {
if (error instanceof Error) {
throw new Error(`Failed to load YAML config: ${error.message}`);
}
throw new Error('Failed to load YAML config: Unknown error');
}
}
/**
* Convert a YAML configuration to an EvalConfig
*/
export function yamlConfigToEvalConfig(yamlConfig, serverPath) {
// Setup model
let model;
if (yamlConfig.model) {
if (yamlConfig.model.provider === 'openai') {
// Set the API key as an environment variable if provided
if (yamlConfig.model.api_key) {
process.env.OPENAI_API_KEY = yamlConfig.model.api_key;
}
model = openai(yamlConfig.model.name);
}
else if (yamlConfig.model.provider === 'anthropic') {
// Set the API key as an environment variable if provided
if (yamlConfig.model.api_key) {
process.env.ANTHROPIC_API_KEY = yamlConfig.model.api_key;
}
model = anthropic(yamlConfig.model.name);
}
else {
throw new Error(`Unsupported model provider: ${yamlConfig.model.provider}`);
}
}
else {
// Default to GPT-4
model = openai("gpt-4o");
}
// Convert YAML evals to EvalFunctions
const evalFunctions = yamlConfig.evals.map((yamlEval) => ({
name: yamlEval.name,
description: yamlEval.description,
run: async (evalModel) => {
try {
const result = await grade(evalModel, yamlEval.prompt, serverPath);
return JSON.parse(result);
}
catch (error) {
// If JSON parsing fails, return a default structure
return {
accuracy: 0,
completeness: 0,
relevance: 0,
clarity: 0,
reasoning: 0,
overall_comments: `Error running evaluation: ${error instanceof Error ? error.message : String(error)}`
};
}
}
}));
return {
model,
evals: evalFunctions
};
}
/**
* Load a YAML config file and convert it to an EvalConfig
*/
export function loadYamlEvalConfig(filePath, serverPath) {
const yamlConfig = loadYamlConfig(filePath);
return yamlConfigToEvalConfig(yamlConfig, serverPath);
}
//# sourceMappingURL=yaml-loader.js.map

1
node_modules/mcp-evals/dist/yaml-loader.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"yaml-loader.js","sourceRoot":"","sources":["../src/yaml-loader.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,SAAS,CAAC;AAChC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAG9C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAEnC;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,QAAgB;IAC7C,IAAI,CAAC;QACH,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QAC5C,MAAM,YAAY,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;QAC3D,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,YAAY,CAAmB,CAAC;QAEzD,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACrE,CAAC;QAED,qBAAqB;QACrB,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YACpC,IAAI,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;gBAChE,MAAM,IAAI,KAAK,CAAC,8EAA8E,CAAC,CAAC;YAClG,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,EAAE,CAAC;YAC3B,MAAM,IAAI,KAAK,CAAC,+BAA+B,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAClE,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,sBAAsB,CAAC,UAA0B,EAAE,UAAkB;IACnF,cAAc;IACd,IAAI,KAAoB,CAAC;IACzB,IAAI,UAAU,CAAC,KAAK,EAAE,CAAC;QACrB,IAAI,UAAU,CAAC,KAAK,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC3C,yDAAyD;YACzD,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,cAAc,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC;YACxD,CAAC;YACD,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAW,CAAC,CAAC;QAC/C,CAAC;aAAM,IAAI,UAAU,CAAC,KAAK,CAAC,QAAQ,KAAK,WAAW,EAAE,CAAC;YACrD,yDAAyD;YACzD,IAAI,UAAU,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC7B,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,UAAU,CAAC,KAAK,CAAC,OAAO,CAAC;YAC3D,CAAC;YACD,KAAK,GAAG,SAAS,CAAC,UAAU,CAAC,KAAK,CAAC,IAAW,CAAC,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,KAAK,CAAC,+BAA+B,UAAU,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC;SAAM,CAAC;QACN,mBAAmB;QACnB,KAAK,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC3B,CAAC;IAED,sCAAsC;IACtC,MAAM,aAAa,GAAmB,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAkB,EAAE,EAAE,CAAC,CAAC;QAClF,IAAI,EAAE,QAAQ,CAAC,IAAI;QACnB,WAAW,EAAE,QAAQ,CAAC,WAAW;QACjC,GAAG,EAAE,KAAK,EAAE,SAAwB,EAAE,EAAE;YACtC,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,SAAS,EAAE,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;gBACnE,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,oDAAoD;gBACpD,OAAO;oBACL,QAAQ,EAAE,CAAC;oBACX,YAAY,EAAE,CAAC;oBACf,SAAS,EAAE,CAAC;oBACZ,OAAO,EAAE,CAAC;oBACV,SAAS,EAAE,CAAC;oBACZ,gBAAgB,EAAE,6BAA6B,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;iBACxG,CAAC;YACJ,CAAC;QACH,CAAC;KACF,CAAC,CAAC,CAAC;IAEJ,OAAO;QACL,KAAK;QACL,KAAK,EAAE,aAAa;KACrB,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB,EAAE,UAAkB;IACrE,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAC;IAC5C,OAAO,sBAAsB,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;AACxD,CAAC"}

16
node_modules/mcp-evals/node_modules/.bin/openai generated vendored Normal file
View File

@@ -0,0 +1,16 @@
#!/bin/sh
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
case `uname` in
*CYGWIN*|*MINGW*|*MSYS*)
if command -v cygpath > /dev/null 2>&1; then
basedir=`cygpath -w "$basedir"`
fi
;;
esac
if [ -x "$basedir/node" ]; then
exec "$basedir/node" "$basedir/../openai/bin/cli" "$@"
else
exec node "$basedir/../openai/bin/cli" "$@"
fi

17
node_modules/mcp-evals/node_modules/.bin/openai.cmd generated vendored Normal file
View File

@@ -0,0 +1,17 @@
@ECHO off
GOTO start
:find_dp0
SET dp0=%~dp0
EXIT /b
:start
SETLOCAL
CALL :find_dp0
IF EXIST "%dp0%\node.exe" (
SET "_prog=%dp0%\node.exe"
) ELSE (
SET "_prog=node"
SET PATHEXT=%PATHEXT:;.JS;=;%
)
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\openai\bin\cli" %*

28
node_modules/mcp-evals/node_modules/.bin/openai.ps1 generated vendored Normal file
View File

@@ -0,0 +1,28 @@
#!/usr/bin/env pwsh
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
$exe=""
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
# Fix case when both the Windows and Linux builds of Node
# are installed in the same directory
$exe=".exe"
}
$ret=0
if (Test-Path "$basedir/node$exe") {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "$basedir/node$exe" "$basedir/../openai/bin/cli" $args
} else {
& "$basedir/node$exe" "$basedir/../openai/bin/cli" $args
}
$ret=$LASTEXITCODE
} else {
# Support pipeline input
if ($MyInvocation.ExpectingInput) {
$input | & "node$exe" "$basedir/../openai/bin/cli" $args
} else {
& "node$exe" "$basedir/../openai/bin/cli" $args
}
$ret=$LASTEXITCODE
}
exit $ret

View File

@@ -0,0 +1,565 @@
# @ai-sdk/provider-utils
## 2.2.8
### Patch Changes
- d87b9d1: fix(provider-utils): fix SSE parser bug (CRLF)
## 2.2.7
### Patch Changes
- Updated dependencies [beef951]
- @ai-sdk/provider@1.1.3
## 2.2.6
### Patch Changes
- Updated dependencies [013faa8]
- @ai-sdk/provider@1.1.2
## 2.2.5
### Patch Changes
- c21fa6d: feat: add transcription with experimental_transcribe
- Updated dependencies [c21fa6d]
- @ai-sdk/provider@1.1.1
## 2.2.4
### Patch Changes
- 2c19b9a: feat(provider-utils): add TestServerCall#requestCredentials
## 2.2.3
### Patch Changes
- 28be004: chore (provider-utils): add error method to TestStreamController
## 2.2.2
### Patch Changes
- b01120e: chore (provider-utils): update unified test server
## 2.2.1
### Patch Changes
- f10f0fa: fix (provider-utils): improve event source stream parsing performance
## 2.2.0
### Minor Changes
- 5bc638d: AI SDK 4.2
### Patch Changes
- Updated dependencies [5bc638d]
- @ai-sdk/provider@1.1.0
## 2.1.15
### Patch Changes
- d0c4659: feat (provider-utils): parseProviderOptions function
## 2.1.14
### Patch Changes
- Updated dependencies [0bd5bc6]
- @ai-sdk/provider@1.0.12
## 2.1.13
### Patch Changes
- Updated dependencies [2e1101a]
- @ai-sdk/provider@1.0.11
## 2.1.12
### Patch Changes
- 1531959: feat (provider-utils): add readable-stream to unified test server
## 2.1.11
### Patch Changes
- Updated dependencies [e1d3d42]
- @ai-sdk/provider@1.0.10
## 2.1.10
### Patch Changes
- Updated dependencies [ddf9740]
- @ai-sdk/provider@1.0.9
## 2.1.9
### Patch Changes
- Updated dependencies [2761f06]
- @ai-sdk/provider@1.0.8
## 2.1.8
### Patch Changes
- 2e898b4: chore (ai): move mockId test helper into provider utils
## 2.1.7
### Patch Changes
- 3ff4ef8: feat (provider-utils): export removeUndefinedEntries for working with e.g. headers
## 2.1.6
### Patch Changes
- Updated dependencies [d89c3b9]
- @ai-sdk/provider@1.0.7
## 2.1.5
### Patch Changes
- 3a602ca: chore (core): rename CoreTool to Tool
## 2.1.4
### Patch Changes
- 066206e: feat (provider-utils): move delay to provider-utils from ai
## 2.1.3
### Patch Changes
- 39e5c1f: feat (provider-utils): add getFromApi and response handlers for binary responses and status-code errors
## 2.1.2
### Patch Changes
- ed012d2: feat (provider): add metadata extraction mechanism to openai-compatible providers
- Updated dependencies [3a58a2e]
- @ai-sdk/provider@1.0.6
## 2.1.1
### Patch Changes
- e7a9ec9: feat (provider-utils): include raw value in json parse results
- Updated dependencies [0a699f1]
- @ai-sdk/provider@1.0.5
## 2.1.0
### Minor Changes
- 62ba5ad: release: AI SDK 4.1
## 2.0.8
### Patch Changes
- 00114c5: feat: expose IDGenerator and createIdGenerator
## 2.0.7
### Patch Changes
- 90fb95a: chore (provider-utils): switch to unified test server
- e6dfef4: feat (provider/fireworks): Support add'l image models.
- 6636db6: feat (provider-utils): add unified test server
## 2.0.6
### Patch Changes
- 19a2ce7: feat (provider/fireworks): Add image model support.
- 6337688: feat: change image generation errors to warnings
- Updated dependencies [19a2ce7]
- Updated dependencies [6337688]
- @ai-sdk/provider@1.0.4
## 2.0.5
### Patch Changes
- 5ed5e45: chore (config): Use ts-library.json tsconfig for no-UI libs.
- Updated dependencies [5ed5e45]
- @ai-sdk/provider@1.0.3
## 2.0.4
### Patch Changes
- Updated dependencies [09a9cab]
- @ai-sdk/provider@1.0.2
## 2.0.3
### Patch Changes
- 0984f0b: feat (provider-utils): Add resolvable type and utility routine.
## 2.0.2
### Patch Changes
- Updated dependencies [b446ae5]
- @ai-sdk/provider@1.0.1
## 2.0.1
### Patch Changes
- c3ab5de: fix (provider-utils): downgrade nanoid and secure-json-parse (ESM compatibility)
## 2.0.0
### Major Changes
- b469a7e: chore: remove isXXXError methods
- b1da952: chore (provider-utils): remove convertStreamToArray
- 8426f55: chore (ai):increase id generator default size from 7 to 16.
- db46ce5: chore (provider-utils): remove isParseableJson export
### Patch Changes
- dce4158: chore (dependencies): update eventsource-parser to 3.0.0
- dce4158: chore (dependencies): update nanoid to 5.0.8
- Updated dependencies [b469a7e]
- Updated dependencies [c0ddc24]
- @ai-sdk/provider@1.0.0
## 2.0.0-canary.3
### Major Changes
- 8426f55: chore (ai):increase id generator default size from 7 to 16.
## 2.0.0-canary.2
### Patch Changes
- dce4158: chore (dependencies): update eventsource-parser to 3.0.0
- dce4158: chore (dependencies): update nanoid to 5.0.8
## 2.0.0-canary.1
### Major Changes
- b1da952: chore (provider-utils): remove convertStreamToArray
## 2.0.0-canary.0
### Major Changes
- b469a7e: chore: remove isXXXError methods
- db46ce5: chore (provider-utils): remove isParseableJson export
### Patch Changes
- Updated dependencies [b469a7e]
- Updated dependencies [c0ddc24]
- @ai-sdk/provider@1.0.0-canary.0
## 1.0.22
### Patch Changes
- aa98cdb: chore: more flexible dependency versioning
- 7b937c5: feat (provider-utils): improve id generator robustness
- 811a317: feat (ai/core): multi-part tool results (incl. images)
- Updated dependencies [aa98cdb]
- Updated dependencies [1486128]
- Updated dependencies [7b937c5]
- Updated dependencies [3b1b69a]
- Updated dependencies [811a317]
- @ai-sdk/provider@0.0.26
## 1.0.21
### Patch Changes
- Updated dependencies [b9b0d7b]
- @ai-sdk/provider@0.0.25
## 1.0.20
### Patch Changes
- Updated dependencies [d595d0d]
- @ai-sdk/provider@0.0.24
## 1.0.19
### Patch Changes
- 273f696: fix (ai/provider-utils): expose size argument in generateId
## 1.0.18
### Patch Changes
- 03313cd: feat (ai): expose response id, response model, response timestamp in telemetry and api
- Updated dependencies [03313cd]
- Updated dependencies [3be7c1c]
- @ai-sdk/provider@0.0.23
## 1.0.17
### Patch Changes
- Updated dependencies [26515cb]
- @ai-sdk/provider@0.0.22
## 1.0.16
### Patch Changes
- 09f895f: feat (ai/core): no-schema output for generateObject / streamObject
## 1.0.15
### Patch Changes
- d67fa9c: feat (provider/amazon-bedrock): add support for session tokens
## 1.0.14
### Patch Changes
- Updated dependencies [f2c025e]
- @ai-sdk/provider@0.0.21
## 1.0.13
### Patch Changes
- Updated dependencies [6ac355e]
- @ai-sdk/provider@0.0.20
## 1.0.12
### Patch Changes
- dd712ac: fix: use FetchFunction type to prevent self-reference
## 1.0.11
### Patch Changes
- Updated dependencies [dd4a0f5]
- @ai-sdk/provider@0.0.19
## 1.0.10
### Patch Changes
- 4bd27a9: chore (ai/provider): refactor type validation
- 845754b: fix (ai/provider): fix atob/btoa execution on cloudflare edge workers
- Updated dependencies [4bd27a9]
- @ai-sdk/provider@0.0.18
## 1.0.9
### Patch Changes
- Updated dependencies [029af4c]
- @ai-sdk/provider@0.0.17
## 1.0.8
### Patch Changes
- Updated dependencies [d58517b]
- @ai-sdk/provider@0.0.16
## 1.0.7
### Patch Changes
- Updated dependencies [96aed25]
- @ai-sdk/provider@0.0.15
## 1.0.6
### Patch Changes
- 9614584: fix (ai/core): use Symbol.for
- 0762a22: feat (ai/core): support zod transformers in generateObject & streamObject
## 1.0.5
### Patch Changes
- a8d1c9e9: feat (ai/core): parallel image download
- Updated dependencies [a8d1c9e9]
- @ai-sdk/provider@0.0.14
## 1.0.4
### Patch Changes
- 4f88248f: feat (core): support json schema
## 1.0.3
### Patch Changes
- Updated dependencies [2b9da0f0]
- Updated dependencies [a5b58845]
- Updated dependencies [4aa8deb3]
- Updated dependencies [13b27ec6]
- @ai-sdk/provider@0.0.13
## 1.0.2
### Patch Changes
- Updated dependencies [b7290943]
- @ai-sdk/provider@0.0.12
## 1.0.1
### Patch Changes
- d481729f: fix (ai/provider-utils): generalize to Error (DomException not always available)
## 1.0.0
### Major Changes
- 5edc6110: feat (provider-utils): change getRequestHeader() test helper to return Record (breaking change)
### Patch Changes
- 5edc6110: feat (provider-utils): add combineHeaders helper
- Updated dependencies [5edc6110]
- @ai-sdk/provider@0.0.11
## 0.0.16
### Patch Changes
- 02f6a088: feat (provider-utils): add convertArrayToAsyncIterable test helper
## 0.0.15
### Patch Changes
- 85712895: feat (@ai-sdk/provider-utils): add createJsonStreamResponseHandler
- 85712895: chore (@ai-sdk/provider-utils): move test helper to provider utils
## 0.0.14
### Patch Changes
- 7910ae84: feat (providers): support custom fetch implementations
## 0.0.13
### Patch Changes
- Updated dependencies [102ca22f]
- @ai-sdk/provider@0.0.10
## 0.0.12
### Patch Changes
- 09295e2e: feat (@ai-sdk/provider-utils): add download helper
- 043a5de2: fix (provider-utils): rename to isParsableJson
- Updated dependencies [09295e2e]
- @ai-sdk/provider@0.0.9
## 0.0.11
### Patch Changes
- Updated dependencies [f39c0dd2]
- @ai-sdk/provider@0.0.8
## 0.0.10
### Patch Changes
- Updated dependencies [8e780288]
- @ai-sdk/provider@0.0.7
## 0.0.9
### Patch Changes
- 6a50ac4: feat (provider-utils): add loadSetting and convertAsyncGeneratorToReadableStream helpers
- Updated dependencies [6a50ac4]
- @ai-sdk/provider@0.0.6
## 0.0.8
### Patch Changes
- Updated dependencies [0f6bc4e]
- @ai-sdk/provider@0.0.5
## 0.0.7
### Patch Changes
- Updated dependencies [325ca55]
- @ai-sdk/provider@0.0.4
## 0.0.6
### Patch Changes
- 276f22b: fix (ai/provider): improve request error handling
## 0.0.5
### Patch Changes
- Updated dependencies [41d5736]
- @ai-sdk/provider@0.0.3
## 0.0.4
### Patch Changes
- 56ef84a: ai/core: fix abort handling in transformation stream
## 0.0.3
### Patch Changes
- 25f3350: ai/core: add support for getting raw response headers.
- Updated dependencies [d6431ae]
- Updated dependencies [25f3350]
- @ai-sdk/provider@0.0.2
## 0.0.2
### Patch Changes
- eb150a6: ai/core: remove scaling of setting values (breaking change). If you were using the temperature, frequency penalty, or presence penalty settings, you need to update the providers and adjust the setting values.
- Updated dependencies [eb150a6]
- @ai-sdk/provider@0.0.1
## 0.0.1
### Patch Changes
- 7b8791d: Rename baseUrl to baseURL. Automatically remove trailing slashes.

View File

@@ -0,0 +1,13 @@
Copyright 2023 Vercel, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1 @@
# AI SDK - Provider Implementation Utilities

View File

@@ -0,0 +1,379 @@
import { JSONValue, JSONParseError, TypeValidationError, APICallError } from '@ai-sdk/provider';
import { z, ZodSchema } from 'zod';
declare function combineHeaders(...headers: Array<Record<string, string | undefined> | undefined>): Record<string, string | undefined>;
/**
* Converts an AsyncIterator to a ReadableStream.
*
* @template T - The type of elements produced by the AsyncIterator.
* @param { <T>} iterator - The AsyncIterator to convert.
* @returns {ReadableStream<T>} - A ReadableStream that provides the same data as the AsyncIterator.
*/
declare function convertAsyncIteratorToReadableStream<T>(iterator: AsyncIterator<T>): ReadableStream<T>;
/**
* Creates a Promise that resolves after a specified delay
* @param delayInMs - The delay duration in milliseconds. If null or undefined, resolves immediately.
* @returns A Promise that resolves after the specified delay
*/
declare function delay(delayInMs?: number | null): Promise<void>;
type EventSourceChunk = {
event: string | undefined;
data: string;
id?: string;
retry?: number;
};
declare function createEventSourceParserStream(): TransformStream<string, EventSourceChunk>;
/**
Extracts the headers from a response object and returns them as a key-value object.
@param response - The response object to extract headers from.
@returns The headers as a key-value object.
*/
declare function extractResponseHeaders(response: Response): Record<string, string>;
/**
* Fetch function type (standardizes the version of fetch used).
*/
type FetchFunction = typeof globalThis.fetch;
/**
Creates an ID generator.
The total length of the ID is the sum of the prefix, separator, and random part length.
Non-secure.
@param alphabet - The alphabet to use for the ID. Default: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.
@param prefix - The prefix of the ID to generate. Default: ''.
@param separator - The separator between the prefix and the random part of the ID. Default: '-'.
@param size - The size of the random part of the ID to generate. Default: 16.
*/
declare const createIdGenerator: ({ prefix, size: defaultSize, alphabet, separator, }?: {
prefix?: string;
separator?: string;
size?: number;
alphabet?: string;
}) => ((size?: number) => string);
/**
A function that generates an ID.
*/
type IDGenerator = () => string;
/**
Generates a 16-character random string to use for IDs. Not secure.
@param size - The size of the ID to generate. Default: 16.
*/
declare const generateId: (size?: number) => string;
declare function getErrorMessage(error: unknown | undefined): string;
/**
* Used to mark validator functions so we can support both Zod and custom schemas.
*/
declare const validatorSymbol: unique symbol;
type ValidationResult<OBJECT> = {
success: true;
value: OBJECT;
} | {
success: false;
error: Error;
};
type Validator<OBJECT = unknown> = {
/**
* Used to mark validator functions so we can support both Zod and custom schemas.
*/
[validatorSymbol]: true;
/**
* Optional. Validates that the structure of a value matches this schema,
* and returns a typed version of the value if it does.
*/
readonly validate?: (value: unknown) => ValidationResult<OBJECT>;
};
/**
* Create a validator.
*
* @param validate A validation function for the schema.
*/
declare function validator<OBJECT>(validate?: undefined | ((value: unknown) => ValidationResult<OBJECT>)): Validator<OBJECT>;
declare function isValidator(value: unknown): value is Validator;
declare function asValidator<OBJECT>(value: Validator<OBJECT> | z.Schema<OBJECT, z.ZodTypeDef, any>): Validator<OBJECT>;
declare function zodValidator<OBJECT>(zodSchema: z.Schema<OBJECT, z.ZodTypeDef, any>): Validator<OBJECT>;
/**
* Parses a JSON string into an unknown object.
*
* @param text - The JSON string to parse.
* @returns {JSONValue} - The parsed JSON object.
*/
declare function parseJSON(options: {
text: string;
schema?: undefined;
}): JSONValue;
/**
* Parses a JSON string into a strongly-typed object using the provided schema.
*
* @template T - The type of the object to parse the JSON into.
* @param {string} text - The JSON string to parse.
* @param {Validator<T>} schema - The schema to use for parsing the JSON.
* @returns {T} - The parsed object.
*/
declare function parseJSON<T>(options: {
text: string;
schema: ZodSchema<T> | Validator<T>;
}): T;
type ParseResult<T> = {
success: true;
value: T;
rawValue: unknown;
} | {
success: false;
error: JSONParseError | TypeValidationError;
};
/**
* Safely parses a JSON string and returns the result as an object of type `unknown`.
*
* @param text - The JSON string to parse.
* @returns {object} Either an object with `success: true` and the parsed data, or an object with `success: false` and the error that occurred.
*/
declare function safeParseJSON(options: {
text: string;
schema?: undefined;
}): ParseResult<JSONValue>;
/**
* Safely parses a JSON string into a strongly-typed object, using a provided schema to validate the object.
*
* @template T - The type of the object to parse the JSON into.
* @param {string} text - The JSON string to parse.
* @param {Validator<T>} schema - The schema to use for parsing the JSON.
* @returns An object with either a `success` flag and the parsed and typed data, or a `success` flag and an error object.
*/
declare function safeParseJSON<T>(options: {
text: string;
schema: ZodSchema<T> | Validator<T>;
}): ParseResult<T>;
declare function isParsableJson(input: string): boolean;
type ResponseHandler<RETURN_TYPE> = (options: {
url: string;
requestBodyValues: unknown;
response: Response;
}) => PromiseLike<{
value: RETURN_TYPE;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>;
declare const createJsonErrorResponseHandler: <T>({ errorSchema, errorToMessage, isRetryable, }: {
errorSchema: ZodSchema<T>;
errorToMessage: (error: T) => string;
isRetryable?: (response: Response, error?: T) => boolean;
}) => ResponseHandler<APICallError>;
declare const createEventSourceResponseHandler: <T>(chunkSchema: ZodSchema<T>) => ResponseHandler<ReadableStream<ParseResult<T>>>;
declare const createJsonStreamResponseHandler: <T>(chunkSchema: ZodSchema<T>) => ResponseHandler<ReadableStream<ParseResult<T>>>;
declare const createJsonResponseHandler: <T>(responseSchema: ZodSchema<T>) => ResponseHandler<T>;
declare const createBinaryResponseHandler: () => ResponseHandler<Uint8Array>;
declare const createStatusCodeErrorResponseHandler: () => ResponseHandler<APICallError>;
declare const getFromApi: <T>({ url, headers, successfulResponseHandler, failedResponseHandler, abortSignal, fetch, }: {
url: string;
headers?: Record<string, string | undefined>;
failedResponseHandler: ResponseHandler<Error>;
successfulResponseHandler: ResponseHandler<T>;
abortSignal?: AbortSignal;
fetch?: FetchFunction;
}) => Promise<{
value: T;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>;
declare function isAbortError(error: unknown): error is Error;
declare function loadApiKey({ apiKey, environmentVariableName, apiKeyParameterName, description, }: {
apiKey: string | undefined;
environmentVariableName: string;
apiKeyParameterName?: string;
description: string;
}): string;
/**
* Loads an optional `string` setting from the environment or a parameter.
*
* @param settingValue - The setting value.
* @param environmentVariableName - The environment variable name.
* @returns The setting value.
*/
declare function loadOptionalSetting({ settingValue, environmentVariableName, }: {
settingValue: string | undefined;
environmentVariableName: string;
}): string | undefined;
/**
* Loads a `string` setting from the environment or a parameter.
*
* @param settingValue - The setting value.
* @param environmentVariableName - The environment variable name.
* @param settingName - The setting name.
* @param description - The description of the setting.
* @returns The setting value.
*/
declare function loadSetting({ settingValue, environmentVariableName, settingName, description, }: {
settingValue: string | undefined;
environmentVariableName: string;
settingName: string;
description: string;
}): string;
declare function parseProviderOptions<T>({ provider, providerOptions, schema, }: {
provider: string;
providerOptions: Record<string, unknown> | undefined;
schema: z.ZodSchema<T>;
}): T | undefined;
declare const postJsonToApi: <T>({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch, }: {
url: string;
headers?: Record<string, string | undefined>;
body: unknown;
failedResponseHandler: ResponseHandler<APICallError>;
successfulResponseHandler: ResponseHandler<T>;
abortSignal?: AbortSignal;
fetch?: FetchFunction;
}) => Promise<{
value: T;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>;
declare const postFormDataToApi: <T>({ url, headers, formData, failedResponseHandler, successfulResponseHandler, abortSignal, fetch, }: {
url: string;
headers?: Record<string, string | undefined>;
formData: FormData;
failedResponseHandler: ResponseHandler<APICallError>;
successfulResponseHandler: ResponseHandler<T>;
abortSignal?: AbortSignal;
fetch?: FetchFunction;
}) => Promise<{
value: T;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>;
declare const postToApi: <T>({ url, headers, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch, }: {
url: string;
headers?: Record<string, string | undefined>;
body: {
content: string | FormData | Uint8Array;
values: unknown;
};
failedResponseHandler: ResponseHandler<Error>;
successfulResponseHandler: ResponseHandler<T>;
abortSignal?: AbortSignal;
fetch?: FetchFunction;
}) => Promise<{
value: T;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>;
/**
* Removes entries from a record where the value is null or undefined.
* @param record - The input object whose entries may be null or undefined.
* @returns A new object containing only entries with non-null and non-undefined values.
*/
declare function removeUndefinedEntries<T>(record: Record<string, T | undefined>): Record<string, T>;
type Resolvable<T> = T | Promise<T> | (() => T) | (() => Promise<T>);
/**
* Resolves a value that could be a raw value, a Promise, a function returning a value,
* or a function returning a Promise.
*/
declare function resolve<T>(value: Resolvable<T>): Promise<T>;
declare function convertBase64ToUint8Array(base64String: string): Uint8Array;
declare function convertUint8ArrayToBase64(array: Uint8Array): string;
/**
* Validates the types of an unknown object using a schema and
* return a strongly-typed object.
*
* @template T - The type of the object to validate.
* @param {string} options.value - The object to validate.
* @param {Validator<T>} options.schema - The schema to use for validating the JSON.
* @returns {T} - The typed object.
*/
declare function validateTypes<T>({ value, schema: inputSchema, }: {
value: unknown;
schema: z.Schema<T, z.ZodTypeDef, any> | Validator<T>;
}): T;
/**
* Safely validates the types of an unknown object using a schema and
* return a strongly-typed object.
*
* @template T - The type of the object to validate.
* @param {string} options.value - The JSON object to validate.
* @param {Validator<T>} options.schema - The schema to use for validating the JSON.
* @returns An object with either a `success` flag and the parsed and typed data, or a `success` flag and an error object.
*/
declare function safeValidateTypes<T>({ value, schema, }: {
value: unknown;
schema: z.Schema<T, z.ZodTypeDef, any> | Validator<T>;
}): {
success: true;
value: T;
} | {
success: false;
error: TypeValidationError;
};
declare function withoutTrailingSlash(url: string | undefined): string | undefined;
/**
Typed tool call that is returned by generateText and streamText.
It contains the tool call ID, the tool name, and the tool arguments.
*/
interface ToolCall<NAME extends string, ARGS> {
/**
ID of the tool call. This ID is used to match the tool call with the tool result.
*/
toolCallId: string;
/**
Name of the tool that is being called.
*/
toolName: NAME;
/**
Arguments of the tool call. This is a JSON-serializable object that matches the tool's input schema.
*/
args: ARGS;
}
/**
* @deprecated Use `ToolCall` instead.
*/
type CoreToolCall<NAME extends string, ARGS> = ToolCall<NAME, ARGS>;
/**
Typed tool result that is returned by `generateText` and `streamText`.
It contains the tool call ID, the tool name, the tool arguments, and the tool result.
*/
interface ToolResult<NAME extends string, ARGS, RESULT> {
/**
ID of the tool call. This ID is used to match the tool call with the tool result.
*/
toolCallId: string;
/**
Name of the tool that was called.
*/
toolName: NAME;
/**
Arguments of the tool call. This is a JSON-serializable object that matches the tool's input schema.
*/
args: ARGS;
/**
Result of the tool call. This is the result of the tool's execution.
*/
result: RESULT;
}
/**
* @deprecated Use `ToolResult` instead.
*/
type CoreToolResult<NAME extends string, ARGS, RESULT> = ToolResult<NAME, ARGS, RESULT>;
export { type CoreToolCall, type CoreToolResult, type EventSourceChunk, type FetchFunction, type IDGenerator, type ParseResult, type Resolvable, type ResponseHandler, type ToolCall, type ToolResult, type ValidationResult, type Validator, asValidator, combineHeaders, convertAsyncIteratorToReadableStream, convertBase64ToUint8Array, convertUint8ArrayToBase64, createBinaryResponseHandler, createEventSourceParserStream, createEventSourceResponseHandler, createIdGenerator, createJsonErrorResponseHandler, createJsonResponseHandler, createJsonStreamResponseHandler, createStatusCodeErrorResponseHandler, delay, extractResponseHeaders, generateId, getErrorMessage, getFromApi, isAbortError, isParsableJson, isValidator, loadApiKey, loadOptionalSetting, loadSetting, parseJSON, parseProviderOptions, postFormDataToApi, postJsonToApi, postToApi, removeUndefinedEntries, resolve, safeParseJSON, safeValidateTypes, validateTypes, validator, validatorSymbol, withoutTrailingSlash, zodValidator };

View File

@@ -0,0 +1,379 @@
import { JSONValue, JSONParseError, TypeValidationError, APICallError } from '@ai-sdk/provider';
import { z, ZodSchema } from 'zod';
declare function combineHeaders(...headers: Array<Record<string, string | undefined> | undefined>): Record<string, string | undefined>;
/**
* Converts an AsyncIterator to a ReadableStream.
*
* @template T - The type of elements produced by the AsyncIterator.
* @param { <T>} iterator - The AsyncIterator to convert.
* @returns {ReadableStream<T>} - A ReadableStream that provides the same data as the AsyncIterator.
*/
declare function convertAsyncIteratorToReadableStream<T>(iterator: AsyncIterator<T>): ReadableStream<T>;
/**
* Creates a Promise that resolves after a specified delay
* @param delayInMs - The delay duration in milliseconds. If null or undefined, resolves immediately.
* @returns A Promise that resolves after the specified delay
*/
declare function delay(delayInMs?: number | null): Promise<void>;
type EventSourceChunk = {
event: string | undefined;
data: string;
id?: string;
retry?: number;
};
declare function createEventSourceParserStream(): TransformStream<string, EventSourceChunk>;
/**
Extracts the headers from a response object and returns them as a key-value object.
@param response - The response object to extract headers from.
@returns The headers as a key-value object.
*/
declare function extractResponseHeaders(response: Response): Record<string, string>;
/**
* Fetch function type (standardizes the version of fetch used).
*/
type FetchFunction = typeof globalThis.fetch;
/**
Creates an ID generator.
The total length of the ID is the sum of the prefix, separator, and random part length.
Non-secure.
@param alphabet - The alphabet to use for the ID. Default: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.
@param prefix - The prefix of the ID to generate. Default: ''.
@param separator - The separator between the prefix and the random part of the ID. Default: '-'.
@param size - The size of the random part of the ID to generate. Default: 16.
*/
declare const createIdGenerator: ({ prefix, size: defaultSize, alphabet, separator, }?: {
prefix?: string;
separator?: string;
size?: number;
alphabet?: string;
}) => ((size?: number) => string);
/**
A function that generates an ID.
*/
type IDGenerator = () => string;
/**
Generates a 16-character random string to use for IDs. Not secure.
@param size - The size of the ID to generate. Default: 16.
*/
declare const generateId: (size?: number) => string;
declare function getErrorMessage(error: unknown | undefined): string;
/**
* Used to mark validator functions so we can support both Zod and custom schemas.
*/
declare const validatorSymbol: unique symbol;
type ValidationResult<OBJECT> = {
success: true;
value: OBJECT;
} | {
success: false;
error: Error;
};
type Validator<OBJECT = unknown> = {
/**
* Used to mark validator functions so we can support both Zod and custom schemas.
*/
[validatorSymbol]: true;
/**
* Optional. Validates that the structure of a value matches this schema,
* and returns a typed version of the value if it does.
*/
readonly validate?: (value: unknown) => ValidationResult<OBJECT>;
};
/**
* Create a validator.
*
* @param validate A validation function for the schema.
*/
declare function validator<OBJECT>(validate?: undefined | ((value: unknown) => ValidationResult<OBJECT>)): Validator<OBJECT>;
declare function isValidator(value: unknown): value is Validator;
declare function asValidator<OBJECT>(value: Validator<OBJECT> | z.Schema<OBJECT, z.ZodTypeDef, any>): Validator<OBJECT>;
declare function zodValidator<OBJECT>(zodSchema: z.Schema<OBJECT, z.ZodTypeDef, any>): Validator<OBJECT>;
/**
* Parses a JSON string into an unknown object.
*
* @param text - The JSON string to parse.
* @returns {JSONValue} - The parsed JSON object.
*/
declare function parseJSON(options: {
text: string;
schema?: undefined;
}): JSONValue;
/**
* Parses a JSON string into a strongly-typed object using the provided schema.
*
* @template T - The type of the object to parse the JSON into.
* @param {string} text - The JSON string to parse.
* @param {Validator<T>} schema - The schema to use for parsing the JSON.
* @returns {T} - The parsed object.
*/
declare function parseJSON<T>(options: {
text: string;
schema: ZodSchema<T> | Validator<T>;
}): T;
type ParseResult<T> = {
success: true;
value: T;
rawValue: unknown;
} | {
success: false;
error: JSONParseError | TypeValidationError;
};
/**
* Safely parses a JSON string and returns the result as an object of type `unknown`.
*
* @param text - The JSON string to parse.
* @returns {object} Either an object with `success: true` and the parsed data, or an object with `success: false` and the error that occurred.
*/
declare function safeParseJSON(options: {
text: string;
schema?: undefined;
}): ParseResult<JSONValue>;
/**
* Safely parses a JSON string into a strongly-typed object, using a provided schema to validate the object.
*
* @template T - The type of the object to parse the JSON into.
* @param {string} text - The JSON string to parse.
* @param {Validator<T>} schema - The schema to use for parsing the JSON.
* @returns An object with either a `success` flag and the parsed and typed data, or a `success` flag and an error object.
*/
declare function safeParseJSON<T>(options: {
text: string;
schema: ZodSchema<T> | Validator<T>;
}): ParseResult<T>;
declare function isParsableJson(input: string): boolean;
type ResponseHandler<RETURN_TYPE> = (options: {
url: string;
requestBodyValues: unknown;
response: Response;
}) => PromiseLike<{
value: RETURN_TYPE;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>;
declare const createJsonErrorResponseHandler: <T>({ errorSchema, errorToMessage, isRetryable, }: {
errorSchema: ZodSchema<T>;
errorToMessage: (error: T) => string;
isRetryable?: (response: Response, error?: T) => boolean;
}) => ResponseHandler<APICallError>;
declare const createEventSourceResponseHandler: <T>(chunkSchema: ZodSchema<T>) => ResponseHandler<ReadableStream<ParseResult<T>>>;
declare const createJsonStreamResponseHandler: <T>(chunkSchema: ZodSchema<T>) => ResponseHandler<ReadableStream<ParseResult<T>>>;
declare const createJsonResponseHandler: <T>(responseSchema: ZodSchema<T>) => ResponseHandler<T>;
declare const createBinaryResponseHandler: () => ResponseHandler<Uint8Array>;
declare const createStatusCodeErrorResponseHandler: () => ResponseHandler<APICallError>;
declare const getFromApi: <T>({ url, headers, successfulResponseHandler, failedResponseHandler, abortSignal, fetch, }: {
url: string;
headers?: Record<string, string | undefined>;
failedResponseHandler: ResponseHandler<Error>;
successfulResponseHandler: ResponseHandler<T>;
abortSignal?: AbortSignal;
fetch?: FetchFunction;
}) => Promise<{
value: T;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>;
declare function isAbortError(error: unknown): error is Error;
declare function loadApiKey({ apiKey, environmentVariableName, apiKeyParameterName, description, }: {
apiKey: string | undefined;
environmentVariableName: string;
apiKeyParameterName?: string;
description: string;
}): string;
/**
* Loads an optional `string` setting from the environment or a parameter.
*
* @param settingValue - The setting value.
* @param environmentVariableName - The environment variable name.
* @returns The setting value.
*/
declare function loadOptionalSetting({ settingValue, environmentVariableName, }: {
settingValue: string | undefined;
environmentVariableName: string;
}): string | undefined;
/**
* Loads a `string` setting from the environment or a parameter.
*
* @param settingValue - The setting value.
* @param environmentVariableName - The environment variable name.
* @param settingName - The setting name.
* @param description - The description of the setting.
* @returns The setting value.
*/
declare function loadSetting({ settingValue, environmentVariableName, settingName, description, }: {
settingValue: string | undefined;
environmentVariableName: string;
settingName: string;
description: string;
}): string;
declare function parseProviderOptions<T>({ provider, providerOptions, schema, }: {
provider: string;
providerOptions: Record<string, unknown> | undefined;
schema: z.ZodSchema<T>;
}): T | undefined;
declare const postJsonToApi: <T>({ url, headers, body, failedResponseHandler, successfulResponseHandler, abortSignal, fetch, }: {
url: string;
headers?: Record<string, string | undefined>;
body: unknown;
failedResponseHandler: ResponseHandler<APICallError>;
successfulResponseHandler: ResponseHandler<T>;
abortSignal?: AbortSignal;
fetch?: FetchFunction;
}) => Promise<{
value: T;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>;
declare const postFormDataToApi: <T>({ url, headers, formData, failedResponseHandler, successfulResponseHandler, abortSignal, fetch, }: {
url: string;
headers?: Record<string, string | undefined>;
formData: FormData;
failedResponseHandler: ResponseHandler<APICallError>;
successfulResponseHandler: ResponseHandler<T>;
abortSignal?: AbortSignal;
fetch?: FetchFunction;
}) => Promise<{
value: T;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>;
declare const postToApi: <T>({ url, headers, body, successfulResponseHandler, failedResponseHandler, abortSignal, fetch, }: {
url: string;
headers?: Record<string, string | undefined>;
body: {
content: string | FormData | Uint8Array;
values: unknown;
};
failedResponseHandler: ResponseHandler<Error>;
successfulResponseHandler: ResponseHandler<T>;
abortSignal?: AbortSignal;
fetch?: FetchFunction;
}) => Promise<{
value: T;
rawValue?: unknown;
responseHeaders?: Record<string, string>;
}>;
/**
* Removes entries from a record where the value is null or undefined.
* @param record - The input object whose entries may be null or undefined.
* @returns A new object containing only entries with non-null and non-undefined values.
*/
declare function removeUndefinedEntries<T>(record: Record<string, T | undefined>): Record<string, T>;
type Resolvable<T> = T | Promise<T> | (() => T) | (() => Promise<T>);
/**
* Resolves a value that could be a raw value, a Promise, a function returning a value,
* or a function returning a Promise.
*/
declare function resolve<T>(value: Resolvable<T>): Promise<T>;
declare function convertBase64ToUint8Array(base64String: string): Uint8Array;
declare function convertUint8ArrayToBase64(array: Uint8Array): string;
/**
* Validates the types of an unknown object using a schema and
* return a strongly-typed object.
*
* @template T - The type of the object to validate.
* @param {string} options.value - The object to validate.
* @param {Validator<T>} options.schema - The schema to use for validating the JSON.
* @returns {T} - The typed object.
*/
declare function validateTypes<T>({ value, schema: inputSchema, }: {
value: unknown;
schema: z.Schema<T, z.ZodTypeDef, any> | Validator<T>;
}): T;
/**
* Safely validates the types of an unknown object using a schema and
* return a strongly-typed object.
*
* @template T - The type of the object to validate.
* @param {string} options.value - The JSON object to validate.
* @param {Validator<T>} options.schema - The schema to use for validating the JSON.
* @returns An object with either a `success` flag and the parsed and typed data, or a `success` flag and an error object.
*/
declare function safeValidateTypes<T>({ value, schema, }: {
value: unknown;
schema: z.Schema<T, z.ZodTypeDef, any> | Validator<T>;
}): {
success: true;
value: T;
} | {
success: false;
error: TypeValidationError;
};
declare function withoutTrailingSlash(url: string | undefined): string | undefined;
/**
Typed tool call that is returned by generateText and streamText.
It contains the tool call ID, the tool name, and the tool arguments.
*/
interface ToolCall<NAME extends string, ARGS> {
/**
ID of the tool call. This ID is used to match the tool call with the tool result.
*/
toolCallId: string;
/**
Name of the tool that is being called.
*/
toolName: NAME;
/**
Arguments of the tool call. This is a JSON-serializable object that matches the tool's input schema.
*/
args: ARGS;
}
/**
* @deprecated Use `ToolCall` instead.
*/
type CoreToolCall<NAME extends string, ARGS> = ToolCall<NAME, ARGS>;
/**
Typed tool result that is returned by `generateText` and `streamText`.
It contains the tool call ID, the tool name, the tool arguments, and the tool result.
*/
interface ToolResult<NAME extends string, ARGS, RESULT> {
/**
ID of the tool call. This ID is used to match the tool call with the tool result.
*/
toolCallId: string;
/**
Name of the tool that was called.
*/
toolName: NAME;
/**
Arguments of the tool call. This is a JSON-serializable object that matches the tool's input schema.
*/
args: ARGS;
/**
Result of the tool call. This is the result of the tool's execution.
*/
result: RESULT;
}
/**
* @deprecated Use `ToolResult` instead.
*/
type CoreToolResult<NAME extends string, ARGS, RESULT> = ToolResult<NAME, ARGS, RESULT>;
export { type CoreToolCall, type CoreToolResult, type EventSourceChunk, type FetchFunction, type IDGenerator, type ParseResult, type Resolvable, type ResponseHandler, type ToolCall, type ToolResult, type ValidationResult, type Validator, asValidator, combineHeaders, convertAsyncIteratorToReadableStream, convertBase64ToUint8Array, convertUint8ArrayToBase64, createBinaryResponseHandler, createEventSourceParserStream, createEventSourceResponseHandler, createIdGenerator, createJsonErrorResponseHandler, createJsonResponseHandler, createJsonStreamResponseHandler, createStatusCodeErrorResponseHandler, delay, extractResponseHeaders, generateId, getErrorMessage, getFromApi, isAbortError, isParsableJson, isValidator, loadApiKey, loadOptionalSetting, loadSetting, parseJSON, parseProviderOptions, postFormDataToApi, postJsonToApi, postToApi, removeUndefinedEntries, resolve, safeParseJSON, safeValidateTypes, validateTypes, validator, validatorSymbol, withoutTrailingSlash, zodValidator };

View File

@@ -0,0 +1,944 @@
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
asValidator: () => asValidator,
combineHeaders: () => combineHeaders,
convertAsyncIteratorToReadableStream: () => convertAsyncIteratorToReadableStream,
convertBase64ToUint8Array: () => convertBase64ToUint8Array,
convertUint8ArrayToBase64: () => convertUint8ArrayToBase64,
createBinaryResponseHandler: () => createBinaryResponseHandler,
createEventSourceParserStream: () => createEventSourceParserStream,
createEventSourceResponseHandler: () => createEventSourceResponseHandler,
createIdGenerator: () => createIdGenerator,
createJsonErrorResponseHandler: () => createJsonErrorResponseHandler,
createJsonResponseHandler: () => createJsonResponseHandler,
createJsonStreamResponseHandler: () => createJsonStreamResponseHandler,
createStatusCodeErrorResponseHandler: () => createStatusCodeErrorResponseHandler,
delay: () => delay,
extractResponseHeaders: () => extractResponseHeaders,
generateId: () => generateId,
getErrorMessage: () => getErrorMessage,
getFromApi: () => getFromApi,
isAbortError: () => isAbortError,
isParsableJson: () => isParsableJson,
isValidator: () => isValidator,
loadApiKey: () => loadApiKey,
loadOptionalSetting: () => loadOptionalSetting,
loadSetting: () => loadSetting,
parseJSON: () => parseJSON,
parseProviderOptions: () => parseProviderOptions,
postFormDataToApi: () => postFormDataToApi,
postJsonToApi: () => postJsonToApi,
postToApi: () => postToApi,
removeUndefinedEntries: () => removeUndefinedEntries,
resolve: () => resolve,
safeParseJSON: () => safeParseJSON,
safeValidateTypes: () => safeValidateTypes,
validateTypes: () => validateTypes,
validator: () => validator,
validatorSymbol: () => validatorSymbol,
withoutTrailingSlash: () => withoutTrailingSlash,
zodValidator: () => zodValidator
});
module.exports = __toCommonJS(src_exports);
// src/combine-headers.ts
function combineHeaders(...headers) {
return headers.reduce(
(combinedHeaders, currentHeaders) => ({
...combinedHeaders,
...currentHeaders != null ? currentHeaders : {}
}),
{}
);
}
// src/convert-async-iterator-to-readable-stream.ts
function convertAsyncIteratorToReadableStream(iterator) {
return new ReadableStream({
/**
* Called when the consumer wants to pull more data from the stream.
*
* @param {ReadableStreamDefaultController<T>} controller - The controller to enqueue data into the stream.
* @returns {Promise<void>}
*/
async pull(controller) {
try {
const { value, done } = await iterator.next();
if (done) {
controller.close();
} else {
controller.enqueue(value);
}
} catch (error) {
controller.error(error);
}
},
/**
* Called when the consumer cancels the stream.
*/
cancel() {
}
});
}
// src/delay.ts
async function delay(delayInMs) {
return delayInMs == null ? Promise.resolve() : new Promise((resolve2) => setTimeout(resolve2, delayInMs));
}
// src/event-source-parser-stream.ts
function createEventSourceParserStream() {
let buffer = "";
let event = void 0;
let data = [];
let lastEventId = void 0;
let retry = void 0;
function parseLine(line, controller) {
if (line === "") {
dispatchEvent(controller);
return;
}
if (line.startsWith(":")) {
return;
}
const colonIndex = line.indexOf(":");
if (colonIndex === -1) {
handleField(line, "");
return;
}
const field = line.slice(0, colonIndex);
const valueStart = colonIndex + 1;
const value = valueStart < line.length && line[valueStart] === " " ? line.slice(valueStart + 1) : line.slice(valueStart);
handleField(field, value);
}
function dispatchEvent(controller) {
if (data.length > 0) {
controller.enqueue({
event,
data: data.join("\n"),
id: lastEventId,
retry
});
data = [];
event = void 0;
retry = void 0;
}
}
function handleField(field, value) {
switch (field) {
case "event":
event = value;
break;
case "data":
data.push(value);
break;
case "id":
lastEventId = value;
break;
case "retry":
const parsedRetry = parseInt(value, 10);
if (!isNaN(parsedRetry)) {
retry = parsedRetry;
}
break;
}
}
return new TransformStream({
transform(chunk, controller) {
const { lines, incompleteLine } = splitLines(buffer, chunk);
buffer = incompleteLine;
for (let i = 0; i < lines.length; i++) {
parseLine(lines[i], controller);
}
},
flush(controller) {
parseLine(buffer, controller);
dispatchEvent(controller);
}
});
}
function splitLines(buffer, chunk) {
const lines = [];
let currentLine = buffer;
for (let i = 0; i < chunk.length; ) {
const char = chunk[i++];
if (char === "\n") {
lines.push(currentLine);
currentLine = "";
} else if (char === "\r") {
lines.push(currentLine);
currentLine = "";
if (chunk[i] === "\n") {
i++;
}
} else {
currentLine += char;
}
}
return { lines, incompleteLine: currentLine };
}
// src/extract-response-headers.ts
function extractResponseHeaders(response) {
const headers = {};
response.headers.forEach((value, key) => {
headers[key] = value;
});
return headers;
}
// src/generate-id.ts
var import_provider = require("@ai-sdk/provider");
var import_non_secure = require("nanoid/non-secure");
var createIdGenerator = ({
prefix,
size: defaultSize = 16,
alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
separator = "-"
} = {}) => {
const generator = (0, import_non_secure.customAlphabet)(alphabet, defaultSize);
if (prefix == null) {
return generator;
}
if (alphabet.includes(separator)) {
throw new import_provider.InvalidArgumentError({
argument: "separator",
message: `The separator "${separator}" must not be part of the alphabet "${alphabet}".`
});
}
return (size) => `${prefix}${separator}${generator(size)}`;
};
var generateId = createIdGenerator();
// src/get-error-message.ts
function getErrorMessage(error) {
if (error == null) {
return "unknown error";
}
if (typeof error === "string") {
return error;
}
if (error instanceof Error) {
return error.message;
}
return JSON.stringify(error);
}
// src/get-from-api.ts
var import_provider2 = require("@ai-sdk/provider");
// src/remove-undefined-entries.ts
function removeUndefinedEntries(record) {
return Object.fromEntries(
Object.entries(record).filter(([_key, value]) => value != null)
);
}
// src/is-abort-error.ts
function isAbortError(error) {
return error instanceof Error && (error.name === "AbortError" || error.name === "TimeoutError");
}
// src/get-from-api.ts
var getOriginalFetch = () => globalThis.fetch;
var getFromApi = async ({
url,
headers = {},
successfulResponseHandler,
failedResponseHandler,
abortSignal,
fetch = getOriginalFetch()
}) => {
try {
const response = await fetch(url, {
method: "GET",
headers: removeUndefinedEntries(headers),
signal: abortSignal
});
const responseHeaders = extractResponseHeaders(response);
if (!response.ok) {
let errorInformation;
try {
errorInformation = await failedResponseHandler({
response,
url,
requestBodyValues: {}
});
} catch (error) {
if (isAbortError(error) || import_provider2.APICallError.isInstance(error)) {
throw error;
}
throw new import_provider2.APICallError({
message: "Failed to process error response",
cause: error,
statusCode: response.status,
url,
responseHeaders,
requestBodyValues: {}
});
}
throw errorInformation.value;
}
try {
return await successfulResponseHandler({
response,
url,
requestBodyValues: {}
});
} catch (error) {
if (error instanceof Error) {
if (isAbortError(error) || import_provider2.APICallError.isInstance(error)) {
throw error;
}
}
throw new import_provider2.APICallError({
message: "Failed to process successful response",
cause: error,
statusCode: response.status,
url,
responseHeaders,
requestBodyValues: {}
});
}
} catch (error) {
if (isAbortError(error)) {
throw error;
}
if (error instanceof TypeError && error.message === "fetch failed") {
const cause = error.cause;
if (cause != null) {
throw new import_provider2.APICallError({
message: `Cannot connect to API: ${cause.message}`,
cause,
url,
isRetryable: true,
requestBodyValues: {}
});
}
}
throw error;
}
};
// src/load-api-key.ts
var import_provider3 = require("@ai-sdk/provider");
function loadApiKey({
apiKey,
environmentVariableName,
apiKeyParameterName = "apiKey",
description
}) {
if (typeof apiKey === "string") {
return apiKey;
}
if (apiKey != null) {
throw new import_provider3.LoadAPIKeyError({
message: `${description} API key must be a string.`
});
}
if (typeof process === "undefined") {
throw new import_provider3.LoadAPIKeyError({
message: `${description} API key is missing. Pass it using the '${apiKeyParameterName}' parameter. Environment variables is not supported in this environment.`
});
}
apiKey = process.env[environmentVariableName];
if (apiKey == null) {
throw new import_provider3.LoadAPIKeyError({
message: `${description} API key is missing. Pass it using the '${apiKeyParameterName}' parameter or the ${environmentVariableName} environment variable.`
});
}
if (typeof apiKey !== "string") {
throw new import_provider3.LoadAPIKeyError({
message: `${description} API key must be a string. The value of the ${environmentVariableName} environment variable is not a string.`
});
}
return apiKey;
}
// src/load-optional-setting.ts
function loadOptionalSetting({
settingValue,
environmentVariableName
}) {
if (typeof settingValue === "string") {
return settingValue;
}
if (settingValue != null || typeof process === "undefined") {
return void 0;
}
settingValue = process.env[environmentVariableName];
if (settingValue == null || typeof settingValue !== "string") {
return void 0;
}
return settingValue;
}
// src/load-setting.ts
var import_provider4 = require("@ai-sdk/provider");
function loadSetting({
settingValue,
environmentVariableName,
settingName,
description
}) {
if (typeof settingValue === "string") {
return settingValue;
}
if (settingValue != null) {
throw new import_provider4.LoadSettingError({
message: `${description} setting must be a string.`
});
}
if (typeof process === "undefined") {
throw new import_provider4.LoadSettingError({
message: `${description} setting is missing. Pass it using the '${settingName}' parameter. Environment variables is not supported in this environment.`
});
}
settingValue = process.env[environmentVariableName];
if (settingValue == null) {
throw new import_provider4.LoadSettingError({
message: `${description} setting is missing. Pass it using the '${settingName}' parameter or the ${environmentVariableName} environment variable.`
});
}
if (typeof settingValue !== "string") {
throw new import_provider4.LoadSettingError({
message: `${description} setting must be a string. The value of the ${environmentVariableName} environment variable is not a string.`
});
}
return settingValue;
}
// src/parse-json.ts
var import_provider6 = require("@ai-sdk/provider");
var import_secure_json_parse = __toESM(require("secure-json-parse"));
// src/validate-types.ts
var import_provider5 = require("@ai-sdk/provider");
// src/validator.ts
var validatorSymbol = Symbol.for("vercel.ai.validator");
function validator(validate) {
return { [validatorSymbol]: true, validate };
}
function isValidator(value) {
return typeof value === "object" && value !== null && validatorSymbol in value && value[validatorSymbol] === true && "validate" in value;
}
function asValidator(value) {
return isValidator(value) ? value : zodValidator(value);
}
function zodValidator(zodSchema) {
return validator((value) => {
const result = zodSchema.safeParse(value);
return result.success ? { success: true, value: result.data } : { success: false, error: result.error };
});
}
// src/validate-types.ts
function validateTypes({
value,
schema: inputSchema
}) {
const result = safeValidateTypes({ value, schema: inputSchema });
if (!result.success) {
throw import_provider5.TypeValidationError.wrap({ value, cause: result.error });
}
return result.value;
}
function safeValidateTypes({
value,
schema
}) {
const validator2 = asValidator(schema);
try {
if (validator2.validate == null) {
return { success: true, value };
}
const result = validator2.validate(value);
if (result.success) {
return result;
}
return {
success: false,
error: import_provider5.TypeValidationError.wrap({ value, cause: result.error })
};
} catch (error) {
return {
success: false,
error: import_provider5.TypeValidationError.wrap({ value, cause: error })
};
}
}
// src/parse-json.ts
function parseJSON({
text,
schema
}) {
try {
const value = import_secure_json_parse.default.parse(text);
if (schema == null) {
return value;
}
return validateTypes({ value, schema });
} catch (error) {
if (import_provider6.JSONParseError.isInstance(error) || import_provider6.TypeValidationError.isInstance(error)) {
throw error;
}
throw new import_provider6.JSONParseError({ text, cause: error });
}
}
function safeParseJSON({
text,
schema
}) {
try {
const value = import_secure_json_parse.default.parse(text);
if (schema == null) {
return { success: true, value, rawValue: value };
}
const validationResult = safeValidateTypes({ value, schema });
return validationResult.success ? { ...validationResult, rawValue: value } : validationResult;
} catch (error) {
return {
success: false,
error: import_provider6.JSONParseError.isInstance(error) ? error : new import_provider6.JSONParseError({ text, cause: error })
};
}
}
function isParsableJson(input) {
try {
import_secure_json_parse.default.parse(input);
return true;
} catch (e) {
return false;
}
}
// src/parse-provider-options.ts
var import_provider7 = require("@ai-sdk/provider");
function parseProviderOptions({
provider,
providerOptions,
schema
}) {
if ((providerOptions == null ? void 0 : providerOptions[provider]) == null) {
return void 0;
}
const parsedProviderOptions = safeValidateTypes({
value: providerOptions[provider],
schema
});
if (!parsedProviderOptions.success) {
throw new import_provider7.InvalidArgumentError({
argument: "providerOptions",
message: `invalid ${provider} provider options`,
cause: parsedProviderOptions.error
});
}
return parsedProviderOptions.value;
}
// src/post-to-api.ts
var import_provider8 = require("@ai-sdk/provider");
var getOriginalFetch2 = () => globalThis.fetch;
var postJsonToApi = async ({
url,
headers,
body,
failedResponseHandler,
successfulResponseHandler,
abortSignal,
fetch
}) => postToApi({
url,
headers: {
"Content-Type": "application/json",
...headers
},
body: {
content: JSON.stringify(body),
values: body
},
failedResponseHandler,
successfulResponseHandler,
abortSignal,
fetch
});
var postFormDataToApi = async ({
url,
headers,
formData,
failedResponseHandler,
successfulResponseHandler,
abortSignal,
fetch
}) => postToApi({
url,
headers,
body: {
content: formData,
values: Object.fromEntries(formData.entries())
},
failedResponseHandler,
successfulResponseHandler,
abortSignal,
fetch
});
var postToApi = async ({
url,
headers = {},
body,
successfulResponseHandler,
failedResponseHandler,
abortSignal,
fetch = getOriginalFetch2()
}) => {
try {
const response = await fetch(url, {
method: "POST",
headers: removeUndefinedEntries(headers),
body: body.content,
signal: abortSignal
});
const responseHeaders = extractResponseHeaders(response);
if (!response.ok) {
let errorInformation;
try {
errorInformation = await failedResponseHandler({
response,
url,
requestBodyValues: body.values
});
} catch (error) {
if (isAbortError(error) || import_provider8.APICallError.isInstance(error)) {
throw error;
}
throw new import_provider8.APICallError({
message: "Failed to process error response",
cause: error,
statusCode: response.status,
url,
responseHeaders,
requestBodyValues: body.values
});
}
throw errorInformation.value;
}
try {
return await successfulResponseHandler({
response,
url,
requestBodyValues: body.values
});
} catch (error) {
if (error instanceof Error) {
if (isAbortError(error) || import_provider8.APICallError.isInstance(error)) {
throw error;
}
}
throw new import_provider8.APICallError({
message: "Failed to process successful response",
cause: error,
statusCode: response.status,
url,
responseHeaders,
requestBodyValues: body.values
});
}
} catch (error) {
if (isAbortError(error)) {
throw error;
}
if (error instanceof TypeError && error.message === "fetch failed") {
const cause = error.cause;
if (cause != null) {
throw new import_provider8.APICallError({
message: `Cannot connect to API: ${cause.message}`,
cause,
url,
requestBodyValues: body.values,
isRetryable: true
// retry when network error
});
}
}
throw error;
}
};
// src/resolve.ts
async function resolve(value) {
if (typeof value === "function") {
value = value();
}
return Promise.resolve(value);
}
// src/response-handler.ts
var import_provider9 = require("@ai-sdk/provider");
var createJsonErrorResponseHandler = ({
errorSchema,
errorToMessage,
isRetryable
}) => async ({ response, url, requestBodyValues }) => {
const responseBody = await response.text();
const responseHeaders = extractResponseHeaders(response);
if (responseBody.trim() === "") {
return {
responseHeaders,
value: new import_provider9.APICallError({
message: response.statusText,
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody,
isRetryable: isRetryable == null ? void 0 : isRetryable(response)
})
};
}
try {
const parsedError = parseJSON({
text: responseBody,
schema: errorSchema
});
return {
responseHeaders,
value: new import_provider9.APICallError({
message: errorToMessage(parsedError),
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody,
data: parsedError,
isRetryable: isRetryable == null ? void 0 : isRetryable(response, parsedError)
})
};
} catch (parseError) {
return {
responseHeaders,
value: new import_provider9.APICallError({
message: response.statusText,
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody,
isRetryable: isRetryable == null ? void 0 : isRetryable(response)
})
};
}
};
var createEventSourceResponseHandler = (chunkSchema) => async ({ response }) => {
const responseHeaders = extractResponseHeaders(response);
if (response.body == null) {
throw new import_provider9.EmptyResponseBodyError({});
}
return {
responseHeaders,
value: response.body.pipeThrough(new TextDecoderStream()).pipeThrough(createEventSourceParserStream()).pipeThrough(
new TransformStream({
transform({ data }, controller) {
if (data === "[DONE]") {
return;
}
controller.enqueue(
safeParseJSON({
text: data,
schema: chunkSchema
})
);
}
})
)
};
};
var createJsonStreamResponseHandler = (chunkSchema) => async ({ response }) => {
const responseHeaders = extractResponseHeaders(response);
if (response.body == null) {
throw new import_provider9.EmptyResponseBodyError({});
}
let buffer = "";
return {
responseHeaders,
value: response.body.pipeThrough(new TextDecoderStream()).pipeThrough(
new TransformStream({
transform(chunkText, controller) {
if (chunkText.endsWith("\n")) {
controller.enqueue(
safeParseJSON({
text: buffer + chunkText,
schema: chunkSchema
})
);
buffer = "";
} else {
buffer += chunkText;
}
}
})
)
};
};
var createJsonResponseHandler = (responseSchema) => async ({ response, url, requestBodyValues }) => {
const responseBody = await response.text();
const parsedResult = safeParseJSON({
text: responseBody,
schema: responseSchema
});
const responseHeaders = extractResponseHeaders(response);
if (!parsedResult.success) {
throw new import_provider9.APICallError({
message: "Invalid JSON response",
cause: parsedResult.error,
statusCode: response.status,
responseHeaders,
responseBody,
url,
requestBodyValues
});
}
return {
responseHeaders,
value: parsedResult.value,
rawValue: parsedResult.rawValue
};
};
var createBinaryResponseHandler = () => async ({ response, url, requestBodyValues }) => {
const responseHeaders = extractResponseHeaders(response);
if (!response.body) {
throw new import_provider9.APICallError({
message: "Response body is empty",
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody: void 0
});
}
try {
const buffer = await response.arrayBuffer();
return {
responseHeaders,
value: new Uint8Array(buffer)
};
} catch (error) {
throw new import_provider9.APICallError({
message: "Failed to read response as array buffer",
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody: void 0,
cause: error
});
}
};
var createStatusCodeErrorResponseHandler = () => async ({ response, url, requestBodyValues }) => {
const responseHeaders = extractResponseHeaders(response);
const responseBody = await response.text();
return {
responseHeaders,
value: new import_provider9.APICallError({
message: response.statusText,
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody
})
};
};
// src/uint8-utils.ts
var { btoa, atob } = globalThis;
function convertBase64ToUint8Array(base64String) {
const base64Url = base64String.replace(/-/g, "+").replace(/_/g, "/");
const latin1string = atob(base64Url);
return Uint8Array.from(latin1string, (byte) => byte.codePointAt(0));
}
function convertUint8ArrayToBase64(array) {
let latin1string = "";
for (let i = 0; i < array.length; i++) {
latin1string += String.fromCodePoint(array[i]);
}
return btoa(latin1string);
}
// src/without-trailing-slash.ts
function withoutTrailingSlash(url) {
return url == null ? void 0 : url.replace(/\/$/, "");
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
asValidator,
combineHeaders,
convertAsyncIteratorToReadableStream,
convertBase64ToUint8Array,
convertUint8ArrayToBase64,
createBinaryResponseHandler,
createEventSourceParserStream,
createEventSourceResponseHandler,
createIdGenerator,
createJsonErrorResponseHandler,
createJsonResponseHandler,
createJsonStreamResponseHandler,
createStatusCodeErrorResponseHandler,
delay,
extractResponseHeaders,
generateId,
getErrorMessage,
getFromApi,
isAbortError,
isParsableJson,
isValidator,
loadApiKey,
loadOptionalSetting,
loadSetting,
parseJSON,
parseProviderOptions,
postFormDataToApi,
postJsonToApi,
postToApi,
removeUndefinedEntries,
resolve,
safeParseJSON,
safeValidateTypes,
validateTypes,
validator,
validatorSymbol,
withoutTrailingSlash,
zodValidator
});
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,873 @@
// src/combine-headers.ts
function combineHeaders(...headers) {
return headers.reduce(
(combinedHeaders, currentHeaders) => ({
...combinedHeaders,
...currentHeaders != null ? currentHeaders : {}
}),
{}
);
}
// src/convert-async-iterator-to-readable-stream.ts
function convertAsyncIteratorToReadableStream(iterator) {
return new ReadableStream({
/**
* Called when the consumer wants to pull more data from the stream.
*
* @param {ReadableStreamDefaultController<T>} controller - The controller to enqueue data into the stream.
* @returns {Promise<void>}
*/
async pull(controller) {
try {
const { value, done } = await iterator.next();
if (done) {
controller.close();
} else {
controller.enqueue(value);
}
} catch (error) {
controller.error(error);
}
},
/**
* Called when the consumer cancels the stream.
*/
cancel() {
}
});
}
// src/delay.ts
async function delay(delayInMs) {
return delayInMs == null ? Promise.resolve() : new Promise((resolve2) => setTimeout(resolve2, delayInMs));
}
// src/event-source-parser-stream.ts
function createEventSourceParserStream() {
let buffer = "";
let event = void 0;
let data = [];
let lastEventId = void 0;
let retry = void 0;
function parseLine(line, controller) {
if (line === "") {
dispatchEvent(controller);
return;
}
if (line.startsWith(":")) {
return;
}
const colonIndex = line.indexOf(":");
if (colonIndex === -1) {
handleField(line, "");
return;
}
const field = line.slice(0, colonIndex);
const valueStart = colonIndex + 1;
const value = valueStart < line.length && line[valueStart] === " " ? line.slice(valueStart + 1) : line.slice(valueStart);
handleField(field, value);
}
function dispatchEvent(controller) {
if (data.length > 0) {
controller.enqueue({
event,
data: data.join("\n"),
id: lastEventId,
retry
});
data = [];
event = void 0;
retry = void 0;
}
}
function handleField(field, value) {
switch (field) {
case "event":
event = value;
break;
case "data":
data.push(value);
break;
case "id":
lastEventId = value;
break;
case "retry":
const parsedRetry = parseInt(value, 10);
if (!isNaN(parsedRetry)) {
retry = parsedRetry;
}
break;
}
}
return new TransformStream({
transform(chunk, controller) {
const { lines, incompleteLine } = splitLines(buffer, chunk);
buffer = incompleteLine;
for (let i = 0; i < lines.length; i++) {
parseLine(lines[i], controller);
}
},
flush(controller) {
parseLine(buffer, controller);
dispatchEvent(controller);
}
});
}
function splitLines(buffer, chunk) {
const lines = [];
let currentLine = buffer;
for (let i = 0; i < chunk.length; ) {
const char = chunk[i++];
if (char === "\n") {
lines.push(currentLine);
currentLine = "";
} else if (char === "\r") {
lines.push(currentLine);
currentLine = "";
if (chunk[i] === "\n") {
i++;
}
} else {
currentLine += char;
}
}
return { lines, incompleteLine: currentLine };
}
// src/extract-response-headers.ts
function extractResponseHeaders(response) {
const headers = {};
response.headers.forEach((value, key) => {
headers[key] = value;
});
return headers;
}
// src/generate-id.ts
import { InvalidArgumentError } from "@ai-sdk/provider";
import { customAlphabet } from "nanoid/non-secure";
var createIdGenerator = ({
prefix,
size: defaultSize = 16,
alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",
separator = "-"
} = {}) => {
const generator = customAlphabet(alphabet, defaultSize);
if (prefix == null) {
return generator;
}
if (alphabet.includes(separator)) {
throw new InvalidArgumentError({
argument: "separator",
message: `The separator "${separator}" must not be part of the alphabet "${alphabet}".`
});
}
return (size) => `${prefix}${separator}${generator(size)}`;
};
var generateId = createIdGenerator();
// src/get-error-message.ts
function getErrorMessage(error) {
if (error == null) {
return "unknown error";
}
if (typeof error === "string") {
return error;
}
if (error instanceof Error) {
return error.message;
}
return JSON.stringify(error);
}
// src/get-from-api.ts
import { APICallError } from "@ai-sdk/provider";
// src/remove-undefined-entries.ts
function removeUndefinedEntries(record) {
return Object.fromEntries(
Object.entries(record).filter(([_key, value]) => value != null)
);
}
// src/is-abort-error.ts
function isAbortError(error) {
return error instanceof Error && (error.name === "AbortError" || error.name === "TimeoutError");
}
// src/get-from-api.ts
var getOriginalFetch = () => globalThis.fetch;
var getFromApi = async ({
url,
headers = {},
successfulResponseHandler,
failedResponseHandler,
abortSignal,
fetch = getOriginalFetch()
}) => {
try {
const response = await fetch(url, {
method: "GET",
headers: removeUndefinedEntries(headers),
signal: abortSignal
});
const responseHeaders = extractResponseHeaders(response);
if (!response.ok) {
let errorInformation;
try {
errorInformation = await failedResponseHandler({
response,
url,
requestBodyValues: {}
});
} catch (error) {
if (isAbortError(error) || APICallError.isInstance(error)) {
throw error;
}
throw new APICallError({
message: "Failed to process error response",
cause: error,
statusCode: response.status,
url,
responseHeaders,
requestBodyValues: {}
});
}
throw errorInformation.value;
}
try {
return await successfulResponseHandler({
response,
url,
requestBodyValues: {}
});
} catch (error) {
if (error instanceof Error) {
if (isAbortError(error) || APICallError.isInstance(error)) {
throw error;
}
}
throw new APICallError({
message: "Failed to process successful response",
cause: error,
statusCode: response.status,
url,
responseHeaders,
requestBodyValues: {}
});
}
} catch (error) {
if (isAbortError(error)) {
throw error;
}
if (error instanceof TypeError && error.message === "fetch failed") {
const cause = error.cause;
if (cause != null) {
throw new APICallError({
message: `Cannot connect to API: ${cause.message}`,
cause,
url,
isRetryable: true,
requestBodyValues: {}
});
}
}
throw error;
}
};
// src/load-api-key.ts
import { LoadAPIKeyError } from "@ai-sdk/provider";
function loadApiKey({
apiKey,
environmentVariableName,
apiKeyParameterName = "apiKey",
description
}) {
if (typeof apiKey === "string") {
return apiKey;
}
if (apiKey != null) {
throw new LoadAPIKeyError({
message: `${description} API key must be a string.`
});
}
if (typeof process === "undefined") {
throw new LoadAPIKeyError({
message: `${description} API key is missing. Pass it using the '${apiKeyParameterName}' parameter. Environment variables is not supported in this environment.`
});
}
apiKey = process.env[environmentVariableName];
if (apiKey == null) {
throw new LoadAPIKeyError({
message: `${description} API key is missing. Pass it using the '${apiKeyParameterName}' parameter or the ${environmentVariableName} environment variable.`
});
}
if (typeof apiKey !== "string") {
throw new LoadAPIKeyError({
message: `${description} API key must be a string. The value of the ${environmentVariableName} environment variable is not a string.`
});
}
return apiKey;
}
// src/load-optional-setting.ts
function loadOptionalSetting({
settingValue,
environmentVariableName
}) {
if (typeof settingValue === "string") {
return settingValue;
}
if (settingValue != null || typeof process === "undefined") {
return void 0;
}
settingValue = process.env[environmentVariableName];
if (settingValue == null || typeof settingValue !== "string") {
return void 0;
}
return settingValue;
}
// src/load-setting.ts
import { LoadSettingError } from "@ai-sdk/provider";
function loadSetting({
settingValue,
environmentVariableName,
settingName,
description
}) {
if (typeof settingValue === "string") {
return settingValue;
}
if (settingValue != null) {
throw new LoadSettingError({
message: `${description} setting must be a string.`
});
}
if (typeof process === "undefined") {
throw new LoadSettingError({
message: `${description} setting is missing. Pass it using the '${settingName}' parameter. Environment variables is not supported in this environment.`
});
}
settingValue = process.env[environmentVariableName];
if (settingValue == null) {
throw new LoadSettingError({
message: `${description} setting is missing. Pass it using the '${settingName}' parameter or the ${environmentVariableName} environment variable.`
});
}
if (typeof settingValue !== "string") {
throw new LoadSettingError({
message: `${description} setting must be a string. The value of the ${environmentVariableName} environment variable is not a string.`
});
}
return settingValue;
}
// src/parse-json.ts
import {
JSONParseError,
TypeValidationError as TypeValidationError2
} from "@ai-sdk/provider";
import SecureJSON from "secure-json-parse";
// src/validate-types.ts
import { TypeValidationError } from "@ai-sdk/provider";
// src/validator.ts
var validatorSymbol = Symbol.for("vercel.ai.validator");
function validator(validate) {
return { [validatorSymbol]: true, validate };
}
function isValidator(value) {
return typeof value === "object" && value !== null && validatorSymbol in value && value[validatorSymbol] === true && "validate" in value;
}
function asValidator(value) {
return isValidator(value) ? value : zodValidator(value);
}
function zodValidator(zodSchema) {
return validator((value) => {
const result = zodSchema.safeParse(value);
return result.success ? { success: true, value: result.data } : { success: false, error: result.error };
});
}
// src/validate-types.ts
function validateTypes({
value,
schema: inputSchema
}) {
const result = safeValidateTypes({ value, schema: inputSchema });
if (!result.success) {
throw TypeValidationError.wrap({ value, cause: result.error });
}
return result.value;
}
function safeValidateTypes({
value,
schema
}) {
const validator2 = asValidator(schema);
try {
if (validator2.validate == null) {
return { success: true, value };
}
const result = validator2.validate(value);
if (result.success) {
return result;
}
return {
success: false,
error: TypeValidationError.wrap({ value, cause: result.error })
};
} catch (error) {
return {
success: false,
error: TypeValidationError.wrap({ value, cause: error })
};
}
}
// src/parse-json.ts
function parseJSON({
text,
schema
}) {
try {
const value = SecureJSON.parse(text);
if (schema == null) {
return value;
}
return validateTypes({ value, schema });
} catch (error) {
if (JSONParseError.isInstance(error) || TypeValidationError2.isInstance(error)) {
throw error;
}
throw new JSONParseError({ text, cause: error });
}
}
function safeParseJSON({
text,
schema
}) {
try {
const value = SecureJSON.parse(text);
if (schema == null) {
return { success: true, value, rawValue: value };
}
const validationResult = safeValidateTypes({ value, schema });
return validationResult.success ? { ...validationResult, rawValue: value } : validationResult;
} catch (error) {
return {
success: false,
error: JSONParseError.isInstance(error) ? error : new JSONParseError({ text, cause: error })
};
}
}
function isParsableJson(input) {
try {
SecureJSON.parse(input);
return true;
} catch (e) {
return false;
}
}
// src/parse-provider-options.ts
import { InvalidArgumentError as InvalidArgumentError2 } from "@ai-sdk/provider";
function parseProviderOptions({
provider,
providerOptions,
schema
}) {
if ((providerOptions == null ? void 0 : providerOptions[provider]) == null) {
return void 0;
}
const parsedProviderOptions = safeValidateTypes({
value: providerOptions[provider],
schema
});
if (!parsedProviderOptions.success) {
throw new InvalidArgumentError2({
argument: "providerOptions",
message: `invalid ${provider} provider options`,
cause: parsedProviderOptions.error
});
}
return parsedProviderOptions.value;
}
// src/post-to-api.ts
import { APICallError as APICallError2 } from "@ai-sdk/provider";
var getOriginalFetch2 = () => globalThis.fetch;
var postJsonToApi = async ({
url,
headers,
body,
failedResponseHandler,
successfulResponseHandler,
abortSignal,
fetch
}) => postToApi({
url,
headers: {
"Content-Type": "application/json",
...headers
},
body: {
content: JSON.stringify(body),
values: body
},
failedResponseHandler,
successfulResponseHandler,
abortSignal,
fetch
});
var postFormDataToApi = async ({
url,
headers,
formData,
failedResponseHandler,
successfulResponseHandler,
abortSignal,
fetch
}) => postToApi({
url,
headers,
body: {
content: formData,
values: Object.fromEntries(formData.entries())
},
failedResponseHandler,
successfulResponseHandler,
abortSignal,
fetch
});
var postToApi = async ({
url,
headers = {},
body,
successfulResponseHandler,
failedResponseHandler,
abortSignal,
fetch = getOriginalFetch2()
}) => {
try {
const response = await fetch(url, {
method: "POST",
headers: removeUndefinedEntries(headers),
body: body.content,
signal: abortSignal
});
const responseHeaders = extractResponseHeaders(response);
if (!response.ok) {
let errorInformation;
try {
errorInformation = await failedResponseHandler({
response,
url,
requestBodyValues: body.values
});
} catch (error) {
if (isAbortError(error) || APICallError2.isInstance(error)) {
throw error;
}
throw new APICallError2({
message: "Failed to process error response",
cause: error,
statusCode: response.status,
url,
responseHeaders,
requestBodyValues: body.values
});
}
throw errorInformation.value;
}
try {
return await successfulResponseHandler({
response,
url,
requestBodyValues: body.values
});
} catch (error) {
if (error instanceof Error) {
if (isAbortError(error) || APICallError2.isInstance(error)) {
throw error;
}
}
throw new APICallError2({
message: "Failed to process successful response",
cause: error,
statusCode: response.status,
url,
responseHeaders,
requestBodyValues: body.values
});
}
} catch (error) {
if (isAbortError(error)) {
throw error;
}
if (error instanceof TypeError && error.message === "fetch failed") {
const cause = error.cause;
if (cause != null) {
throw new APICallError2({
message: `Cannot connect to API: ${cause.message}`,
cause,
url,
requestBodyValues: body.values,
isRetryable: true
// retry when network error
});
}
}
throw error;
}
};
// src/resolve.ts
async function resolve(value) {
if (typeof value === "function") {
value = value();
}
return Promise.resolve(value);
}
// src/response-handler.ts
import { APICallError as APICallError3, EmptyResponseBodyError } from "@ai-sdk/provider";
var createJsonErrorResponseHandler = ({
errorSchema,
errorToMessage,
isRetryable
}) => async ({ response, url, requestBodyValues }) => {
const responseBody = await response.text();
const responseHeaders = extractResponseHeaders(response);
if (responseBody.trim() === "") {
return {
responseHeaders,
value: new APICallError3({
message: response.statusText,
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody,
isRetryable: isRetryable == null ? void 0 : isRetryable(response)
})
};
}
try {
const parsedError = parseJSON({
text: responseBody,
schema: errorSchema
});
return {
responseHeaders,
value: new APICallError3({
message: errorToMessage(parsedError),
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody,
data: parsedError,
isRetryable: isRetryable == null ? void 0 : isRetryable(response, parsedError)
})
};
} catch (parseError) {
return {
responseHeaders,
value: new APICallError3({
message: response.statusText,
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody,
isRetryable: isRetryable == null ? void 0 : isRetryable(response)
})
};
}
};
var createEventSourceResponseHandler = (chunkSchema) => async ({ response }) => {
const responseHeaders = extractResponseHeaders(response);
if (response.body == null) {
throw new EmptyResponseBodyError({});
}
return {
responseHeaders,
value: response.body.pipeThrough(new TextDecoderStream()).pipeThrough(createEventSourceParserStream()).pipeThrough(
new TransformStream({
transform({ data }, controller) {
if (data === "[DONE]") {
return;
}
controller.enqueue(
safeParseJSON({
text: data,
schema: chunkSchema
})
);
}
})
)
};
};
var createJsonStreamResponseHandler = (chunkSchema) => async ({ response }) => {
const responseHeaders = extractResponseHeaders(response);
if (response.body == null) {
throw new EmptyResponseBodyError({});
}
let buffer = "";
return {
responseHeaders,
value: response.body.pipeThrough(new TextDecoderStream()).pipeThrough(
new TransformStream({
transform(chunkText, controller) {
if (chunkText.endsWith("\n")) {
controller.enqueue(
safeParseJSON({
text: buffer + chunkText,
schema: chunkSchema
})
);
buffer = "";
} else {
buffer += chunkText;
}
}
})
)
};
};
var createJsonResponseHandler = (responseSchema) => async ({ response, url, requestBodyValues }) => {
const responseBody = await response.text();
const parsedResult = safeParseJSON({
text: responseBody,
schema: responseSchema
});
const responseHeaders = extractResponseHeaders(response);
if (!parsedResult.success) {
throw new APICallError3({
message: "Invalid JSON response",
cause: parsedResult.error,
statusCode: response.status,
responseHeaders,
responseBody,
url,
requestBodyValues
});
}
return {
responseHeaders,
value: parsedResult.value,
rawValue: parsedResult.rawValue
};
};
var createBinaryResponseHandler = () => async ({ response, url, requestBodyValues }) => {
const responseHeaders = extractResponseHeaders(response);
if (!response.body) {
throw new APICallError3({
message: "Response body is empty",
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody: void 0
});
}
try {
const buffer = await response.arrayBuffer();
return {
responseHeaders,
value: new Uint8Array(buffer)
};
} catch (error) {
throw new APICallError3({
message: "Failed to read response as array buffer",
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody: void 0,
cause: error
});
}
};
var createStatusCodeErrorResponseHandler = () => async ({ response, url, requestBodyValues }) => {
const responseHeaders = extractResponseHeaders(response);
const responseBody = await response.text();
return {
responseHeaders,
value: new APICallError3({
message: response.statusText,
url,
requestBodyValues,
statusCode: response.status,
responseHeaders,
responseBody
})
};
};
// src/uint8-utils.ts
var { btoa, atob } = globalThis;
function convertBase64ToUint8Array(base64String) {
const base64Url = base64String.replace(/-/g, "+").replace(/_/g, "/");
const latin1string = atob(base64Url);
return Uint8Array.from(latin1string, (byte) => byte.codePointAt(0));
}
function convertUint8ArrayToBase64(array) {
let latin1string = "";
for (let i = 0; i < array.length; i++) {
latin1string += String.fromCodePoint(array[i]);
}
return btoa(latin1string);
}
// src/without-trailing-slash.ts
function withoutTrailingSlash(url) {
return url == null ? void 0 : url.replace(/\/$/, "");
}
export {
asValidator,
combineHeaders,
convertAsyncIteratorToReadableStream,
convertBase64ToUint8Array,
convertUint8ArrayToBase64,
createBinaryResponseHandler,
createEventSourceParserStream,
createEventSourceResponseHandler,
createIdGenerator,
createJsonErrorResponseHandler,
createJsonResponseHandler,
createJsonStreamResponseHandler,
createStatusCodeErrorResponseHandler,
delay,
extractResponseHeaders,
generateId,
getErrorMessage,
getFromApi,
isAbortError,
isParsableJson,
isValidator,
loadApiKey,
loadOptionalSetting,
loadSetting,
parseJSON,
parseProviderOptions,
postFormDataToApi,
postJsonToApi,
postToApi,
removeUndefinedEntries,
resolve,
safeParseJSON,
safeValidateTypes,
validateTypes,
validator,
validatorSymbol,
withoutTrailingSlash,
zodValidator
};
//# sourceMappingURL=index.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,72 @@
{
"name": "@ai-sdk/provider-utils",
"version": "2.2.8",
"license": "Apache-2.0",
"sideEffects": false,
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist/**/*",
"test/dist/**/*",
"CHANGELOG.md"
],
"exports": {
"./package.json": "./package.json",
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./test": {
"types": "./test/dist/index.d.ts",
"import": "./test/dist/index.mjs",
"module": "./test/dist/index.mjs",
"require": "./test/dist/index.js"
}
},
"dependencies": {
"@ai-sdk/provider": "1.1.3",
"nanoid": "^3.3.8",
"secure-json-parse": "^2.7.0"
},
"devDependencies": {
"@types/node": "20.17.24",
"msw": "2.7.0",
"tsup": "^8",
"typescript": "5.6.3",
"zod": "3.23.8",
"@vercel/ai-tsconfig": "0.0.0"
},
"peerDependencies": {
"zod": "^3.23.8"
},
"engines": {
"node": ">=18"
},
"publishConfig": {
"access": "public"
},
"homepage": "https://ai-sdk.dev/docs",
"repository": {
"type": "git",
"url": "git+https://github.com/vercel/ai.git"
},
"bugs": {
"url": "https://github.com/vercel/ai/issues"
},
"keywords": [
"ai"
],
"scripts": {
"build": "tsup",
"build:watch": "tsup --watch",
"clean": "rm -rf dist && rm -rf test/dist",
"lint": "eslint \"./**/*.ts*\"",
"type-check": "tsc --noEmit",
"prettier-check": "prettier --check \"./**/*.ts*\"",
"test": "pnpm test:node && pnpm test:edge",
"test:edge": "vitest --config vitest.edge.config.js --run",
"test:node": "vitest --config vitest.node.config.js --run"
}
}

View File

@@ -0,0 +1,45 @@
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined")
return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
var __accessCheck = (obj, member, msg) => {
if (!member.has(obj))
throw TypeError("Cannot " + msg);
};
var __privateGet = (obj, member, getter) => {
__accessCheck(obj, member, "read from private field");
return getter ? getter.call(obj) : member.get(obj);
};
var __privateAdd = (obj, member, value) => {
if (member.has(obj))
throw TypeError("Cannot add the same private member more than once");
member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
};
var __privateSet = (obj, member, value, setter) => {
__accessCheck(obj, member, "write to private field");
setter ? setter.call(obj, value) : member.set(obj, value);
return value;
};
var __privateMethod = (obj, member, method) => {
__accessCheck(obj, member, "access private method");
return method;
};
export {
__require,
__publicField,
__privateGet,
__privateAdd,
__privateSet,
__privateMethod
};
//# sourceMappingURL=chunk-D6YTI3O5.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,162 @@
import { SetupServer } from 'msw/node';
import { JsonBodyType } from 'msw';
declare function convertArrayToAsyncIterable<T>(values: T[]): AsyncIterable<T>;
declare function convertArrayToReadableStream<T>(values: T[]): ReadableStream<T>;
declare function convertAsyncIterableToArray<T>(iterable: AsyncIterable<T>): Promise<T[]>;
declare function convertReadableStreamToArray<T>(stream: ReadableStream<T>): Promise<T[]>;
declare function convertResponseStreamToArray(response: Response): Promise<string[]>;
/**
* @deprecated Use createTestServer instead
*/
declare class JsonTestServer {
readonly server: SetupServer;
responseHeaders: Record<string, string>;
responseBodyJson: any;
request: Request | undefined;
/**
* @deprecated Use createTestServer instead
*/
constructor(url: string);
getRequestBodyJson(): Promise<any>;
getRequestHeaders(): Promise<Record<string, string>>;
getRequestUrlSearchParams(): Promise<URLSearchParams>;
getRequestUrl(): Promise<string>;
setupTestEnvironment(): void;
}
declare function mockId({ prefix, }?: {
prefix?: string;
}): () => string;
/**
* @deprecated Use createTestServer instead
*/
declare class StreamingTestServer {
readonly server: SetupServer;
responseHeaders: Record<string, string>;
responseChunks: any[];
request: Request | undefined;
/**
* @deprecated Use createTestServer instead
*/
constructor(url: string);
getRequestBodyJson(): Promise<any>;
getRequestHeaders(): Promise<Record<string, string>>;
getRequestUrlSearchParams(): Promise<URLSearchParams>;
setupTestEnvironment(): void;
}
type TestServerJsonBodyType = JsonBodyType;
type TestServerResponse = {
url: string;
headers?: Record<string, string>;
} & ({
type: 'json-value';
content: TestServerJsonBodyType;
} | {
type: 'stream-values';
content: Array<string>;
} | {
type: 'controlled-stream';
id?: string;
} | {
type: 'error';
status: number;
content?: string;
});
declare class TestServerCall$1 {
private request;
constructor(request: Request);
getRequestBodyJson(): Promise<any>;
getRequestCredentials(): RequestCredentials;
getRequestHeaders(): Record<string, string>;
getRequestUrlSearchParams(): URLSearchParams;
}
declare function withTestServer(responses: Array<TestServerResponse> | TestServerResponse, testFunction: (options: {
calls: () => Array<TestServerCall$1>;
call: (index: number) => TestServerCall$1;
getStreamController: (id: string) => ReadableStreamDefaultController<string>;
streamController: ReadableStreamDefaultController<string>;
}) => Promise<void>): () => Promise<void>;
declare function describeWithTestServer(description: string, responses: Array<TestServerResponse> | TestServerResponse, testFunction: (options: {
calls: () => Array<TestServerCall$1>;
call: (index: number) => TestServerCall$1;
getStreamController: (id: string) => ReadableStreamDefaultController<string>;
streamController: ReadableStreamDefaultController<string>;
}) => void): void;
type UrlResponse = {
type: 'json-value';
headers?: Record<string, string>;
body: JsonBodyType;
} | {
type: 'stream-chunks';
headers?: Record<string, string>;
chunks: Array<string>;
} | {
type: 'binary';
headers?: Record<string, string>;
body: Buffer;
} | {
type: 'empty';
headers?: Record<string, string>;
status?: number;
} | {
type: 'error';
headers?: Record<string, string>;
status?: number;
body?: string;
} | {
type: 'controlled-stream';
headers?: Record<string, string>;
controller: TestResponseController;
} | undefined;
type UrlResponseParameter = UrlResponse | UrlResponse[] | ((options: {
callNumber: number;
}) => UrlResponse);
type UrlHandler = {
response: UrlResponseParameter;
};
type UrlHandlers<URLS extends {
[url: string]: {
response?: UrlResponseParameter;
};
}> = {
[url in keyof URLS]: UrlHandler;
};
declare class TestServerCall {
private request;
constructor(request: Request);
get requestBody(): Promise<any>;
get requestBodyMultipart(): Promise<Record<string, any>> | null;
get requestCredentials(): RequestCredentials;
get requestHeaders(): Record<string, string>;
get requestUrlSearchParams(): URLSearchParams;
get requestUrl(): string;
get requestMethod(): string;
}
declare function createTestServer<URLS extends {
[url: string]: {
response?: UrlResponseParameter;
};
}>(routes: URLS): {
urls: UrlHandlers<URLS>;
calls: TestServerCall[];
};
declare class TestResponseController {
private readonly transformStream;
private readonly writer;
constructor();
get stream(): ReadableStream;
write(chunk: string): Promise<void>;
error(error: Error): Promise<void>;
close(): Promise<void>;
}
export { JsonTestServer, StreamingTestServer, TestResponseController, type TestServerJsonBodyType, type TestServerResponse, type UrlHandler, type UrlHandlers, type UrlResponse, convertArrayToAsyncIterable, convertArrayToReadableStream, convertAsyncIterableToArray, convertReadableStreamToArray, convertResponseStreamToArray, createTestServer, describeWithTestServer, mockId, withTestServer };

View File

@@ -0,0 +1,162 @@
import { SetupServer } from 'msw/node';
import { JsonBodyType } from 'msw';
declare function convertArrayToAsyncIterable<T>(values: T[]): AsyncIterable<T>;
declare function convertArrayToReadableStream<T>(values: T[]): ReadableStream<T>;
declare function convertAsyncIterableToArray<T>(iterable: AsyncIterable<T>): Promise<T[]>;
declare function convertReadableStreamToArray<T>(stream: ReadableStream<T>): Promise<T[]>;
declare function convertResponseStreamToArray(response: Response): Promise<string[]>;
/**
* @deprecated Use createTestServer instead
*/
declare class JsonTestServer {
readonly server: SetupServer;
responseHeaders: Record<string, string>;
responseBodyJson: any;
request: Request | undefined;
/**
* @deprecated Use createTestServer instead
*/
constructor(url: string);
getRequestBodyJson(): Promise<any>;
getRequestHeaders(): Promise<Record<string, string>>;
getRequestUrlSearchParams(): Promise<URLSearchParams>;
getRequestUrl(): Promise<string>;
setupTestEnvironment(): void;
}
declare function mockId({ prefix, }?: {
prefix?: string;
}): () => string;
/**
* @deprecated Use createTestServer instead
*/
declare class StreamingTestServer {
readonly server: SetupServer;
responseHeaders: Record<string, string>;
responseChunks: any[];
request: Request | undefined;
/**
* @deprecated Use createTestServer instead
*/
constructor(url: string);
getRequestBodyJson(): Promise<any>;
getRequestHeaders(): Promise<Record<string, string>>;
getRequestUrlSearchParams(): Promise<URLSearchParams>;
setupTestEnvironment(): void;
}
type TestServerJsonBodyType = JsonBodyType;
type TestServerResponse = {
url: string;
headers?: Record<string, string>;
} & ({
type: 'json-value';
content: TestServerJsonBodyType;
} | {
type: 'stream-values';
content: Array<string>;
} | {
type: 'controlled-stream';
id?: string;
} | {
type: 'error';
status: number;
content?: string;
});
declare class TestServerCall$1 {
private request;
constructor(request: Request);
getRequestBodyJson(): Promise<any>;
getRequestCredentials(): RequestCredentials;
getRequestHeaders(): Record<string, string>;
getRequestUrlSearchParams(): URLSearchParams;
}
declare function withTestServer(responses: Array<TestServerResponse> | TestServerResponse, testFunction: (options: {
calls: () => Array<TestServerCall$1>;
call: (index: number) => TestServerCall$1;
getStreamController: (id: string) => ReadableStreamDefaultController<string>;
streamController: ReadableStreamDefaultController<string>;
}) => Promise<void>): () => Promise<void>;
declare function describeWithTestServer(description: string, responses: Array<TestServerResponse> | TestServerResponse, testFunction: (options: {
calls: () => Array<TestServerCall$1>;
call: (index: number) => TestServerCall$1;
getStreamController: (id: string) => ReadableStreamDefaultController<string>;
streamController: ReadableStreamDefaultController<string>;
}) => void): void;
type UrlResponse = {
type: 'json-value';
headers?: Record<string, string>;
body: JsonBodyType;
} | {
type: 'stream-chunks';
headers?: Record<string, string>;
chunks: Array<string>;
} | {
type: 'binary';
headers?: Record<string, string>;
body: Buffer;
} | {
type: 'empty';
headers?: Record<string, string>;
status?: number;
} | {
type: 'error';
headers?: Record<string, string>;
status?: number;
body?: string;
} | {
type: 'controlled-stream';
headers?: Record<string, string>;
controller: TestResponseController;
} | undefined;
type UrlResponseParameter = UrlResponse | UrlResponse[] | ((options: {
callNumber: number;
}) => UrlResponse);
type UrlHandler = {
response: UrlResponseParameter;
};
type UrlHandlers<URLS extends {
[url: string]: {
response?: UrlResponseParameter;
};
}> = {
[url in keyof URLS]: UrlHandler;
};
declare class TestServerCall {
private request;
constructor(request: Request);
get requestBody(): Promise<any>;
get requestBodyMultipart(): Promise<Record<string, any>> | null;
get requestCredentials(): RequestCredentials;
get requestHeaders(): Record<string, string>;
get requestUrlSearchParams(): URLSearchParams;
get requestUrl(): string;
get requestMethod(): string;
}
declare function createTestServer<URLS extends {
[url: string]: {
response?: UrlResponseParameter;
};
}>(routes: URLS): {
urls: UrlHandlers<URLS>;
calls: TestServerCall[];
};
declare class TestResponseController {
private readonly transformStream;
private readonly writer;
constructor();
get stream(): ReadableStream;
write(chunk: string): Promise<void>;
error(error: Error): Promise<void>;
close(): Promise<void>;
}
export { JsonTestServer, StreamingTestServer, TestResponseController, type TestServerJsonBodyType, type TestServerResponse, type UrlHandler, type UrlHandlers, type UrlResponse, convertArrayToAsyncIterable, convertArrayToReadableStream, convertAsyncIterableToArray, convertReadableStreamToArray, convertResponseStreamToArray, createTestServer, describeWithTestServer, mockId, withTestServer };

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,13 @@
Copyright 2023 Vercel, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,7 @@
# AI SDK: React provider
[React](https://react.dev/) UI components for the [AI SDK](https://ai-sdk.dev/docs):
- [`useChat`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-chat) hook
- [`useCompletion`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-completion) hook
- [`useAssistant`](https://ai-sdk.dev/docs/reference/ai-sdk-ui/use-assistant) hook

View File

@@ -0,0 +1,301 @@
import { Message, CreateMessage, AssistantStatus, UseAssistantOptions, UIMessage, ChatRequestOptions, JSONValue, UseChatOptions, RequestOptions, UseCompletionOptions, Schema, DeepPartial } from '@ai-sdk/ui-utils';
export { CreateMessage, Message, UseChatOptions, UseCompletionOptions } from '@ai-sdk/ui-utils';
import { FetchFunction } from '@ai-sdk/provider-utils';
import z from 'zod';
type UseAssistantHelpers = {
/**
* The current array of chat messages.
*/
messages: Message[];
/**
* Update the message store with a new array of messages.
*/
setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
/**
* The current thread ID.
*/
threadId: string | undefined;
/**
* Set the current thread ID. Specifying a thread ID will switch to that thread, if it exists. If set to 'undefined', a new thread will be created. For both cases, `threadId` will be updated with the new value and `messages` will be cleared.
*/
setThreadId: (threadId: string | undefined) => void;
/**
* The current value of the input field.
*/
input: string;
/**
* Append a user message to the chat list. This triggers the API call to fetch
* the assistant's response.
* @param message The message to append
* @param requestOptions Additional options to pass to the API call
*/
append: (message: Message | CreateMessage, requestOptions?: {
data?: Record<string, string>;
}) => Promise<void>;
/**
Abort the current request immediately, keep the generated tokens if any.
*/
stop: () => void;
/**
* setState-powered method to update the input value.
*/
setInput: React.Dispatch<React.SetStateAction<string>>;
/**
* Handler for the `onChange` event of the input field to control the input's value.
*/
handleInputChange: (event: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>) => void;
/**
* Form submission handler that automatically resets the input field and appends a user message.
*/
submitMessage: (event?: React.FormEvent<HTMLFormElement>, requestOptions?: {
data?: Record<string, string>;
}) => Promise<void>;
/**
* The current status of the assistant. This can be used to show a loading indicator.
*/
status: AssistantStatus;
/**
* The error thrown during the assistant message processing, if any.
*/
error: undefined | Error;
};
declare function useAssistant({ api, threadId: threadIdParam, credentials, headers, body, onError, fetch, }: UseAssistantOptions): UseAssistantHelpers;
type UseChatHelpers = {
/** Current messages in the chat */
messages: UIMessage[];
/** The error object of the API request */
error: undefined | Error;
/**
* Append a user message to the chat list. This triggers the API call to fetch
* the assistant's response.
* @param message The message to append
* @param options Additional options to pass to the API call
*/
append: (message: Message | CreateMessage, chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
/**
* Reload the last AI chat response for the given chat history. If the last
* message isn't from the assistant, it will request the API to generate a
* new response.
*/
reload: (chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
/**
* Abort the current request immediately, keep the generated tokens if any.
*/
stop: () => void;
/**
* Resume an ongoing chat generation stream. This does not resume an aborted generation.
*/
experimental_resume: () => void;
/**
* Update the `messages` state locally. This is useful when you want to
* edit the messages on the client, and then trigger the `reload` method
* manually to regenerate the AI response.
*/
setMessages: (messages: Message[] | ((messages: Message[]) => Message[])) => void;
/** The current value of the input */
input: string;
/** setState-powered method to update the input value */
setInput: React.Dispatch<React.SetStateAction<string>>;
/** An input/textarea-ready onChange handler to control the value of the input */
handleInputChange: (e: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>) => void;
/** Form submission handler to automatically reset input and append a user message */
handleSubmit: (event?: {
preventDefault?: () => void;
}, chatRequestOptions?: ChatRequestOptions) => void;
metadata?: Object;
/**
* Whether the API request is in progress
*
* @deprecated use `status` instead
*/
isLoading: boolean;
/**
* Hook status:
*
* - `submitted`: The message has been sent to the API and we're awaiting the start of the response stream.
* - `streaming`: The response is actively streaming in from the API, receiving chunks of data.
* - `ready`: The full response has been received and processed; a new user message can be submitted.
* - `error`: An error occurred during the API request, preventing successful completion.
*/
status: 'submitted' | 'streaming' | 'ready' | 'error';
/** Additional data added on the server via StreamData. */
data?: JSONValue[];
/** Set the data of the chat. You can use this to transform or clear the chat data. */
setData: (data: JSONValue[] | undefined | ((data: JSONValue[] | undefined) => JSONValue[] | undefined)) => void;
/** The id of the chat */
id: string;
};
declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, onToolCall, experimental_prepareRequestBody, maxSteps, streamProtocol, onResponse, onFinish, onError, credentials, headers, body, generateId, fetch, keepLastMessageOnError, experimental_throttle: throttleWaitMs, }?: UseChatOptions & {
key?: string;
/**
* Experimental (React only). When a function is provided, it will be used
* to prepare the request body for the chat API. This can be useful for
* customizing the request body based on the messages and data in the chat.
*
* @param messages The current messages in the chat.
* @param requestData The data object passed in the chat request.
* @param requestBody The request body object passed in the chat request.
*/
experimental_prepareRequestBody?: (options: {
id: string;
messages: UIMessage[];
requestData?: JSONValue;
requestBody?: object;
}) => unknown;
/**
Custom throttle wait in ms for the chat messages and data updates.
Default is undefined, which disables throttling.
*/
experimental_throttle?: number;
/**
Maximum number of sequential LLM calls (steps), e.g. when you use tool calls.
Must be at least 1.
A maximum number is required to prevent infinite loops in the case of misconfigured tools.
By default, it's set to 1, which means that only a single LLM call is made.
*/
maxSteps?: number;
}): UseChatHelpers & {
addToolResult: ({ toolCallId, result, }: {
toolCallId: string;
result: any;
}) => void;
};
type UseCompletionHelpers = {
/** The current completion result */
completion: string;
/**
* Send a new prompt to the API endpoint and update the completion state.
*/
complete: (prompt: string, options?: RequestOptions) => Promise<string | null | undefined>;
/** The error object of the API request */
error: undefined | Error;
/**
* Abort the current API request but keep the generated tokens.
*/
stop: () => void;
/**
* Update the `completion` state locally.
*/
setCompletion: (completion: string) => void;
/** The current value of the input */
input: string;
/** setState-powered method to update the input value */
setInput: React.Dispatch<React.SetStateAction<string>>;
/**
* An input/textarea-ready onChange handler to control the value of the input
* @example
* ```jsx
* <input onChange={handleInputChange} value={input} />
* ```
*/
handleInputChange: (event: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>) => void;
/**
* Form submission handler to automatically reset input and append a user message
* @example
* ```jsx
* <form onSubmit={handleSubmit}>
* <input onChange={handleInputChange} value={input} />
* </form>
* ```
*/
handleSubmit: (event?: {
preventDefault?: () => void;
}) => void;
/** Whether the API request is in progress */
isLoading: boolean;
/** Additional data added on the server via StreamData */
data?: JSONValue[];
};
declare function useCompletion({ api, id, initialCompletion, initialInput, credentials, headers, body, streamProtocol, fetch, onResponse, onFinish, onError, experimental_throttle: throttleWaitMs, }?: UseCompletionOptions & {
/**
* Custom throttle wait in ms for the completion and data updates.
* Default is undefined, which disables throttling.
*/
experimental_throttle?: number;
}): UseCompletionHelpers;
type Experimental_UseObjectOptions<RESULT> = {
/**
* The API endpoint. It should stream JSON that matches the schema as chunked text.
*/
api: string;
/**
* A Zod schema that defines the shape of the complete object.
*/
schema: z.Schema<RESULT, z.ZodTypeDef, any> | Schema<RESULT>;
/**
* An unique identifier. If not provided, a random one will be
* generated. When provided, the `useObject` hook with the same `id` will
* have shared states across components.
*/
id?: string;
/**
* An optional value for the initial object.
*/
initialValue?: DeepPartial<RESULT>;
/**
Custom fetch implementation. You can use it as a middleware to intercept requests,
or to provide a custom fetch implementation for e.g. testing.
*/
fetch?: FetchFunction;
/**
Callback that is called when the stream has finished.
*/
onFinish?: (event: {
/**
The generated object (typed according to the schema).
Can be undefined if the final object does not match the schema.
*/
object: RESULT | undefined;
/**
Optional error object. This is e.g. a TypeValidationError when the final object does not match the schema.
*/
error: Error | undefined;
}) => Promise<void> | void;
/**
* Callback function to be called when an error is encountered.
*/
onError?: (error: Error) => void;
/**
* Additional HTTP headers to be included in the request.
*/
headers?: Record<string, string> | Headers;
/**
* The credentials mode to be used for the fetch request.
* Possible values are: 'omit', 'same-origin', 'include'.
* Defaults to 'same-origin'.
*/
credentials?: RequestCredentials;
};
type Experimental_UseObjectHelpers<RESULT, INPUT> = {
/**
* Calls the API with the provided input as JSON body.
*/
submit: (input: INPUT) => void;
/**
* The current value for the generated object. Updated as the API streams JSON chunks.
*/
object: DeepPartial<RESULT> | undefined;
/**
* The error object of the API request if any.
*/
error: Error | undefined;
/**
* Flag that indicates whether an API request is in progress.
*/
isLoading: boolean;
/**
* Abort the current request immediately, keep the current partial object if any.
*/
stop: () => void;
};
declare function useObject<RESULT, INPUT = any>({ api, id, schema, // required, in the future we will use it for validation
initialValue, fetch, onError, onFinish, headers, credentials, }: Experimental_UseObjectOptions<RESULT>): Experimental_UseObjectHelpers<RESULT, INPUT>;
declare const experimental_useObject: typeof useObject;
export { Experimental_UseObjectHelpers, Experimental_UseObjectOptions, UseAssistantHelpers, UseChatHelpers, UseCompletionHelpers, experimental_useObject, useAssistant, useChat, useCompletion };

View File

@@ -0,0 +1,301 @@
import { Message, CreateMessage, AssistantStatus, UseAssistantOptions, UIMessage, ChatRequestOptions, JSONValue, UseChatOptions, RequestOptions, UseCompletionOptions, Schema, DeepPartial } from '@ai-sdk/ui-utils';
export { CreateMessage, Message, UseChatOptions, UseCompletionOptions } from '@ai-sdk/ui-utils';
import { FetchFunction } from '@ai-sdk/provider-utils';
import z from 'zod';
type UseAssistantHelpers = {
/**
* The current array of chat messages.
*/
messages: Message[];
/**
* Update the message store with a new array of messages.
*/
setMessages: React.Dispatch<React.SetStateAction<Message[]>>;
/**
* The current thread ID.
*/
threadId: string | undefined;
/**
* Set the current thread ID. Specifying a thread ID will switch to that thread, if it exists. If set to 'undefined', a new thread will be created. For both cases, `threadId` will be updated with the new value and `messages` will be cleared.
*/
setThreadId: (threadId: string | undefined) => void;
/**
* The current value of the input field.
*/
input: string;
/**
* Append a user message to the chat list. This triggers the API call to fetch
* the assistant's response.
* @param message The message to append
* @param requestOptions Additional options to pass to the API call
*/
append: (message: Message | CreateMessage, requestOptions?: {
data?: Record<string, string>;
}) => Promise<void>;
/**
Abort the current request immediately, keep the generated tokens if any.
*/
stop: () => void;
/**
* setState-powered method to update the input value.
*/
setInput: React.Dispatch<React.SetStateAction<string>>;
/**
* Handler for the `onChange` event of the input field to control the input's value.
*/
handleInputChange: (event: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>) => void;
/**
* Form submission handler that automatically resets the input field and appends a user message.
*/
submitMessage: (event?: React.FormEvent<HTMLFormElement>, requestOptions?: {
data?: Record<string, string>;
}) => Promise<void>;
/**
* The current status of the assistant. This can be used to show a loading indicator.
*/
status: AssistantStatus;
/**
* The error thrown during the assistant message processing, if any.
*/
error: undefined | Error;
};
declare function useAssistant({ api, threadId: threadIdParam, credentials, headers, body, onError, fetch, }: UseAssistantOptions): UseAssistantHelpers;
type UseChatHelpers = {
/** Current messages in the chat */
messages: UIMessage[];
/** The error object of the API request */
error: undefined | Error;
/**
* Append a user message to the chat list. This triggers the API call to fetch
* the assistant's response.
* @param message The message to append
* @param options Additional options to pass to the API call
*/
append: (message: Message | CreateMessage, chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
/**
* Reload the last AI chat response for the given chat history. If the last
* message isn't from the assistant, it will request the API to generate a
* new response.
*/
reload: (chatRequestOptions?: ChatRequestOptions) => Promise<string | null | undefined>;
/**
* Abort the current request immediately, keep the generated tokens if any.
*/
stop: () => void;
/**
* Resume an ongoing chat generation stream. This does not resume an aborted generation.
*/
experimental_resume: () => void;
/**
* Update the `messages` state locally. This is useful when you want to
* edit the messages on the client, and then trigger the `reload` method
* manually to regenerate the AI response.
*/
setMessages: (messages: Message[] | ((messages: Message[]) => Message[])) => void;
/** The current value of the input */
input: string;
/** setState-powered method to update the input value */
setInput: React.Dispatch<React.SetStateAction<string>>;
/** An input/textarea-ready onChange handler to control the value of the input */
handleInputChange: (e: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>) => void;
/** Form submission handler to automatically reset input and append a user message */
handleSubmit: (event?: {
preventDefault?: () => void;
}, chatRequestOptions?: ChatRequestOptions) => void;
metadata?: Object;
/**
* Whether the API request is in progress
*
* @deprecated use `status` instead
*/
isLoading: boolean;
/**
* Hook status:
*
* - `submitted`: The message has been sent to the API and we're awaiting the start of the response stream.
* - `streaming`: The response is actively streaming in from the API, receiving chunks of data.
* - `ready`: The full response has been received and processed; a new user message can be submitted.
* - `error`: An error occurred during the API request, preventing successful completion.
*/
status: 'submitted' | 'streaming' | 'ready' | 'error';
/** Additional data added on the server via StreamData. */
data?: JSONValue[];
/** Set the data of the chat. You can use this to transform or clear the chat data. */
setData: (data: JSONValue[] | undefined | ((data: JSONValue[] | undefined) => JSONValue[] | undefined)) => void;
/** The id of the chat */
id: string;
};
declare function useChat({ api, id, initialMessages, initialInput, sendExtraMessageFields, onToolCall, experimental_prepareRequestBody, maxSteps, streamProtocol, onResponse, onFinish, onError, credentials, headers, body, generateId, fetch, keepLastMessageOnError, experimental_throttle: throttleWaitMs, }?: UseChatOptions & {
key?: string;
/**
* Experimental (React only). When a function is provided, it will be used
* to prepare the request body for the chat API. This can be useful for
* customizing the request body based on the messages and data in the chat.
*
* @param messages The current messages in the chat.
* @param requestData The data object passed in the chat request.
* @param requestBody The request body object passed in the chat request.
*/
experimental_prepareRequestBody?: (options: {
id: string;
messages: UIMessage[];
requestData?: JSONValue;
requestBody?: object;
}) => unknown;
/**
Custom throttle wait in ms for the chat messages and data updates.
Default is undefined, which disables throttling.
*/
experimental_throttle?: number;
/**
Maximum number of sequential LLM calls (steps), e.g. when you use tool calls.
Must be at least 1.
A maximum number is required to prevent infinite loops in the case of misconfigured tools.
By default, it's set to 1, which means that only a single LLM call is made.
*/
maxSteps?: number;
}): UseChatHelpers & {
addToolResult: ({ toolCallId, result, }: {
toolCallId: string;
result: any;
}) => void;
};
type UseCompletionHelpers = {
/** The current completion result */
completion: string;
/**
* Send a new prompt to the API endpoint and update the completion state.
*/
complete: (prompt: string, options?: RequestOptions) => Promise<string | null | undefined>;
/** The error object of the API request */
error: undefined | Error;
/**
* Abort the current API request but keep the generated tokens.
*/
stop: () => void;
/**
* Update the `completion` state locally.
*/
setCompletion: (completion: string) => void;
/** The current value of the input */
input: string;
/** setState-powered method to update the input value */
setInput: React.Dispatch<React.SetStateAction<string>>;
/**
* An input/textarea-ready onChange handler to control the value of the input
* @example
* ```jsx
* <input onChange={handleInputChange} value={input} />
* ```
*/
handleInputChange: (event: React.ChangeEvent<HTMLInputElement> | React.ChangeEvent<HTMLTextAreaElement>) => void;
/**
* Form submission handler to automatically reset input and append a user message
* @example
* ```jsx
* <form onSubmit={handleSubmit}>
* <input onChange={handleInputChange} value={input} />
* </form>
* ```
*/
handleSubmit: (event?: {
preventDefault?: () => void;
}) => void;
/** Whether the API request is in progress */
isLoading: boolean;
/** Additional data added on the server via StreamData */
data?: JSONValue[];
};
declare function useCompletion({ api, id, initialCompletion, initialInput, credentials, headers, body, streamProtocol, fetch, onResponse, onFinish, onError, experimental_throttle: throttleWaitMs, }?: UseCompletionOptions & {
/**
* Custom throttle wait in ms for the completion and data updates.
* Default is undefined, which disables throttling.
*/
experimental_throttle?: number;
}): UseCompletionHelpers;
type Experimental_UseObjectOptions<RESULT> = {
/**
* The API endpoint. It should stream JSON that matches the schema as chunked text.
*/
api: string;
/**
* A Zod schema that defines the shape of the complete object.
*/
schema: z.Schema<RESULT, z.ZodTypeDef, any> | Schema<RESULT>;
/**
* An unique identifier. If not provided, a random one will be
* generated. When provided, the `useObject` hook with the same `id` will
* have shared states across components.
*/
id?: string;
/**
* An optional value for the initial object.
*/
initialValue?: DeepPartial<RESULT>;
/**
Custom fetch implementation. You can use it as a middleware to intercept requests,
or to provide a custom fetch implementation for e.g. testing.
*/
fetch?: FetchFunction;
/**
Callback that is called when the stream has finished.
*/
onFinish?: (event: {
/**
The generated object (typed according to the schema).
Can be undefined if the final object does not match the schema.
*/
object: RESULT | undefined;
/**
Optional error object. This is e.g. a TypeValidationError when the final object does not match the schema.
*/
error: Error | undefined;
}) => Promise<void> | void;
/**
* Callback function to be called when an error is encountered.
*/
onError?: (error: Error) => void;
/**
* Additional HTTP headers to be included in the request.
*/
headers?: Record<string, string> | Headers;
/**
* The credentials mode to be used for the fetch request.
* Possible values are: 'omit', 'same-origin', 'include'.
* Defaults to 'same-origin'.
*/
credentials?: RequestCredentials;
};
type Experimental_UseObjectHelpers<RESULT, INPUT> = {
/**
* Calls the API with the provided input as JSON body.
*/
submit: (input: INPUT) => void;
/**
* The current value for the generated object. Updated as the API streams JSON chunks.
*/
object: DeepPartial<RESULT> | undefined;
/**
* The error object of the API request if any.
*/
error: Error | undefined;
/**
* Flag that indicates whether an API request is in progress.
*/
isLoading: boolean;
/**
* Abort the current request immediately, keep the current partial object if any.
*/
stop: () => void;
};
declare function useObject<RESULT, INPUT = any>({ api, id, schema, // required, in the future we will use it for validation
initialValue, fetch, onError, onFinish, headers, credentials, }: Experimental_UseObjectOptions<RESULT>): Experimental_UseObjectHelpers<RESULT, INPUT>;
declare const experimental_useObject: typeof useObject;
export { Experimental_UseObjectHelpers, Experimental_UseObjectOptions, UseAssistantHelpers, UseChatHelpers, UseCompletionHelpers, experimental_useObject, useAssistant, useChat, useCompletion };

View File

@@ -0,0 +1,841 @@
"use strict";
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/index.ts
var src_exports = {};
__export(src_exports, {
experimental_useObject: () => experimental_useObject,
useAssistant: () => useAssistant,
useChat: () => useChat,
useCompletion: () => useCompletion
});
module.exports = __toCommonJS(src_exports);
// src/use-assistant.ts
var import_provider_utils = require("@ai-sdk/provider-utils");
var import_ui_utils = require("@ai-sdk/ui-utils");
var import_react = require("react");
var getOriginalFetch = () => fetch;
function useAssistant({
api,
threadId: threadIdParam,
credentials,
headers,
body,
onError,
fetch: fetch2
}) {
const [messages, setMessages] = (0, import_react.useState)([]);
const [input, setInput] = (0, import_react.useState)("");
const [currentThreadId, setCurrentThreadId] = (0, import_react.useState)(
void 0
);
const [status, setStatus] = (0, import_react.useState)("awaiting_message");
const [error, setError] = (0, import_react.useState)(void 0);
const handleInputChange = (event) => {
setInput(event.target.value);
};
const abortControllerRef = (0, import_react.useRef)(null);
const stop = (0, import_react.useCallback)(() => {
if (abortControllerRef.current) {
abortControllerRef.current.abort();
abortControllerRef.current = null;
}
}, []);
const append = async (message, requestOptions) => {
var _a, _b;
setStatus("in_progress");
setMessages((messages2) => {
var _a2;
return [
...messages2,
{
...message,
id: (_a2 = message.id) != null ? _a2 : (0, import_ui_utils.generateId)()
}
];
});
setInput("");
const abortController = new AbortController();
try {
abortControllerRef.current = abortController;
const actualFetch = fetch2 != null ? fetch2 : getOriginalFetch();
const response = await actualFetch(api, {
method: "POST",
credentials,
signal: abortController.signal,
headers: { "Content-Type": "application/json", ...headers },
body: JSON.stringify({
...body,
// always use user-provided threadId when available:
threadId: (_a = threadIdParam != null ? threadIdParam : currentThreadId) != null ? _a : null,
message: message.content,
// optional request data:
data: requestOptions == null ? void 0 : requestOptions.data
})
});
if (!response.ok) {
throw new Error(
(_b = await response.text()) != null ? _b : "Failed to fetch the assistant response."
);
}
if (response.body == null) {
throw new Error("The response body is empty.");
}
await (0, import_ui_utils.processAssistantStream)({
stream: response.body,
onAssistantMessagePart(value) {
setMessages((messages2) => [
...messages2,
{
id: value.id,
role: value.role,
content: value.content[0].text.value,
parts: []
}
]);
},
onTextPart(value) {
setMessages((messages2) => {
const lastMessage = messages2[messages2.length - 1];
return [
...messages2.slice(0, messages2.length - 1),
{
id: lastMessage.id,
role: lastMessage.role,
content: lastMessage.content + value,
parts: lastMessage.parts
}
];
});
},
onAssistantControlDataPart(value) {
setCurrentThreadId(value.threadId);
setMessages((messages2) => {
const lastMessage = messages2[messages2.length - 1];
lastMessage.id = value.messageId;
return [...messages2.slice(0, messages2.length - 1), lastMessage];
});
},
onDataMessagePart(value) {
setMessages((messages2) => {
var _a2;
return [
...messages2,
{
id: (_a2 = value.id) != null ? _a2 : (0, import_ui_utils.generateId)(),
role: "data",
content: "",
data: value.data,
parts: []
}
];
});
},
onErrorPart(value) {
setError(new Error(value));
}
});
} catch (error2) {
if ((0, import_provider_utils.isAbortError)(error2) && abortController.signal.aborted) {
abortControllerRef.current = null;
return;
}
if (onError && error2 instanceof Error) {
onError(error2);
}
setError(error2);
} finally {
abortControllerRef.current = null;
setStatus("awaiting_message");
}
};
const submitMessage = async (event, requestOptions) => {
var _a;
(_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
if (input === "") {
return;
}
append({ role: "user", content: input, parts: [] }, requestOptions);
};
const setThreadId = (threadId) => {
setCurrentThreadId(threadId);
setMessages([]);
};
return {
append,
messages,
setMessages,
threadId: currentThreadId,
setThreadId,
input,
setInput,
handleInputChange,
submitMessage,
status,
error,
stop
};
}
// src/use-chat.ts
var import_ui_utils3 = require("@ai-sdk/ui-utils");
var import_react3 = require("react");
var import_swr = __toESM(require("swr"));
// src/throttle.ts
var import_throttleit = __toESM(require("throttleit"));
function throttle(fn, waitMs) {
return waitMs != null ? (0, import_throttleit.default)(fn, waitMs) : fn;
}
// src/util/use-stable-value.ts
var import_ui_utils2 = require("@ai-sdk/ui-utils");
var import_react2 = require("react");
function useStableValue(latestValue) {
const [value, setValue] = (0, import_react2.useState)(latestValue);
(0, import_react2.useEffect)(() => {
if (!(0, import_ui_utils2.isDeepEqualData)(latestValue, value)) {
setValue(latestValue);
}
}, [latestValue, value]);
return value;
}
// src/use-chat.ts
function useChat({
api = "/api/chat",
id,
initialMessages,
initialInput = "",
sendExtraMessageFields,
onToolCall,
experimental_prepareRequestBody,
maxSteps = 1,
streamProtocol = "data",
onResponse,
onFinish,
onError,
credentials,
headers,
body,
generateId: generateId2 = import_ui_utils3.generateId,
fetch: fetch2,
keepLastMessageOnError = true,
experimental_throttle: throttleWaitMs
} = {}) {
const [hookId] = (0, import_react3.useState)(generateId2);
const chatId = id != null ? id : hookId;
const chatKey = typeof api === "string" ? [api, chatId] : chatId;
const stableInitialMessages = useStableValue(initialMessages != null ? initialMessages : []);
const processedInitialMessages = (0, import_react3.useMemo)(
() => (0, import_ui_utils3.fillMessageParts)(stableInitialMessages),
[stableInitialMessages]
);
const { data: messages, mutate } = (0, import_swr.default)(
[chatKey, "messages"],
null,
{ fallbackData: processedInitialMessages }
);
const messagesRef = (0, import_react3.useRef)(messages || []);
(0, import_react3.useEffect)(() => {
messagesRef.current = messages || [];
}, [messages]);
const { data: streamData, mutate: mutateStreamData } = (0, import_swr.default)([chatKey, "streamData"], null);
const streamDataRef = (0, import_react3.useRef)(streamData);
(0, import_react3.useEffect)(() => {
streamDataRef.current = streamData;
}, [streamData]);
const { data: status = "ready", mutate: mutateStatus } = (0, import_swr.default)([chatKey, "status"], null);
const { data: error = void 0, mutate: setError } = (0, import_swr.default)([chatKey, "error"], null);
const abortControllerRef = (0, import_react3.useRef)(null);
const extraMetadataRef = (0, import_react3.useRef)({
credentials,
headers,
body
});
(0, import_react3.useEffect)(() => {
extraMetadataRef.current = {
credentials,
headers,
body
};
}, [credentials, headers, body]);
const triggerRequest = (0, import_react3.useCallback)(
async (chatRequest, requestType = "generate") => {
var _a, _b;
mutateStatus("submitted");
setError(void 0);
const chatMessages = (0, import_ui_utils3.fillMessageParts)(chatRequest.messages);
const messageCount = chatMessages.length;
const maxStep = (0, import_ui_utils3.extractMaxToolInvocationStep)(
(_a = chatMessages[chatMessages.length - 1]) == null ? void 0 : _a.toolInvocations
);
try {
const abortController = new AbortController();
abortControllerRef.current = abortController;
const throttledMutate = throttle(mutate, throttleWaitMs);
const throttledMutateStreamData = throttle(
mutateStreamData,
throttleWaitMs
);
const previousMessages = messagesRef.current;
throttledMutate(chatMessages, false);
const constructedMessagesPayload = sendExtraMessageFields ? chatMessages : chatMessages.map(
({
role,
content,
experimental_attachments,
data,
annotations,
toolInvocations,
parts
}) => ({
role,
content,
...experimental_attachments !== void 0 && {
experimental_attachments
},
...data !== void 0 && { data },
...annotations !== void 0 && { annotations },
...toolInvocations !== void 0 && { toolInvocations },
...parts !== void 0 && { parts }
})
);
const existingData = streamDataRef.current;
await (0, import_ui_utils3.callChatApi)({
api,
body: (_b = experimental_prepareRequestBody == null ? void 0 : experimental_prepareRequestBody({
id: chatId,
messages: chatMessages,
requestData: chatRequest.data,
requestBody: chatRequest.body
})) != null ? _b : {
id: chatId,
messages: constructedMessagesPayload,
data: chatRequest.data,
...extraMetadataRef.current.body,
...chatRequest.body
},
streamProtocol,
credentials: extraMetadataRef.current.credentials,
headers: {
...extraMetadataRef.current.headers,
...chatRequest.headers
},
abortController: () => abortControllerRef.current,
restoreMessagesOnFailure() {
if (!keepLastMessageOnError) {
throttledMutate(previousMessages, false);
}
},
onResponse,
onUpdate({ message, data, replaceLastMessage }) {
mutateStatus("streaming");
throttledMutate(
[
...replaceLastMessage ? chatMessages.slice(0, chatMessages.length - 1) : chatMessages,
message
],
false
);
if (data == null ? void 0 : data.length) {
throttledMutateStreamData(
[...existingData != null ? existingData : [], ...data],
false
);
}
},
onToolCall,
onFinish,
generateId: generateId2,
fetch: fetch2,
lastMessage: chatMessages[chatMessages.length - 1],
requestType
});
abortControllerRef.current = null;
mutateStatus("ready");
} catch (err) {
if (err.name === "AbortError") {
abortControllerRef.current = null;
mutateStatus("ready");
return null;
}
if (onError && err instanceof Error) {
onError(err);
}
setError(err);
mutateStatus("error");
}
const messages2 = messagesRef.current;
if ((0, import_ui_utils3.shouldResubmitMessages)({
originalMaxToolInvocationStep: maxStep,
originalMessageCount: messageCount,
maxSteps,
messages: messages2
})) {
await triggerRequest({ messages: messages2 });
}
},
[
mutate,
mutateStatus,
api,
extraMetadataRef,
onResponse,
onFinish,
onError,
setError,
mutateStreamData,
streamDataRef,
streamProtocol,
sendExtraMessageFields,
experimental_prepareRequestBody,
onToolCall,
maxSteps,
messagesRef,
abortControllerRef,
generateId2,
fetch2,
keepLastMessageOnError,
throttleWaitMs,
chatId
]
);
const append = (0, import_react3.useCallback)(
async (message, {
data,
headers: headers2,
body: body2,
experimental_attachments = message.experimental_attachments
} = {}) => {
var _a, _b;
const attachmentsForRequest = await (0, import_ui_utils3.prepareAttachmentsForRequest)(
experimental_attachments
);
const messages2 = messagesRef.current.concat({
...message,
id: (_a = message.id) != null ? _a : generateId2(),
createdAt: (_b = message.createdAt) != null ? _b : /* @__PURE__ */ new Date(),
experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : void 0,
parts: (0, import_ui_utils3.getMessageParts)(message)
});
return triggerRequest({ messages: messages2, headers: headers2, body: body2, data });
},
[triggerRequest, generateId2]
);
const reload = (0, import_react3.useCallback)(
async ({ data, headers: headers2, body: body2 } = {}) => {
const messages2 = messagesRef.current;
if (messages2.length === 0) {
return null;
}
const lastMessage = messages2[messages2.length - 1];
return triggerRequest({
messages: lastMessage.role === "assistant" ? messages2.slice(0, -1) : messages2,
headers: headers2,
body: body2,
data
});
},
[triggerRequest]
);
const stop = (0, import_react3.useCallback)(() => {
if (abortControllerRef.current) {
abortControllerRef.current.abort();
abortControllerRef.current = null;
}
}, []);
const experimental_resume = (0, import_react3.useCallback)(async () => {
const messages2 = messagesRef.current;
triggerRequest({ messages: messages2 }, "resume");
}, [triggerRequest]);
const setMessages = (0, import_react3.useCallback)(
(messages2) => {
if (typeof messages2 === "function") {
messages2 = messages2(messagesRef.current);
}
const messagesWithParts = (0, import_ui_utils3.fillMessageParts)(messages2);
mutate(messagesWithParts, false);
messagesRef.current = messagesWithParts;
},
[mutate]
);
const setData = (0, import_react3.useCallback)(
(data) => {
if (typeof data === "function") {
data = data(streamDataRef.current);
}
mutateStreamData(data, false);
streamDataRef.current = data;
},
[mutateStreamData]
);
const [input, setInput] = (0, import_react3.useState)(initialInput);
const handleSubmit = (0, import_react3.useCallback)(
async (event, options = {}, metadata) => {
var _a;
(_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
if (!input && !options.allowEmptySubmit)
return;
if (metadata) {
extraMetadataRef.current = {
...extraMetadataRef.current,
...metadata
};
}
const attachmentsForRequest = await (0, import_ui_utils3.prepareAttachmentsForRequest)(
options.experimental_attachments
);
const messages2 = messagesRef.current.concat({
id: generateId2(),
createdAt: /* @__PURE__ */ new Date(),
role: "user",
content: input,
experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : void 0,
parts: [{ type: "text", text: input }]
});
const chatRequest = {
messages: messages2,
headers: options.headers,
body: options.body,
data: options.data
};
triggerRequest(chatRequest);
setInput("");
},
[input, generateId2, triggerRequest]
);
const handleInputChange = (e) => {
setInput(e.target.value);
};
const addToolResult = (0, import_react3.useCallback)(
({ toolCallId, result }) => {
const currentMessages = messagesRef.current;
(0, import_ui_utils3.updateToolCallResult)({
messages: currentMessages,
toolCallId,
toolResult: result
});
mutate(
[
...currentMessages.slice(0, currentMessages.length - 1),
{ ...currentMessages[currentMessages.length - 1] }
],
false
);
if (status === "submitted" || status === "streaming") {
return;
}
const lastMessage = currentMessages[currentMessages.length - 1];
if ((0, import_ui_utils3.isAssistantMessageWithCompletedToolCalls)(lastMessage)) {
triggerRequest({ messages: currentMessages });
}
},
[mutate, status, triggerRequest]
);
return {
messages: messages != null ? messages : [],
id: chatId,
setMessages,
data: streamData,
setData,
error,
append,
reload,
stop,
experimental_resume,
input,
setInput,
handleInputChange,
handleSubmit,
isLoading: status === "submitted" || status === "streaming",
status,
addToolResult
};
}
// src/use-completion.ts
var import_ui_utils4 = require("@ai-sdk/ui-utils");
var import_react4 = require("react");
var import_swr2 = __toESM(require("swr"));
function useCompletion({
api = "/api/completion",
id,
initialCompletion = "",
initialInput = "",
credentials,
headers,
body,
streamProtocol = "data",
fetch: fetch2,
onResponse,
onFinish,
onError,
experimental_throttle: throttleWaitMs
} = {}) {
const hookId = (0, import_react4.useId)();
const completionId = id || hookId;
const { data, mutate } = (0, import_swr2.default)([api, completionId], null, {
fallbackData: initialCompletion
});
const { data: isLoading = false, mutate: mutateLoading } = (0, import_swr2.default)(
[completionId, "loading"],
null
);
const { data: streamData, mutate: mutateStreamData } = (0, import_swr2.default)([completionId, "streamData"], null);
const [error, setError] = (0, import_react4.useState)(void 0);
const completion = data;
const [abortController, setAbortController] = (0, import_react4.useState)(null);
const extraMetadataRef = (0, import_react4.useRef)({
credentials,
headers,
body
});
(0, import_react4.useEffect)(() => {
extraMetadataRef.current = {
credentials,
headers,
body
};
}, [credentials, headers, body]);
const triggerRequest = (0, import_react4.useCallback)(
async (prompt, options) => (0, import_ui_utils4.callCompletionApi)({
api,
prompt,
credentials: extraMetadataRef.current.credentials,
headers: { ...extraMetadataRef.current.headers, ...options == null ? void 0 : options.headers },
body: {
...extraMetadataRef.current.body,
...options == null ? void 0 : options.body
},
streamProtocol,
fetch: fetch2,
// throttle streamed ui updates:
setCompletion: throttle(
(completion2) => mutate(completion2, false),
throttleWaitMs
),
onData: throttle(
(data2) => mutateStreamData([...streamData != null ? streamData : [], ...data2 != null ? data2 : []], false),
throttleWaitMs
),
setLoading: mutateLoading,
setError,
setAbortController,
onResponse,
onFinish,
onError
}),
[
mutate,
mutateLoading,
api,
extraMetadataRef,
setAbortController,
onResponse,
onFinish,
onError,
setError,
streamData,
streamProtocol,
fetch2,
mutateStreamData,
throttleWaitMs
]
);
const stop = (0, import_react4.useCallback)(() => {
if (abortController) {
abortController.abort();
setAbortController(null);
}
}, [abortController]);
const setCompletion = (0, import_react4.useCallback)(
(completion2) => {
mutate(completion2, false);
},
[mutate]
);
const complete = (0, import_react4.useCallback)(
async (prompt, options) => {
return triggerRequest(prompt, options);
},
[triggerRequest]
);
const [input, setInput] = (0, import_react4.useState)(initialInput);
const handleSubmit = (0, import_react4.useCallback)(
(event) => {
var _a;
(_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
return input ? complete(input) : void 0;
},
[input, complete]
);
const handleInputChange = (0, import_react4.useCallback)(
(e) => {
setInput(e.target.value);
},
[setInput]
);
return {
completion,
complete,
error,
setCompletion,
stop,
input,
setInput,
handleInputChange,
handleSubmit,
isLoading,
data: streamData
};
}
// src/use-object.ts
var import_provider_utils2 = require("@ai-sdk/provider-utils");
var import_ui_utils5 = require("@ai-sdk/ui-utils");
var import_react5 = require("react");
var import_swr3 = __toESM(require("swr"));
var getOriginalFetch2 = () => fetch;
function useObject({
api,
id,
schema,
// required, in the future we will use it for validation
initialValue,
fetch: fetch2,
onError,
onFinish,
headers,
credentials
}) {
const hookId = (0, import_react5.useId)();
const completionId = id != null ? id : hookId;
const { data, mutate } = (0, import_swr3.default)(
[api, completionId],
null,
{ fallbackData: initialValue }
);
const [error, setError] = (0, import_react5.useState)(void 0);
const [isLoading, setIsLoading] = (0, import_react5.useState)(false);
const abortControllerRef = (0, import_react5.useRef)(null);
const stop = (0, import_react5.useCallback)(() => {
var _a;
try {
(_a = abortControllerRef.current) == null ? void 0 : _a.abort();
} catch (ignored) {
} finally {
setIsLoading(false);
abortControllerRef.current = null;
}
}, []);
const submit = async (input) => {
var _a;
try {
mutate(void 0);
setIsLoading(true);
setError(void 0);
const abortController = new AbortController();
abortControllerRef.current = abortController;
const actualFetch = fetch2 != null ? fetch2 : getOriginalFetch2();
const response = await actualFetch(api, {
method: "POST",
headers: {
"Content-Type": "application/json",
...headers
},
credentials,
signal: abortController.signal,
body: JSON.stringify(input)
});
if (!response.ok) {
throw new Error(
(_a = await response.text()) != null ? _a : "Failed to fetch the response."
);
}
if (response.body == null) {
throw new Error("The response body is empty.");
}
let accumulatedText = "";
let latestObject = void 0;
await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
new WritableStream({
write(chunk) {
accumulatedText += chunk;
const { value } = (0, import_ui_utils5.parsePartialJson)(accumulatedText);
const currentObject = value;
if (!(0, import_ui_utils5.isDeepEqualData)(latestObject, currentObject)) {
latestObject = currentObject;
mutate(currentObject);
}
},
close() {
setIsLoading(false);
abortControllerRef.current = null;
if (onFinish != null) {
const validationResult = (0, import_provider_utils2.safeValidateTypes)({
value: latestObject,
schema: (0, import_ui_utils5.asSchema)(schema)
});
onFinish(
validationResult.success ? { object: validationResult.value, error: void 0 } : { object: void 0, error: validationResult.error }
);
}
}
})
);
} catch (error2) {
if ((0, import_provider_utils2.isAbortError)(error2)) {
return;
}
if (onError && error2 instanceof Error) {
onError(error2);
}
setIsLoading(false);
setError(error2 instanceof Error ? error2 : new Error(String(error2)));
}
};
return {
submit,
object: data,
error,
isLoading,
stop
};
}
var experimental_useObject = useObject;
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
experimental_useObject,
useAssistant,
useChat,
useCompletion
});
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,823 @@
// src/use-assistant.ts
import { isAbortError } from "@ai-sdk/provider-utils";
import {
generateId,
processAssistantStream
} from "@ai-sdk/ui-utils";
import { useCallback, useRef, useState } from "react";
var getOriginalFetch = () => fetch;
function useAssistant({
api,
threadId: threadIdParam,
credentials,
headers,
body,
onError,
fetch: fetch2
}) {
const [messages, setMessages] = useState([]);
const [input, setInput] = useState("");
const [currentThreadId, setCurrentThreadId] = useState(
void 0
);
const [status, setStatus] = useState("awaiting_message");
const [error, setError] = useState(void 0);
const handleInputChange = (event) => {
setInput(event.target.value);
};
const abortControllerRef = useRef(null);
const stop = useCallback(() => {
if (abortControllerRef.current) {
abortControllerRef.current.abort();
abortControllerRef.current = null;
}
}, []);
const append = async (message, requestOptions) => {
var _a, _b;
setStatus("in_progress");
setMessages((messages2) => {
var _a2;
return [
...messages2,
{
...message,
id: (_a2 = message.id) != null ? _a2 : generateId()
}
];
});
setInput("");
const abortController = new AbortController();
try {
abortControllerRef.current = abortController;
const actualFetch = fetch2 != null ? fetch2 : getOriginalFetch();
const response = await actualFetch(api, {
method: "POST",
credentials,
signal: abortController.signal,
headers: { "Content-Type": "application/json", ...headers },
body: JSON.stringify({
...body,
// always use user-provided threadId when available:
threadId: (_a = threadIdParam != null ? threadIdParam : currentThreadId) != null ? _a : null,
message: message.content,
// optional request data:
data: requestOptions == null ? void 0 : requestOptions.data
})
});
if (!response.ok) {
throw new Error(
(_b = await response.text()) != null ? _b : "Failed to fetch the assistant response."
);
}
if (response.body == null) {
throw new Error("The response body is empty.");
}
await processAssistantStream({
stream: response.body,
onAssistantMessagePart(value) {
setMessages((messages2) => [
...messages2,
{
id: value.id,
role: value.role,
content: value.content[0].text.value,
parts: []
}
]);
},
onTextPart(value) {
setMessages((messages2) => {
const lastMessage = messages2[messages2.length - 1];
return [
...messages2.slice(0, messages2.length - 1),
{
id: lastMessage.id,
role: lastMessage.role,
content: lastMessage.content + value,
parts: lastMessage.parts
}
];
});
},
onAssistantControlDataPart(value) {
setCurrentThreadId(value.threadId);
setMessages((messages2) => {
const lastMessage = messages2[messages2.length - 1];
lastMessage.id = value.messageId;
return [...messages2.slice(0, messages2.length - 1), lastMessage];
});
},
onDataMessagePart(value) {
setMessages((messages2) => {
var _a2;
return [
...messages2,
{
id: (_a2 = value.id) != null ? _a2 : generateId(),
role: "data",
content: "",
data: value.data,
parts: []
}
];
});
},
onErrorPart(value) {
setError(new Error(value));
}
});
} catch (error2) {
if (isAbortError(error2) && abortController.signal.aborted) {
abortControllerRef.current = null;
return;
}
if (onError && error2 instanceof Error) {
onError(error2);
}
setError(error2);
} finally {
abortControllerRef.current = null;
setStatus("awaiting_message");
}
};
const submitMessage = async (event, requestOptions) => {
var _a;
(_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
if (input === "") {
return;
}
append({ role: "user", content: input, parts: [] }, requestOptions);
};
const setThreadId = (threadId) => {
setCurrentThreadId(threadId);
setMessages([]);
};
return {
append,
messages,
setMessages,
threadId: currentThreadId,
setThreadId,
input,
setInput,
handleInputChange,
submitMessage,
status,
error,
stop
};
}
// src/use-chat.ts
import {
callChatApi,
extractMaxToolInvocationStep,
fillMessageParts,
generateId as generateIdFunc,
getMessageParts,
isAssistantMessageWithCompletedToolCalls,
prepareAttachmentsForRequest,
shouldResubmitMessages,
updateToolCallResult
} from "@ai-sdk/ui-utils";
import { useCallback as useCallback2, useEffect as useEffect2, useMemo, useRef as useRef2, useState as useState3 } from "react";
import useSWR from "swr";
// src/throttle.ts
import throttleFunction from "throttleit";
function throttle(fn, waitMs) {
return waitMs != null ? throttleFunction(fn, waitMs) : fn;
}
// src/util/use-stable-value.ts
import { isDeepEqualData } from "@ai-sdk/ui-utils";
import { useEffect, useState as useState2 } from "react";
function useStableValue(latestValue) {
const [value, setValue] = useState2(latestValue);
useEffect(() => {
if (!isDeepEqualData(latestValue, value)) {
setValue(latestValue);
}
}, [latestValue, value]);
return value;
}
// src/use-chat.ts
function useChat({
api = "/api/chat",
id,
initialMessages,
initialInput = "",
sendExtraMessageFields,
onToolCall,
experimental_prepareRequestBody,
maxSteps = 1,
streamProtocol = "data",
onResponse,
onFinish,
onError,
credentials,
headers,
body,
generateId: generateId2 = generateIdFunc,
fetch: fetch2,
keepLastMessageOnError = true,
experimental_throttle: throttleWaitMs
} = {}) {
const [hookId] = useState3(generateId2);
const chatId = id != null ? id : hookId;
const chatKey = typeof api === "string" ? [api, chatId] : chatId;
const stableInitialMessages = useStableValue(initialMessages != null ? initialMessages : []);
const processedInitialMessages = useMemo(
() => fillMessageParts(stableInitialMessages),
[stableInitialMessages]
);
const { data: messages, mutate } = useSWR(
[chatKey, "messages"],
null,
{ fallbackData: processedInitialMessages }
);
const messagesRef = useRef2(messages || []);
useEffect2(() => {
messagesRef.current = messages || [];
}, [messages]);
const { data: streamData, mutate: mutateStreamData } = useSWR([chatKey, "streamData"], null);
const streamDataRef = useRef2(streamData);
useEffect2(() => {
streamDataRef.current = streamData;
}, [streamData]);
const { data: status = "ready", mutate: mutateStatus } = useSWR([chatKey, "status"], null);
const { data: error = void 0, mutate: setError } = useSWR([chatKey, "error"], null);
const abortControllerRef = useRef2(null);
const extraMetadataRef = useRef2({
credentials,
headers,
body
});
useEffect2(() => {
extraMetadataRef.current = {
credentials,
headers,
body
};
}, [credentials, headers, body]);
const triggerRequest = useCallback2(
async (chatRequest, requestType = "generate") => {
var _a, _b;
mutateStatus("submitted");
setError(void 0);
const chatMessages = fillMessageParts(chatRequest.messages);
const messageCount = chatMessages.length;
const maxStep = extractMaxToolInvocationStep(
(_a = chatMessages[chatMessages.length - 1]) == null ? void 0 : _a.toolInvocations
);
try {
const abortController = new AbortController();
abortControllerRef.current = abortController;
const throttledMutate = throttle(mutate, throttleWaitMs);
const throttledMutateStreamData = throttle(
mutateStreamData,
throttleWaitMs
);
const previousMessages = messagesRef.current;
throttledMutate(chatMessages, false);
const constructedMessagesPayload = sendExtraMessageFields ? chatMessages : chatMessages.map(
({
role,
content,
experimental_attachments,
data,
annotations,
toolInvocations,
parts
}) => ({
role,
content,
...experimental_attachments !== void 0 && {
experimental_attachments
},
...data !== void 0 && { data },
...annotations !== void 0 && { annotations },
...toolInvocations !== void 0 && { toolInvocations },
...parts !== void 0 && { parts }
})
);
const existingData = streamDataRef.current;
await callChatApi({
api,
body: (_b = experimental_prepareRequestBody == null ? void 0 : experimental_prepareRequestBody({
id: chatId,
messages: chatMessages,
requestData: chatRequest.data,
requestBody: chatRequest.body
})) != null ? _b : {
id: chatId,
messages: constructedMessagesPayload,
data: chatRequest.data,
...extraMetadataRef.current.body,
...chatRequest.body
},
streamProtocol,
credentials: extraMetadataRef.current.credentials,
headers: {
...extraMetadataRef.current.headers,
...chatRequest.headers
},
abortController: () => abortControllerRef.current,
restoreMessagesOnFailure() {
if (!keepLastMessageOnError) {
throttledMutate(previousMessages, false);
}
},
onResponse,
onUpdate({ message, data, replaceLastMessage }) {
mutateStatus("streaming");
throttledMutate(
[
...replaceLastMessage ? chatMessages.slice(0, chatMessages.length - 1) : chatMessages,
message
],
false
);
if (data == null ? void 0 : data.length) {
throttledMutateStreamData(
[...existingData != null ? existingData : [], ...data],
false
);
}
},
onToolCall,
onFinish,
generateId: generateId2,
fetch: fetch2,
lastMessage: chatMessages[chatMessages.length - 1],
requestType
});
abortControllerRef.current = null;
mutateStatus("ready");
} catch (err) {
if (err.name === "AbortError") {
abortControllerRef.current = null;
mutateStatus("ready");
return null;
}
if (onError && err instanceof Error) {
onError(err);
}
setError(err);
mutateStatus("error");
}
const messages2 = messagesRef.current;
if (shouldResubmitMessages({
originalMaxToolInvocationStep: maxStep,
originalMessageCount: messageCount,
maxSteps,
messages: messages2
})) {
await triggerRequest({ messages: messages2 });
}
},
[
mutate,
mutateStatus,
api,
extraMetadataRef,
onResponse,
onFinish,
onError,
setError,
mutateStreamData,
streamDataRef,
streamProtocol,
sendExtraMessageFields,
experimental_prepareRequestBody,
onToolCall,
maxSteps,
messagesRef,
abortControllerRef,
generateId2,
fetch2,
keepLastMessageOnError,
throttleWaitMs,
chatId
]
);
const append = useCallback2(
async (message, {
data,
headers: headers2,
body: body2,
experimental_attachments = message.experimental_attachments
} = {}) => {
var _a, _b;
const attachmentsForRequest = await prepareAttachmentsForRequest(
experimental_attachments
);
const messages2 = messagesRef.current.concat({
...message,
id: (_a = message.id) != null ? _a : generateId2(),
createdAt: (_b = message.createdAt) != null ? _b : /* @__PURE__ */ new Date(),
experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : void 0,
parts: getMessageParts(message)
});
return triggerRequest({ messages: messages2, headers: headers2, body: body2, data });
},
[triggerRequest, generateId2]
);
const reload = useCallback2(
async ({ data, headers: headers2, body: body2 } = {}) => {
const messages2 = messagesRef.current;
if (messages2.length === 0) {
return null;
}
const lastMessage = messages2[messages2.length - 1];
return triggerRequest({
messages: lastMessage.role === "assistant" ? messages2.slice(0, -1) : messages2,
headers: headers2,
body: body2,
data
});
},
[triggerRequest]
);
const stop = useCallback2(() => {
if (abortControllerRef.current) {
abortControllerRef.current.abort();
abortControllerRef.current = null;
}
}, []);
const experimental_resume = useCallback2(async () => {
const messages2 = messagesRef.current;
triggerRequest({ messages: messages2 }, "resume");
}, [triggerRequest]);
const setMessages = useCallback2(
(messages2) => {
if (typeof messages2 === "function") {
messages2 = messages2(messagesRef.current);
}
const messagesWithParts = fillMessageParts(messages2);
mutate(messagesWithParts, false);
messagesRef.current = messagesWithParts;
},
[mutate]
);
const setData = useCallback2(
(data) => {
if (typeof data === "function") {
data = data(streamDataRef.current);
}
mutateStreamData(data, false);
streamDataRef.current = data;
},
[mutateStreamData]
);
const [input, setInput] = useState3(initialInput);
const handleSubmit = useCallback2(
async (event, options = {}, metadata) => {
var _a;
(_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
if (!input && !options.allowEmptySubmit)
return;
if (metadata) {
extraMetadataRef.current = {
...extraMetadataRef.current,
...metadata
};
}
const attachmentsForRequest = await prepareAttachmentsForRequest(
options.experimental_attachments
);
const messages2 = messagesRef.current.concat({
id: generateId2(),
createdAt: /* @__PURE__ */ new Date(),
role: "user",
content: input,
experimental_attachments: attachmentsForRequest.length > 0 ? attachmentsForRequest : void 0,
parts: [{ type: "text", text: input }]
});
const chatRequest = {
messages: messages2,
headers: options.headers,
body: options.body,
data: options.data
};
triggerRequest(chatRequest);
setInput("");
},
[input, generateId2, triggerRequest]
);
const handleInputChange = (e) => {
setInput(e.target.value);
};
const addToolResult = useCallback2(
({ toolCallId, result }) => {
const currentMessages = messagesRef.current;
updateToolCallResult({
messages: currentMessages,
toolCallId,
toolResult: result
});
mutate(
[
...currentMessages.slice(0, currentMessages.length - 1),
{ ...currentMessages[currentMessages.length - 1] }
],
false
);
if (status === "submitted" || status === "streaming") {
return;
}
const lastMessage = currentMessages[currentMessages.length - 1];
if (isAssistantMessageWithCompletedToolCalls(lastMessage)) {
triggerRequest({ messages: currentMessages });
}
},
[mutate, status, triggerRequest]
);
return {
messages: messages != null ? messages : [],
id: chatId,
setMessages,
data: streamData,
setData,
error,
append,
reload,
stop,
experimental_resume,
input,
setInput,
handleInputChange,
handleSubmit,
isLoading: status === "submitted" || status === "streaming",
status,
addToolResult
};
}
// src/use-completion.ts
import {
callCompletionApi
} from "@ai-sdk/ui-utils";
import { useCallback as useCallback3, useEffect as useEffect3, useId, useRef as useRef3, useState as useState4 } from "react";
import useSWR2 from "swr";
function useCompletion({
api = "/api/completion",
id,
initialCompletion = "",
initialInput = "",
credentials,
headers,
body,
streamProtocol = "data",
fetch: fetch2,
onResponse,
onFinish,
onError,
experimental_throttle: throttleWaitMs
} = {}) {
const hookId = useId();
const completionId = id || hookId;
const { data, mutate } = useSWR2([api, completionId], null, {
fallbackData: initialCompletion
});
const { data: isLoading = false, mutate: mutateLoading } = useSWR2(
[completionId, "loading"],
null
);
const { data: streamData, mutate: mutateStreamData } = useSWR2([completionId, "streamData"], null);
const [error, setError] = useState4(void 0);
const completion = data;
const [abortController, setAbortController] = useState4(null);
const extraMetadataRef = useRef3({
credentials,
headers,
body
});
useEffect3(() => {
extraMetadataRef.current = {
credentials,
headers,
body
};
}, [credentials, headers, body]);
const triggerRequest = useCallback3(
async (prompt, options) => callCompletionApi({
api,
prompt,
credentials: extraMetadataRef.current.credentials,
headers: { ...extraMetadataRef.current.headers, ...options == null ? void 0 : options.headers },
body: {
...extraMetadataRef.current.body,
...options == null ? void 0 : options.body
},
streamProtocol,
fetch: fetch2,
// throttle streamed ui updates:
setCompletion: throttle(
(completion2) => mutate(completion2, false),
throttleWaitMs
),
onData: throttle(
(data2) => mutateStreamData([...streamData != null ? streamData : [], ...data2 != null ? data2 : []], false),
throttleWaitMs
),
setLoading: mutateLoading,
setError,
setAbortController,
onResponse,
onFinish,
onError
}),
[
mutate,
mutateLoading,
api,
extraMetadataRef,
setAbortController,
onResponse,
onFinish,
onError,
setError,
streamData,
streamProtocol,
fetch2,
mutateStreamData,
throttleWaitMs
]
);
const stop = useCallback3(() => {
if (abortController) {
abortController.abort();
setAbortController(null);
}
}, [abortController]);
const setCompletion = useCallback3(
(completion2) => {
mutate(completion2, false);
},
[mutate]
);
const complete = useCallback3(
async (prompt, options) => {
return triggerRequest(prompt, options);
},
[triggerRequest]
);
const [input, setInput] = useState4(initialInput);
const handleSubmit = useCallback3(
(event) => {
var _a;
(_a = event == null ? void 0 : event.preventDefault) == null ? void 0 : _a.call(event);
return input ? complete(input) : void 0;
},
[input, complete]
);
const handleInputChange = useCallback3(
(e) => {
setInput(e.target.value);
},
[setInput]
);
return {
completion,
complete,
error,
setCompletion,
stop,
input,
setInput,
handleInputChange,
handleSubmit,
isLoading,
data: streamData
};
}
// src/use-object.ts
import {
isAbortError as isAbortError2,
safeValidateTypes
} from "@ai-sdk/provider-utils";
import {
asSchema,
isDeepEqualData as isDeepEqualData2,
parsePartialJson
} from "@ai-sdk/ui-utils";
import { useCallback as useCallback4, useId as useId2, useRef as useRef4, useState as useState5 } from "react";
import useSWR3 from "swr";
var getOriginalFetch2 = () => fetch;
function useObject({
api,
id,
schema,
// required, in the future we will use it for validation
initialValue,
fetch: fetch2,
onError,
onFinish,
headers,
credentials
}) {
const hookId = useId2();
const completionId = id != null ? id : hookId;
const { data, mutate } = useSWR3(
[api, completionId],
null,
{ fallbackData: initialValue }
);
const [error, setError] = useState5(void 0);
const [isLoading, setIsLoading] = useState5(false);
const abortControllerRef = useRef4(null);
const stop = useCallback4(() => {
var _a;
try {
(_a = abortControllerRef.current) == null ? void 0 : _a.abort();
} catch (ignored) {
} finally {
setIsLoading(false);
abortControllerRef.current = null;
}
}, []);
const submit = async (input) => {
var _a;
try {
mutate(void 0);
setIsLoading(true);
setError(void 0);
const abortController = new AbortController();
abortControllerRef.current = abortController;
const actualFetch = fetch2 != null ? fetch2 : getOriginalFetch2();
const response = await actualFetch(api, {
method: "POST",
headers: {
"Content-Type": "application/json",
...headers
},
credentials,
signal: abortController.signal,
body: JSON.stringify(input)
});
if (!response.ok) {
throw new Error(
(_a = await response.text()) != null ? _a : "Failed to fetch the response."
);
}
if (response.body == null) {
throw new Error("The response body is empty.");
}
let accumulatedText = "";
let latestObject = void 0;
await response.body.pipeThrough(new TextDecoderStream()).pipeTo(
new WritableStream({
write(chunk) {
accumulatedText += chunk;
const { value } = parsePartialJson(accumulatedText);
const currentObject = value;
if (!isDeepEqualData2(latestObject, currentObject)) {
latestObject = currentObject;
mutate(currentObject);
}
},
close() {
setIsLoading(false);
abortControllerRef.current = null;
if (onFinish != null) {
const validationResult = safeValidateTypes({
value: latestObject,
schema: asSchema(schema)
});
onFinish(
validationResult.success ? { object: validationResult.value, error: void 0 } : { object: void 0, error: validationResult.error }
);
}
}
})
);
} catch (error2) {
if (isAbortError2(error2)) {
return;
}
if (onError && error2 instanceof Error) {
onError(error2);
}
setIsLoading(false);
setError(error2 instanceof Error ? error2 : new Error(String(error2)));
}
};
return {
submit,
object: data,
error,
isLoading,
stop
};
}
var experimental_useObject = useObject;
export {
experimental_useObject,
useAssistant,
useChat,
useCompletion
};
//# sourceMappingURL=index.mjs.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,81 @@
{
"name": "@ai-sdk/react",
"version": "1.2.12",
"license": "Apache-2.0",
"sideEffects": false,
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"exports": {
"./package.json": "./package.json",
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
}
},
"files": [
"dist/**/*",
"CHANGELOG.md"
],
"dependencies": {
"@ai-sdk/provider-utils": "2.2.8",
"@ai-sdk/ui-utils": "1.2.11",
"swr": "^2.2.5",
"throttleit": "2.1.0"
},
"devDependencies": {
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/user-event": "^14.5.2",
"@testing-library/react": "^16.0.1",
"@types/node": "20.17.24",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "8.57.1",
"jsdom": "^24.0.0",
"msw": "2.6.4",
"react-dom": "^18",
"tsup": "^7.2.0",
"typescript": "5.6.3",
"zod": "3.23.8",
"@vercel/ai-tsconfig": "0.0.0",
"eslint-config-vercel-ai": "0.0.0"
},
"peerDependencies": {
"react": "^18 || ^19 || ^19.0.0-rc",
"zod": "^3.23.8"
},
"peerDependenciesMeta": {
"zod": {
"optional": true
}
},
"engines": {
"node": ">=18"
},
"publishConfig": {
"access": "public"
},
"homepage": "https://ai-sdk.dev/docs",
"repository": {
"type": "git",
"url": "git+https://github.com/vercel/ai.git"
},
"bugs": {
"url": "https://github.com/vercel/ai/issues"
},
"keywords": [
"ai",
"react"
],
"scripts": {
"build": "tsup",
"build:watch": "tsup --watch",
"clean": "rm -rf dist",
"lint": "eslint \"./**/*.ts*\"",
"type-check": "tsc --noEmit",
"prettier-check": "prettier --check \"./**/*.ts*\"",
"test": "vitest --config vitest.config.js --run",
"test:watch": "vitest --config vitest.config.js"
}
}

View File

@@ -0,0 +1,796 @@
# @ai-sdk/ui-utils
## 1.2.11
### Patch Changes
- Updated dependencies [d87b9d1]
- @ai-sdk/provider-utils@2.2.8
## 1.2.10
### Patch Changes
- 6c59ae7: feat (ui/react): support resuming an ongoing stream
## 1.2.9
### Patch Changes
- 62181ef: fix(react-native): support experimental_attachments without FileList global
## 1.2.8
### Patch Changes
- Updated dependencies [beef951]
- @ai-sdk/provider@1.1.3
- @ai-sdk/provider-utils@2.2.7
## 1.2.7
### Patch Changes
- Updated dependencies [013faa8]
- @ai-sdk/provider@1.1.2
- @ai-sdk/provider-utils@2.2.6
## 1.2.6
### Patch Changes
- Updated dependencies [c21fa6d]
- @ai-sdk/provider-utils@2.2.5
- @ai-sdk/provider@1.1.1
## 1.2.5
### Patch Changes
- Updated dependencies [2c19b9a]
- @ai-sdk/provider-utils@2.2.4
## 1.2.4
### Patch Changes
- Updated dependencies [28be004]
- @ai-sdk/provider-utils@2.2.3
## 1.2.3
### Patch Changes
- Updated dependencies [b01120e]
- @ai-sdk/provider-utils@2.2.2
## 1.2.2
### Patch Changes
- 65243ce: fix (ui): introduce step start parts
## 1.2.1
### Patch Changes
- Updated dependencies [f10f0fa]
- @ai-sdk/provider-utils@2.2.1
## 1.2.0
### Minor Changes
- 5bc638d: AI SDK 4.2
### Patch Changes
- Updated dependencies [5bc638d]
- @ai-sdk/provider@1.1.0
- @ai-sdk/provider-utils@2.2.0
## 1.1.21
### Patch Changes
- Updated dependencies [d0c4659]
- @ai-sdk/provider-utils@2.1.15
## 1.1.20
### Patch Changes
- Updated dependencies [0bd5bc6]
- @ai-sdk/provider@1.0.12
- @ai-sdk/provider-utils@2.1.14
## 1.1.19
### Patch Changes
- Updated dependencies [2e1101a]
- @ai-sdk/provider@1.0.11
- @ai-sdk/provider-utils@2.1.13
## 1.1.18
### Patch Changes
- Updated dependencies [1531959]
- @ai-sdk/provider-utils@2.1.12
## 1.1.17
### Patch Changes
- Updated dependencies [e1d3d42]
- @ai-sdk/provider@1.0.10
- @ai-sdk/provider-utils@2.1.11
## 1.1.16
### Patch Changes
- ddf9740: feat (ai): add anthropic reasoning
- Updated dependencies [ddf9740]
- @ai-sdk/provider@1.0.9
- @ai-sdk/provider-utils@2.1.10
## 1.1.15
### Patch Changes
- Updated dependencies [2761f06]
- @ai-sdk/provider@1.0.8
- @ai-sdk/provider-utils@2.1.9
## 1.1.14
### Patch Changes
- Updated dependencies [2e898b4]
- @ai-sdk/provider-utils@2.1.8
## 1.1.13
### Patch Changes
- Updated dependencies [3ff4ef8]
- @ai-sdk/provider-utils@2.1.7
## 1.1.12
### Patch Changes
- 166e09e: feat (ai/ui): forward source parts to useChat
## 1.1.11
### Patch Changes
- 318b351: fix (ui): update ui before automatic client-side tool call is executed
## 1.1.10
### Patch Changes
- bcc61d4: feat (ui): introduce message parts for useChat
## 1.1.9
### Patch Changes
- 6b8cc14: feat (ai/core): support recursive zod schemas
## 1.1.8
### Patch Changes
- Updated dependencies [d89c3b9]
- @ai-sdk/provider@1.0.7
- @ai-sdk/provider-utils@2.1.6
## 1.1.7
### Patch Changes
- 0d2d9bf: fix (ui): single assistant message with multiple tool steps
## 1.1.6
### Patch Changes
- 3a602ca: chore (core): rename CoreTool to Tool
- Updated dependencies [3a602ca]
- @ai-sdk/provider-utils@2.1.5
## 1.1.5
### Patch Changes
- Updated dependencies [066206e]
- @ai-sdk/provider-utils@2.1.4
## 1.1.4
### Patch Changes
- Updated dependencies [39e5c1f]
- @ai-sdk/provider-utils@2.1.3
## 1.1.3
### Patch Changes
- 9ce598c: feat (ai/ui): add reasoning support to useChat
## 1.1.2
### Patch Changes
- Updated dependencies [ed012d2]
- Updated dependencies [3a58a2e]
- @ai-sdk/provider-utils@2.1.2
- @ai-sdk/provider@1.0.6
## 1.1.1
### Patch Changes
- e7a9ec9: feat (provider-utils): include raw value in json parse results
- 0a699f1: feat: add reasoning token support
- Updated dependencies [e7a9ec9]
- Updated dependencies [0a699f1]
- @ai-sdk/provider-utils@2.1.1
- @ai-sdk/provider@1.0.5
## 1.1.0
### Minor Changes
- 62ba5ad: release: AI SDK 4.1
### Patch Changes
- Updated dependencies [62ba5ad]
- @ai-sdk/provider-utils@2.1.0
## 1.0.12
### Patch Changes
- 33592d2: fix (ai/core): switch to json schema 7 target for zod to json schema conversion
## 1.0.11
### Patch Changes
- 00114c5: feat (ui): generate and forward message ids for response messages
- Updated dependencies [00114c5]
- @ai-sdk/provider-utils@2.0.8
## 1.0.10
### Patch Changes
- 37f4510: feat (ui): expose useChat id and send it to the server
## 1.0.9
### Patch Changes
- 2495973: feat (ai/core): use openai compatible mode for json schema conversion
- 2495973: fix (ai/core): duplicate instead of using reference in json schema
## 1.0.8
### Patch Changes
- Updated dependencies [90fb95a]
- Updated dependencies [e6dfef4]
- Updated dependencies [6636db6]
- @ai-sdk/provider-utils@2.0.7
## 1.0.7
### Patch Changes
- Updated dependencies [19a2ce7]
- Updated dependencies [19a2ce7]
- Updated dependencies [6337688]
- @ai-sdk/provider@1.0.4
- @ai-sdk/provider-utils@2.0.6
## 1.0.6
### Patch Changes
- Updated dependencies [5ed5e45]
- @ai-sdk/provider-utils@2.0.5
- @ai-sdk/provider@1.0.3
## 1.0.5
### Patch Changes
- Updated dependencies [09a9cab]
- @ai-sdk/provider@1.0.2
- @ai-sdk/provider-utils@2.0.4
## 1.0.4
### Patch Changes
- Updated dependencies [0984f0b]
- @ai-sdk/provider-utils@2.0.3
## 1.0.3
### Patch Changes
- 953469c: chore (ui): extract prepareAttachmentsForRequest
- a3dd2ed: fix (ui): preserve createdAt as Date object
## 1.0.2
### Patch Changes
- 88b364b: fix (ui-utils): deep clone messages
- Updated dependencies [b446ae5]
- @ai-sdk/provider@1.0.1
- @ai-sdk/provider-utils@2.0.2
## 1.0.1
### Patch Changes
- Updated dependencies [c3ab5de]
- @ai-sdk/provider-utils@2.0.1
## 1.0.0
### Major Changes
- 8bf5756: chore: remove legacy function/tool calling
- 7814c4b: chore (ui): remove streamMode setting from useChat & useCompletion
- fe4f109: chore (ui): set default value of useChat keepLastMessageOnError to true
- 7e89ccb: chore: remove nanoid export
### Patch Changes
- 9f81e66: chore (ui-utils): remove unnecessary dependencies
- 70f28f6: chore (ui-utils): mark vitest as external to reduce bundle size of /test
- 04d3747: chore (ui-utils): restructure processAssistantMessage
- b053413: chore (ui): refactorings & README update
- Updated dependencies [b469a7e]
- Updated dependencies [dce4158]
- Updated dependencies [c0ddc24]
- Updated dependencies [b1da952]
- Updated dependencies [dce4158]
- Updated dependencies [8426f55]
- Updated dependencies [db46ce5]
- @ai-sdk/provider-utils@2.0.0
- @ai-sdk/provider@1.0.0
## 1.0.0-canary.9
### Patch Changes
- 04d3747: chore (ui-utils): restructure processAssistantMessage
## 1.0.0-canary.8
### Patch Changes
- b053413: chore (ui): refactorings & README update
## 1.0.0-canary.7
### Major Changes
- fe4f109: chore (ui): set default value of useChat keepLastMessageOnError to true
## 1.0.0-canary.6
### Patch Changes
- 70f28f6: chore (ui-utils): mark vitest as external to reduce bundle size of /test
## 1.0.0-canary.5
### Patch Changes
- 9f81e66: chore (ui-utils): remove unnecessary dependencies
- Updated dependencies [8426f55]
- @ai-sdk/provider-utils@2.0.0-canary.3
## 1.0.0-canary.4
### Patch Changes
- Updated dependencies [dce4158]
- Updated dependencies [dce4158]
- @ai-sdk/provider-utils@2.0.0-canary.2
## 1.0.0-canary.3
### Patch Changes
- Updated dependencies [b1da952]
- @ai-sdk/provider-utils@2.0.0-canary.1
## 1.0.0-canary.2
### Major Changes
- 7814c4b: chore (ui): remove streamMode setting from useChat & useCompletion
### Patch Changes
- Updated dependencies [b469a7e]
- Updated dependencies [c0ddc24]
- Updated dependencies [db46ce5]
- @ai-sdk/provider-utils@2.0.0-canary.0
- @ai-sdk/provider@1.0.0-canary.0
## 1.0.0-canary.1
### Major Changes
- 8bf5756: chore: remove legacy function/tool calling
## 1.0.0-canary.0
### Major Changes
- 7e89ccb: chore: remove nanoid export
## 0.0.50
### Patch Changes
- a85c965: fix (ai/ui): send message annotations from onChunk
## 0.0.49
### Patch Changes
- 3bf8da0: fix (ai/ui): update latest message with stream data message annotations until new message starts
## 0.0.48
### Patch Changes
- aa98cdb: chore: more flexible dependency versioning
- 811a317: feat (ai/core): multi-part tool results (incl. images)
- Updated dependencies [aa98cdb]
- Updated dependencies [1486128]
- Updated dependencies [7b937c5]
- Updated dependencies [3b1b69a]
- Updated dependencies [811a317]
- @ai-sdk/provider-utils@1.0.22
- @ai-sdk/provider@0.0.26
## 0.0.47
### Patch Changes
- Updated dependencies [b9b0d7b]
- @ai-sdk/provider@0.0.25
- @ai-sdk/provider-utils@1.0.21
## 0.0.46
### Patch Changes
- Updated dependencies [d595d0d]
- @ai-sdk/provider@0.0.24
- @ai-sdk/provider-utils@1.0.20
## 0.0.45
### Patch Changes
- cd77c5d: feat (ai/core): add isContinued to steps
## 0.0.44
### Patch Changes
- Updated dependencies [273f696]
- @ai-sdk/provider-utils@1.0.19
## 0.0.43
### Patch Changes
- 1f590ef: chore (ai): rename roundtrips to steps
## 0.0.42
### Patch Changes
- 14210d5: feat (ai/core): add sendUsage information to streamText data stream methods
## 0.0.41
### Patch Changes
- Updated dependencies [03313cd]
- Updated dependencies [3be7c1c]
- @ai-sdk/provider-utils@1.0.18
- @ai-sdk/provider@0.0.23
## 0.0.40
### Patch Changes
- aa2dc58: feat (ai/core): add maxToolRoundtrips to streamText
## 0.0.39
### Patch Changes
- Updated dependencies [26515cb]
- @ai-sdk/provider@0.0.22
- @ai-sdk/provider-utils@1.0.17
## 0.0.38
### Patch Changes
- d151349: feat (ai/core): array output for generateObject / streamObject
## 0.0.37
### Patch Changes
- Updated dependencies [09f895f]
- @ai-sdk/provider-utils@1.0.16
## 0.0.36
### Patch Changes
- b5a82b7: chore (ai): update zod-to-json-schema to 3.23.2
## 0.0.35
### Patch Changes
- Updated dependencies [d67fa9c]
- @ai-sdk/provider-utils@1.0.15
## 0.0.34
### Patch Changes
- Updated dependencies [f2c025e]
- @ai-sdk/provider@0.0.21
- @ai-sdk/provider-utils@1.0.14
## 0.0.33
### Patch Changes
- Updated dependencies [6ac355e]
- @ai-sdk/provider@0.0.20
- @ai-sdk/provider-utils@1.0.13
## 0.0.32
### Patch Changes
- dd712ac: fix: use FetchFunction type to prevent self-reference
- Updated dependencies [dd712ac]
- @ai-sdk/provider-utils@1.0.12
## 0.0.31
### Patch Changes
- Updated dependencies [dd4a0f5]
- @ai-sdk/provider@0.0.19
- @ai-sdk/provider-utils@1.0.11
## 0.0.30
### Patch Changes
- e9c891d: feat (ai/react): useObject supports non-Zod schemas
- Updated dependencies [4bd27a9]
- Updated dependencies [845754b]
- @ai-sdk/provider-utils@1.0.10
- @ai-sdk/provider@0.0.18
## 0.0.29
### Patch Changes
- e5b58f3: fix (ai/ui): forward streaming errors in useChat
## 0.0.28
### Patch Changes
- Updated dependencies [029af4c]
- @ai-sdk/provider@0.0.17
- @ai-sdk/provider-utils@1.0.9
## 0.0.27
### Patch Changes
- Updated dependencies [d58517b]
- @ai-sdk/provider@0.0.16
- @ai-sdk/provider-utils@1.0.8
## 0.0.26
### Patch Changes
- Updated dependencies [96aed25]
- @ai-sdk/provider@0.0.15
- @ai-sdk/provider-utils@1.0.7
## 0.0.25
### Patch Changes
- Updated dependencies [9614584]
- Updated dependencies [0762a22]
- @ai-sdk/provider-utils@1.0.6
## 0.0.24
### Patch Changes
- 5be25124: fix (ai/ui): useChat messages have stable ids with streamProtocol: "text"
## 0.0.23
### Patch Changes
- fea7b604: chore (ai/ui): remove "args" and "toolName" from tool result stream part.
## 0.0.22
### Patch Changes
- 1d93d716: fix (ai/ui): parse null as NaN in finish message stream parts
## 0.0.21
### Patch Changes
- c450fcf7: feat (ui): invoke useChat onFinish with finishReason and tokens
- e4a1719f: chore (ai/ui): rename streamMode to streamProtocol
## 0.0.20
### Patch Changes
- Updated dependencies [a8d1c9e9]
- @ai-sdk/provider-utils@1.0.5
## 0.0.19
### Patch Changes
- Updated dependencies [4f88248f]
- @ai-sdk/provider-utils@1.0.4
## 0.0.18
### Patch Changes
- @ai-sdk/provider-utils@1.0.3
## 0.0.17
### Patch Changes
- f63829fe: feat (ai/ui): add allowEmptySubmit flag to handleSubmit
## 0.0.16
### Patch Changes
- 5b7b3bbe: fix (ai/ui): tool call streaming
## 0.0.15
### Patch Changes
- 1f67fe49: feat (ai/ui): stream tool calls with streamText and useChat
## 0.0.14
### Patch Changes
- 99ddbb74: feat (ai/react): add experimental support for managing attachments to useChat
## 0.0.13
### Patch Changes
- a6cb2c8b: feat (ai/ui): add keepLastMessageOnError option to useChat
## 0.0.12
### Patch Changes
- 56bbc2a7: feat (ai/ui): set body and headers directly on options for handleSubmit and append
## 0.0.11
### Patch Changes
- @ai-sdk/provider-utils@1.0.2
## 0.0.10
### Patch Changes
- Updated dependencies [d481729f]
- @ai-sdk/provider-utils@1.0.1
## 0.0.9
### Patch Changes
- 1894f811: feat (ai/ui): allow JSONValue as data in useChat handleSubmit
## 0.0.8
### Patch Changes
- d3100b9c: feat (ai/ui): support custom fetch function in useChat, useCompletion, useAssistant, useObject
## 0.0.7
### Patch Changes
- Updated dependencies [5edc6110]
- Updated dependencies [5edc6110]
- @ai-sdk/provider-utils@1.0.0
## 0.0.6
### Patch Changes
- 54bf4083: feat (ai/react): control request body in useChat
## 0.0.5
### Patch Changes
- Updated dependencies [02f6a088]
- @ai-sdk/provider-utils@0.0.16
## 0.0.4
### Patch Changes
- 008725ec: chore (@ai-sdk/ui-utils): move functions
## 0.0.3
### Patch Changes
- Updated dependencies [85712895]
- Updated dependencies [85712895]
- @ai-sdk/provider-utils@0.0.15
## 0.0.2
### Patch Changes
- Updated dependencies [7910ae84]
- @ai-sdk/provider-utils@0.0.14
## 0.0.1
### Patch Changes
- 85f209a4: chore: extracted ui library support into separate modules

View File

@@ -0,0 +1,13 @@
Copyright 2023 Vercel, Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,3 @@
# AI SDK - UI Framework Integration Implementation Utilities
Important: this is an internal API. Expect breaking changes.

View File

@@ -0,0 +1,820 @@
import { LanguageModelV1Source, LanguageModelV1FinishReason, JSONValue as JSONValue$1 } from '@ai-sdk/provider';
import { FetchFunction, ToolCall, ToolResult, Validator } from '@ai-sdk/provider-utils';
export { generateId } from '@ai-sdk/provider-utils';
import { z } from 'zod';
import { JSONSchema7 } from 'json-schema';
/**
Represents the number of tokens used in a prompt and completion.
*/
type LanguageModelUsage = {
/**
The number of tokens used in the prompt.
*/
promptTokens: number;
/**
The number of tokens used in the completion.
*/
completionTokens: number;
/**
The total number of tokens used (promptTokens + completionTokens).
*/
totalTokens: number;
};
type AssistantStatus = 'in_progress' | 'awaiting_message';
type UseAssistantOptions = {
/**
* The API endpoint that accepts a `{ threadId: string | null; message: string; }` object and returns an `AssistantResponse` stream.
* The threadId refers to an existing thread with messages (or is `null` to create a new thread).
* The message is the next message that should be appended to the thread and sent to the assistant.
*/
api: string;
/**
* An optional string that represents the ID of an existing thread.
* If not provided, a new thread will be created.
*/
threadId?: string;
/**
* An optional literal that sets the mode of credentials to be used on the request.
* Defaults to "same-origin".
*/
credentials?: RequestCredentials;
/**
* An optional object of headers to be passed to the API endpoint.
*/
headers?: Record<string, string> | Headers;
/**
* An optional, additional body object to be passed to the API endpoint.
*/
body?: object;
/**
* An optional callback that will be called when the assistant encounters an error.
*/
onError?: (error: Error) => void;
/**
Custom fetch implementation. You can use it as a middleware to intercept requests,
or to provide a custom fetch implementation for e.g. testing.
*/
fetch?: FetchFunction;
};
type IdGenerator = () => string;
/**
Tool invocations are either tool calls or tool results. For each assistant tool call,
there is one tool invocation. While the call is in progress, the invocation is a tool call.
Once the call is complete, the invocation is a tool result.
The step is used to track how to map an assistant UI message with many tool invocations
back to a sequence of LLM assistant/tool result message pairs.
It is optional for backwards compatibility.
*/
type ToolInvocation = ({
state: 'partial-call';
step?: number;
} & ToolCall<string, any>) | ({
state: 'call';
step?: number;
} & ToolCall<string, any>) | ({
state: 'result';
step?: number;
} & ToolResult<string, any, any>);
/**
* An attachment that can be sent along with a message.
*/
interface Attachment {
/**
* The name of the attachment, usually the file name.
*/
name?: string;
/**
* A string indicating the [media type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type).
* By default, it's extracted from the pathname's extension.
*/
contentType?: string;
/**
* The URL of the attachment. It can either be a URL to a hosted file or a [Data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs).
*/
url: string;
}
/**
* AI SDK UI Messages. They are used in the client and to communicate between the frontend and the API routes.
*/
interface Message {
/**
A unique identifier for the message.
*/
id: string;
/**
The timestamp of the message.
*/
createdAt?: Date;
/**
Text content of the message. Use parts when possible.
*/
content: string;
/**
Reasoning for the message.
@deprecated Use `parts` instead.
*/
reasoning?: string;
/**
* Additional attachments to be sent along with the message.
*/
experimental_attachments?: Attachment[];
/**
The 'data' role is deprecated.
*/
role: 'system' | 'user' | 'assistant' | 'data';
/**
For data messages.
@deprecated Data messages will be removed.
*/
data?: JSONValue;
/**
* Additional message-specific information added on the server via StreamData
*/
annotations?: JSONValue[] | undefined;
/**
Tool invocations (that can be tool calls or tool results, depending on whether or not the invocation has finished)
that the assistant made as part of this message.
@deprecated Use `parts` instead.
*/
toolInvocations?: Array<ToolInvocation>;
/**
* The parts of the message. Use this for rendering the message in the UI.
*
* Assistant messages can have text, reasoning and tool invocation parts.
* User messages can have text parts.
*/
parts?: Array<TextUIPart | ReasoningUIPart | ToolInvocationUIPart | SourceUIPart | FileUIPart | StepStartUIPart>;
}
type UIMessage = Message & {
/**
* The parts of the message. Use this for rendering the message in the UI.
*
* Assistant messages can have text, reasoning and tool invocation parts.
* User messages can have text parts.
*/
parts: Array<TextUIPart | ReasoningUIPart | ToolInvocationUIPart | SourceUIPart | FileUIPart | StepStartUIPart>;
};
/**
* A text part of a message.
*/
type TextUIPart = {
type: 'text';
/**
* The text content.
*/
text: string;
};
/**
* A reasoning part of a message.
*/
type ReasoningUIPart = {
type: 'reasoning';
/**
* The reasoning text.
*/
reasoning: string;
details: Array<{
type: 'text';
text: string;
signature?: string;
} | {
type: 'redacted';
data: string;
}>;
};
/**
* A tool invocation part of a message.
*/
type ToolInvocationUIPart = {
type: 'tool-invocation';
/**
* The tool invocation.
*/
toolInvocation: ToolInvocation;
};
/**
* A source part of a message.
*/
type SourceUIPart = {
type: 'source';
/**
* The source.
*/
source: LanguageModelV1Source;
};
/**
* A file part of a message.
*/
type FileUIPart = {
type: 'file';
mimeType: string;
data: string;
};
/**
* A step boundary part of a message.
*/
type StepStartUIPart = {
type: 'step-start';
};
type CreateMessage = Omit<Message, 'id'> & {
id?: Message['id'];
};
type ChatRequest = {
/**
An optional object of headers to be passed to the API endpoint.
*/
headers?: Record<string, string> | Headers;
/**
An optional object to be passed to the API endpoint.
*/
body?: object;
/**
The messages of the chat.
*/
messages: Message[];
/**
Additional data to be sent to the server.
*/
data?: JSONValue;
};
type RequestOptions = {
/**
An optional object of headers to be passed to the API endpoint.
*/
headers?: Record<string, string> | Headers;
/**
An optional object to be passed to the API endpoint.
*/
body?: object;
};
type ChatRequestOptions = {
/**
Additional headers that should be to be passed to the API endpoint.
*/
headers?: Record<string, string> | Headers;
/**
Additional body JSON properties that should be sent to the API endpoint.
*/
body?: object;
/**
Additional data to be sent to the API endpoint.
*/
data?: JSONValue;
/**
* Additional files to be sent to the server.
*/
experimental_attachments?: FileList | Array<Attachment>;
/**
* Allow submitting an empty message. Defaults to `false`.
*/
allowEmptySubmit?: boolean;
};
type UseChatOptions = {
/**
Keeps the last message when an error happens. Defaults to `true`.
@deprecated This option will be removed in the next major release.
*/
keepLastMessageOnError?: boolean;
/**
* The API endpoint that accepts a `{ messages: Message[] }` object and returns
* a stream of tokens of the AI chat response. Defaults to `/api/chat`.
*/
api?: string;
/**
* A unique identifier for the chat. If not provided, a random one will be
* generated. When provided, the `useChat` hook with the same `id` will
* have shared states across components.
*/
id?: string;
/**
* Initial messages of the chat. Useful to load an existing chat history.
*/
initialMessages?: Message[];
/**
* Initial input of the chat.
*/
initialInput?: string;
/**
Optional callback function that is invoked when a tool call is received.
Intended for automatic client-side tool execution.
You can optionally return a result for the tool call,
either synchronously or asynchronously.
*/
onToolCall?: ({ toolCall, }: {
toolCall: ToolCall<string, unknown>;
}) => void | Promise<unknown> | unknown;
/**
* Callback function to be called when the API response is received.
*/
onResponse?: (response: Response) => void | Promise<void>;
/**
* Optional callback function that is called when the assistant message is finished streaming.
*
* @param message The message that was streamed.
* @param options.usage The token usage of the message.
* @param options.finishReason The finish reason of the message.
*/
onFinish?: (message: Message, options: {
usage: LanguageModelUsage;
finishReason: LanguageModelV1FinishReason;
}) => void;
/**
* Callback function to be called when an error is encountered.
*/
onError?: (error: Error) => void;
/**
* A way to provide a function that is going to be used for ids for messages and the chat.
* If not provided the default AI SDK `generateId` is used.
*/
generateId?: IdGenerator;
/**
* The credentials mode to be used for the fetch request.
* Possible values are: 'omit', 'same-origin', 'include'.
* Defaults to 'same-origin'.
*/
credentials?: RequestCredentials;
/**
* HTTP headers to be sent with the API request.
*/
headers?: Record<string, string> | Headers;
/**
* Extra body object to be sent with the API request.
* @example
* Send a `sessionId` to the API along with the messages.
* ```js
* useChat({
* body: {
* sessionId: '123',
* }
* })
* ```
*/
body?: object;
/**
* Whether to send extra message fields such as `message.id` and `message.createdAt` to the API.
* Defaults to `false`. When set to `true`, the API endpoint might need to
* handle the extra fields before forwarding the request to the AI service.
*/
sendExtraMessageFields?: boolean;
/**
Streaming protocol that is used. Defaults to `data`.
*/
streamProtocol?: 'data' | 'text';
/**
Custom fetch implementation. You can use it as a middleware to intercept requests,
or to provide a custom fetch implementation for e.g. testing.
*/
fetch?: FetchFunction;
};
type UseCompletionOptions = {
/**
* The API endpoint that accepts a `{ prompt: string }` object and returns
* a stream of tokens of the AI completion response. Defaults to `/api/completion`.
*/
api?: string;
/**
* An unique identifier for the chat. If not provided, a random one will be
* generated. When provided, the `useChat` hook with the same `id` will
* have shared states across components.
*/
id?: string;
/**
* Initial prompt input of the completion.
*/
initialInput?: string;
/**
* Initial completion result. Useful to load an existing history.
*/
initialCompletion?: string;
/**
* Callback function to be called when the API response is received.
*/
onResponse?: (response: Response) => void | Promise<void>;
/**
* Callback function to be called when the completion is finished streaming.
*/
onFinish?: (prompt: string, completion: string) => void;
/**
* Callback function to be called when an error is encountered.
*/
onError?: (error: Error) => void;
/**
* The credentials mode to be used for the fetch request.
* Possible values are: 'omit', 'same-origin', 'include'.
* Defaults to 'same-origin'.
*/
credentials?: RequestCredentials;
/**
* HTTP headers to be sent with the API request.
*/
headers?: Record<string, string> | Headers;
/**
* Extra body object to be sent with the API request.
* @example
* Send a `sessionId` to the API along with the prompt.
* ```js
* useChat({
* body: {
* sessionId: '123',
* }
* })
* ```
*/
body?: object;
/**
Streaming protocol that is used. Defaults to `data`.
*/
streamProtocol?: 'data' | 'text';
/**
Custom fetch implementation. You can use it as a middleware to intercept requests,
or to provide a custom fetch implementation for e.g. testing.
*/
fetch?: FetchFunction;
};
/**
A JSON value can be a string, number, boolean, object, array, or null.
JSON values can be serialized and deserialized by the JSON.stringify and JSON.parse methods.
*/
type JSONValue = null | string | number | boolean | {
[value: string]: JSONValue;
} | Array<JSONValue>;
type AssistantMessage = {
id: string;
role: 'assistant';
content: Array<{
type: 'text';
text: {
value: string;
};
}>;
};
type DataMessage = {
id?: string;
role: 'data';
data: JSONValue;
};
type AssistantStreamString = `${(typeof StreamStringPrefixes)[keyof typeof StreamStringPrefixes]}:${string}\n`;
interface AssistantStreamPart<CODE extends string, NAME extends string, TYPE> {
code: CODE;
name: NAME;
parse: (value: JSONValue) => {
type: NAME;
value: TYPE;
};
}
declare const textStreamPart: AssistantStreamPart<'0', 'text', string>;
declare const errorStreamPart: AssistantStreamPart<'3', 'error', string>;
declare const assistantMessageStreamPart: AssistantStreamPart<'4', 'assistant_message', AssistantMessage>;
declare const assistantControlDataStreamPart: AssistantStreamPart<'5', 'assistant_control_data', {
threadId: string;
messageId: string;
}>;
declare const dataMessageStreamPart: AssistantStreamPart<'6', 'data_message', DataMessage>;
type AssistantStreamParts = typeof textStreamPart | typeof errorStreamPart | typeof assistantMessageStreamPart | typeof assistantControlDataStreamPart | typeof dataMessageStreamPart;
type AssistantStreamPartValueType = {
[P in AssistantStreamParts as P['name']]: ReturnType<P['parse']>['value'];
};
type AssistantStreamPartType = ReturnType<typeof textStreamPart.parse> | ReturnType<typeof errorStreamPart.parse> | ReturnType<typeof assistantMessageStreamPart.parse> | ReturnType<typeof assistantControlDataStreamPart.parse> | ReturnType<typeof dataMessageStreamPart.parse>;
declare const StreamStringPrefixes: {
readonly text: "0";
readonly error: "3";
readonly assistant_message: "4";
readonly assistant_control_data: "5";
readonly data_message: "6";
};
declare const parseAssistantStreamPart: (line: string) => AssistantStreamPartType;
declare function formatAssistantStreamPart<T extends keyof AssistantStreamPartValueType>(type: T, value: AssistantStreamPartValueType[T]): AssistantStreamString;
declare const getOriginalFetch$1: () => typeof fetch;
declare function callChatApi({ api, body, streamProtocol, credentials, headers, abortController, restoreMessagesOnFailure, onResponse, onUpdate, onFinish, onToolCall, generateId, fetch, lastMessage, requestType, }: {
api: string;
body: Record<string, any>;
streamProtocol: 'data' | 'text' | undefined;
credentials: RequestCredentials | undefined;
headers: HeadersInit | undefined;
abortController: (() => AbortController | null) | undefined;
restoreMessagesOnFailure: () => void;
onResponse: ((response: Response) => void | Promise<void>) | undefined;
onUpdate: (options: {
message: UIMessage;
data: JSONValue[] | undefined;
replaceLastMessage: boolean;
}) => void;
onFinish: UseChatOptions['onFinish'];
onToolCall: UseChatOptions['onToolCall'];
generateId: IdGenerator;
fetch: ReturnType<typeof getOriginalFetch$1> | undefined;
lastMessage: UIMessage | undefined;
requestType?: 'generate' | 'resume';
}): Promise<void>;
declare const getOriginalFetch: () => typeof fetch;
declare function callCompletionApi({ api, prompt, credentials, headers, body, streamProtocol, setCompletion, setLoading, setError, setAbortController, onResponse, onFinish, onError, onData, fetch, }: {
api: string;
prompt: string;
credentials: RequestCredentials | undefined;
headers: HeadersInit | undefined;
body: Record<string, any>;
streamProtocol: 'data' | 'text' | undefined;
setCompletion: (completion: string) => void;
setLoading: (loading: boolean) => void;
setError: (error: Error | undefined) => void;
setAbortController: (abortController: AbortController | null) => void;
onResponse: ((response: Response) => void | Promise<void>) | undefined;
onFinish: ((prompt: string, completion: string) => void) | undefined;
onError: ((error: Error) => void) | undefined;
onData: ((data: JSONValue[]) => void) | undefined;
fetch: ReturnType<typeof getOriginalFetch> | undefined;
}): Promise<string | null | undefined>;
type DataStreamString = `${(typeof DataStreamStringPrefixes)[keyof typeof DataStreamStringPrefixes]}:${string}\n`;
interface DataStreamPart<CODE extends string, NAME extends string, TYPE> {
code: CODE;
name: NAME;
parse: (value: JSONValue) => {
type: NAME;
value: TYPE;
};
}
declare const dataStreamParts: readonly [DataStreamPart<"0", "text", string>, DataStreamPart<"2", "data", JSONValue[]>, DataStreamPart<"3", "error", string>, DataStreamPart<"8", "message_annotations", JSONValue[]>, DataStreamPart<"9", "tool_call", ToolCall<string, any>>, DataStreamPart<"a", "tool_result", Omit<ToolResult<string, any, any>, "args" | "toolName">>, DataStreamPart<"b", "tool_call_streaming_start", {
toolCallId: string;
toolName: string;
}>, DataStreamPart<"c", "tool_call_delta", {
toolCallId: string;
argsTextDelta: string;
}>, DataStreamPart<"d", "finish_message", {
finishReason: LanguageModelV1FinishReason;
usage?: {
promptTokens: number;
completionTokens: number;
};
}>, DataStreamPart<"e", "finish_step", {
isContinued: boolean;
finishReason: LanguageModelV1FinishReason;
usage?: {
promptTokens: number;
completionTokens: number;
};
}>, DataStreamPart<"f", "start_step", {
messageId: string;
}>, DataStreamPart<"g", "reasoning", string>, DataStreamPart<"h", "source", LanguageModelV1Source>, DataStreamPart<"i", "redacted_reasoning", {
data: string;
}>, DataStreamPart<"j", "reasoning_signature", {
signature: string;
}>, DataStreamPart<"k", "file", {
data: string;
mimeType: string;
}>];
type DataStreamParts = (typeof dataStreamParts)[number];
/**
* Maps the type of a stream part to its value type.
*/
type DataStreamPartValueType = {
[P in DataStreamParts as P['name']]: ReturnType<P['parse']>['value'];
};
type DataStreamPartType = ReturnType<DataStreamParts['parse']>;
/**
* The map of prefixes for data in the stream
*
* - 0: Text from the LLM response
* - 1: (OpenAI) function_call responses
* - 2: custom JSON added by the user using `Data`
* - 6: (OpenAI) tool_call responses
*
* Example:
* ```
* 0:Vercel
* 0:'s
* 0: AI
* 0: AI
* 0: SDK
* 0: is great
* 0:!
* 2: { "someJson": "value" }
* 1: {"function_call": {"name": "get_current_weather", "arguments": "{\\n\\"location\\": \\"Charlottesville, Virginia\\",\\n\\"format\\": \\"celsius\\"\\n}"}}
* 6: {"tool_call": {"id": "tool_0", "type": "function", "function": {"name": "get_current_weather", "arguments": "{\\n\\"location\\": \\"Charlottesville, Virginia\\",\\n\\"format\\": \\"celsius\\"\\n}"}}}
*```
*/
declare const DataStreamStringPrefixes: { [K in DataStreamParts["name"]]: (typeof dataStreamParts)[number]["code"]; };
/**
Parses a stream part from a string.
@param line The string to parse.
@returns The parsed stream part.
@throws An error if the string cannot be parsed.
*/
declare const parseDataStreamPart: (line: string) => DataStreamPartType;
/**
Prepends a string with a prefix from the `StreamChunkPrefixes`, JSON-ifies it,
and appends a new line.
It ensures type-safety for the part type and value.
*/
declare function formatDataStreamPart<T extends keyof DataStreamPartValueType>(type: T, value: DataStreamPartValueType[T]): DataStreamString;
/**
* Converts a data URL of type text/* to a text string.
*/
declare function getTextFromDataUrl(dataUrl: string): string;
/**
Create a type from an object with all keys and nested keys set to optional.
The helper supports normal objects and Zod schemas (which are resolved automatically).
It always recurses into arrays.
Adopted from [type-fest](https://github.com/sindresorhus/type-fest/tree/main) PartialDeep.
*/
type DeepPartial<T> = T extends z.ZodTypeAny ? DeepPartialInternal<z.infer<T>> : DeepPartialInternal<T>;
type DeepPartialInternal<T> = T extends null | undefined | string | number | boolean | symbol | bigint | void | Date | RegExp | ((...arguments_: any[]) => unknown) | (new (...arguments_: any[]) => unknown) ? T : T extends Map<infer KeyType, infer ValueType> ? PartialMap<KeyType, ValueType> : T extends Set<infer ItemType> ? PartialSet<ItemType> : T extends ReadonlyMap<infer KeyType, infer ValueType> ? PartialReadonlyMap<KeyType, ValueType> : T extends ReadonlySet<infer ItemType> ? PartialReadonlySet<ItemType> : T extends object ? T extends ReadonlyArray<infer ItemType> ? ItemType[] extends T ? readonly ItemType[] extends T ? ReadonlyArray<DeepPartialInternal<ItemType | undefined>> : Array<DeepPartialInternal<ItemType | undefined>> : PartialObject<T> : PartialObject<T> : unknown;
type PartialMap<KeyType, ValueType> = {} & Map<DeepPartialInternal<KeyType>, DeepPartialInternal<ValueType>>;
type PartialSet<T> = {} & Set<DeepPartialInternal<T>>;
type PartialReadonlyMap<KeyType, ValueType> = {} & ReadonlyMap<DeepPartialInternal<KeyType>, DeepPartialInternal<ValueType>>;
type PartialReadonlySet<T> = {} & ReadonlySet<DeepPartialInternal<T>>;
type PartialObject<ObjectType extends object> = {
[KeyType in keyof ObjectType]?: DeepPartialInternal<ObjectType[KeyType]>;
};
declare function extractMaxToolInvocationStep(toolInvocations: ToolInvocation[] | undefined): number | undefined;
declare function fillMessageParts(messages: Message[]): UIMessage[];
declare function getMessageParts(message: Message | CreateMessage | UIMessage): (TextUIPart | ReasoningUIPart | ToolInvocationUIPart | SourceUIPart | FileUIPart | StepStartUIPart)[];
/**
* Performs a deep-equal comparison of two parsed JSON objects.
*
* @param {any} obj1 - The first object to compare.
* @param {any} obj2 - The second object to compare.
* @returns {boolean} - Returns true if the two objects are deeply equal, false otherwise.
*/
declare function isDeepEqualData(obj1: any, obj2: any): boolean;
declare function parsePartialJson(jsonText: string | undefined): {
value: JSONValue$1 | undefined;
state: 'undefined-input' | 'successful-parse' | 'repaired-parse' | 'failed-parse';
};
declare function prepareAttachmentsForRequest(attachmentsFromOptions: FileList | Array<Attachment> | undefined): Promise<Attachment[]>;
declare function processAssistantStream({ stream, onTextPart, onErrorPart, onAssistantMessagePart, onAssistantControlDataPart, onDataMessagePart, }: {
stream: ReadableStream<Uint8Array>;
onTextPart?: (streamPart: (AssistantStreamPartType & {
type: 'text';
})['value']) => Promise<void> | void;
onErrorPart?: (streamPart: (AssistantStreamPartType & {
type: 'error';
})['value']) => Promise<void> | void;
onAssistantMessagePart?: (streamPart: (AssistantStreamPartType & {
type: 'assistant_message';
})['value']) => Promise<void> | void;
onAssistantControlDataPart?: (streamPart: (AssistantStreamPartType & {
type: 'assistant_control_data';
})['value']) => Promise<void> | void;
onDataMessagePart?: (streamPart: (AssistantStreamPartType & {
type: 'data_message';
})['value']) => Promise<void> | void;
}): Promise<void>;
declare function processDataStream({ stream, onTextPart, onReasoningPart, onReasoningSignaturePart, onRedactedReasoningPart, onSourcePart, onFilePart, onDataPart, onErrorPart, onToolCallStreamingStartPart, onToolCallDeltaPart, onToolCallPart, onToolResultPart, onMessageAnnotationsPart, onFinishMessagePart, onFinishStepPart, onStartStepPart, }: {
stream: ReadableStream<Uint8Array>;
onTextPart?: (streamPart: (DataStreamPartType & {
type: 'text';
})['value']) => Promise<void> | void;
onReasoningPart?: (streamPart: (DataStreamPartType & {
type: 'reasoning';
})['value']) => Promise<void> | void;
onReasoningSignaturePart?: (streamPart: (DataStreamPartType & {
type: 'reasoning_signature';
})['value']) => Promise<void> | void;
onRedactedReasoningPart?: (streamPart: (DataStreamPartType & {
type: 'redacted_reasoning';
})['value']) => Promise<void> | void;
onFilePart?: (streamPart: (DataStreamPartType & {
type: 'file';
})['value']) => Promise<void> | void;
onSourcePart?: (streamPart: (DataStreamPartType & {
type: 'source';
})['value']) => Promise<void> | void;
onDataPart?: (streamPart: (DataStreamPartType & {
type: 'data';
})['value']) => Promise<void> | void;
onErrorPart?: (streamPart: (DataStreamPartType & {
type: 'error';
})['value']) => Promise<void> | void;
onToolCallStreamingStartPart?: (streamPart: (DataStreamPartType & {
type: 'tool_call_streaming_start';
})['value']) => Promise<void> | void;
onToolCallDeltaPart?: (streamPart: (DataStreamPartType & {
type: 'tool_call_delta';
})['value']) => Promise<void> | void;
onToolCallPart?: (streamPart: (DataStreamPartType & {
type: 'tool_call';
})['value']) => Promise<void> | void;
onToolResultPart?: (streamPart: (DataStreamPartType & {
type: 'tool_result';
})['value']) => Promise<void> | void;
onMessageAnnotationsPart?: (streamPart: (DataStreamPartType & {
type: 'message_annotations';
})['value']) => Promise<void> | void;
onFinishMessagePart?: (streamPart: (DataStreamPartType & {
type: 'finish_message';
})['value']) => Promise<void> | void;
onFinishStepPart?: (streamPart: (DataStreamPartType & {
type: 'finish_step';
})['value']) => Promise<void> | void;
onStartStepPart?: (streamPart: (DataStreamPartType & {
type: 'start_step';
})['value']) => Promise<void> | void;
}): Promise<void>;
declare function processTextStream({ stream, onTextPart, }: {
stream: ReadableStream<Uint8Array>;
onTextPart: (chunk: string) => Promise<void> | void;
}): Promise<void>;
/**
* Used to mark schemas so we can support both Zod and custom schemas.
*/
declare const schemaSymbol: unique symbol;
type Schema<OBJECT = unknown> = Validator<OBJECT> & {
/**
* Used to mark schemas so we can support both Zod and custom schemas.
*/
[schemaSymbol]: true;
/**
* Schema type for inference.
*/
_type: OBJECT;
/**
* The JSON Schema for the schema. It is passed to the providers.
*/
readonly jsonSchema: JSONSchema7;
};
/**
* Create a schema using a JSON Schema.
*
* @param jsonSchema The JSON Schema for the schema.
* @param options.validate Optional. A validation function for the schema.
*/
declare function jsonSchema<OBJECT = unknown>(jsonSchema: JSONSchema7, { validate, }?: {
validate?: (value: unknown) => {
success: true;
value: OBJECT;
} | {
success: false;
error: Error;
};
}): Schema<OBJECT>;
declare function asSchema<OBJECT>(schema: z.Schema<OBJECT, z.ZodTypeDef, any> | Schema<OBJECT>): Schema<OBJECT>;
declare function shouldResubmitMessages({ originalMaxToolInvocationStep, originalMessageCount, maxSteps, messages, }: {
originalMaxToolInvocationStep: number | undefined;
originalMessageCount: number;
maxSteps: number;
messages: UIMessage[];
}): boolean;
/**
Check if the message is an assistant message with completed tool calls.
The last step of the message must have at least one tool invocation and
all tool invocations must have a result.
*/
declare function isAssistantMessageWithCompletedToolCalls(message: UIMessage): message is UIMessage & {
role: 'assistant';
};
/**
* Updates the result of a specific tool invocation in the last message of the given messages array.
*
* @param {object} params - The parameters object.
* @param {UIMessage[]} params.messages - An array of messages, from which the last one is updated.
* @param {string} params.toolCallId - The unique identifier for the tool invocation to update.
* @param {unknown} params.toolResult - The result object to attach to the tool invocation.
* @returns {void} This function does not return anything.
*/
declare function updateToolCallResult({ messages, toolCallId, toolResult: result, }: {
messages: UIMessage[];
toolCallId: string;
toolResult: unknown;
}): void;
declare function zodSchema<OBJECT>(zodSchema: z.Schema<OBJECT, z.ZodTypeDef, any>, options?: {
/**
* Enables support for references in the schema.
* This is required for recursive schemas, e.g. with `z.lazy`.
* However, not all language models and providers support such references.
* Defaults to `false`.
*/
useReferences?: boolean;
}): Schema<OBJECT>;
export { type AssistantMessage, type AssistantStatus, type AssistantStreamPart, type AssistantStreamString, type Attachment, type ChatRequest, type ChatRequestOptions, type CreateMessage, type DataMessage, type DataStreamPart, type DataStreamString, type DeepPartial, type FileUIPart, type IdGenerator, type JSONValue, type Message, type ReasoningUIPart, type RequestOptions, type Schema, type SourceUIPart, type StepStartUIPart, type TextUIPart, type ToolInvocation, type ToolInvocationUIPart, type UIMessage, type UseAssistantOptions, type UseChatOptions, type UseCompletionOptions, asSchema, callChatApi, callCompletionApi, extractMaxToolInvocationStep, fillMessageParts, formatAssistantStreamPart, formatDataStreamPart, getMessageParts, getTextFromDataUrl, isAssistantMessageWithCompletedToolCalls, isDeepEqualData, jsonSchema, parseAssistantStreamPart, parseDataStreamPart, parsePartialJson, prepareAttachmentsForRequest, processAssistantStream, processDataStream, processTextStream, shouldResubmitMessages, updateToolCallResult, zodSchema };

View File

@@ -0,0 +1,820 @@
import { LanguageModelV1Source, LanguageModelV1FinishReason, JSONValue as JSONValue$1 } from '@ai-sdk/provider';
import { FetchFunction, ToolCall, ToolResult, Validator } from '@ai-sdk/provider-utils';
export { generateId } from '@ai-sdk/provider-utils';
import { z } from 'zod';
import { JSONSchema7 } from 'json-schema';
/**
Represents the number of tokens used in a prompt and completion.
*/
type LanguageModelUsage = {
/**
The number of tokens used in the prompt.
*/
promptTokens: number;
/**
The number of tokens used in the completion.
*/
completionTokens: number;
/**
The total number of tokens used (promptTokens + completionTokens).
*/
totalTokens: number;
};
type AssistantStatus = 'in_progress' | 'awaiting_message';
type UseAssistantOptions = {
/**
* The API endpoint that accepts a `{ threadId: string | null; message: string; }` object and returns an `AssistantResponse` stream.
* The threadId refers to an existing thread with messages (or is `null` to create a new thread).
* The message is the next message that should be appended to the thread and sent to the assistant.
*/
api: string;
/**
* An optional string that represents the ID of an existing thread.
* If not provided, a new thread will be created.
*/
threadId?: string;
/**
* An optional literal that sets the mode of credentials to be used on the request.
* Defaults to "same-origin".
*/
credentials?: RequestCredentials;
/**
* An optional object of headers to be passed to the API endpoint.
*/
headers?: Record<string, string> | Headers;
/**
* An optional, additional body object to be passed to the API endpoint.
*/
body?: object;
/**
* An optional callback that will be called when the assistant encounters an error.
*/
onError?: (error: Error) => void;
/**
Custom fetch implementation. You can use it as a middleware to intercept requests,
or to provide a custom fetch implementation for e.g. testing.
*/
fetch?: FetchFunction;
};
type IdGenerator = () => string;
/**
Tool invocations are either tool calls or tool results. For each assistant tool call,
there is one tool invocation. While the call is in progress, the invocation is a tool call.
Once the call is complete, the invocation is a tool result.
The step is used to track how to map an assistant UI message with many tool invocations
back to a sequence of LLM assistant/tool result message pairs.
It is optional for backwards compatibility.
*/
type ToolInvocation = ({
state: 'partial-call';
step?: number;
} & ToolCall<string, any>) | ({
state: 'call';
step?: number;
} & ToolCall<string, any>) | ({
state: 'result';
step?: number;
} & ToolResult<string, any, any>);
/**
* An attachment that can be sent along with a message.
*/
interface Attachment {
/**
* The name of the attachment, usually the file name.
*/
name?: string;
/**
* A string indicating the [media type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Type).
* By default, it's extracted from the pathname's extension.
*/
contentType?: string;
/**
* The URL of the attachment. It can either be a URL to a hosted file or a [Data URL](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs).
*/
url: string;
}
/**
* AI SDK UI Messages. They are used in the client and to communicate between the frontend and the API routes.
*/
interface Message {
/**
A unique identifier for the message.
*/
id: string;
/**
The timestamp of the message.
*/
createdAt?: Date;
/**
Text content of the message. Use parts when possible.
*/
content: string;
/**
Reasoning for the message.
@deprecated Use `parts` instead.
*/
reasoning?: string;
/**
* Additional attachments to be sent along with the message.
*/
experimental_attachments?: Attachment[];
/**
The 'data' role is deprecated.
*/
role: 'system' | 'user' | 'assistant' | 'data';
/**
For data messages.
@deprecated Data messages will be removed.
*/
data?: JSONValue;
/**
* Additional message-specific information added on the server via StreamData
*/
annotations?: JSONValue[] | undefined;
/**
Tool invocations (that can be tool calls or tool results, depending on whether or not the invocation has finished)
that the assistant made as part of this message.
@deprecated Use `parts` instead.
*/
toolInvocations?: Array<ToolInvocation>;
/**
* The parts of the message. Use this for rendering the message in the UI.
*
* Assistant messages can have text, reasoning and tool invocation parts.
* User messages can have text parts.
*/
parts?: Array<TextUIPart | ReasoningUIPart | ToolInvocationUIPart | SourceUIPart | FileUIPart | StepStartUIPart>;
}
type UIMessage = Message & {
/**
* The parts of the message. Use this for rendering the message in the UI.
*
* Assistant messages can have text, reasoning and tool invocation parts.
* User messages can have text parts.
*/
parts: Array<TextUIPart | ReasoningUIPart | ToolInvocationUIPart | SourceUIPart | FileUIPart | StepStartUIPart>;
};
/**
* A text part of a message.
*/
type TextUIPart = {
type: 'text';
/**
* The text content.
*/
text: string;
};
/**
* A reasoning part of a message.
*/
type ReasoningUIPart = {
type: 'reasoning';
/**
* The reasoning text.
*/
reasoning: string;
details: Array<{
type: 'text';
text: string;
signature?: string;
} | {
type: 'redacted';
data: string;
}>;
};
/**
* A tool invocation part of a message.
*/
type ToolInvocationUIPart = {
type: 'tool-invocation';
/**
* The tool invocation.
*/
toolInvocation: ToolInvocation;
};
/**
* A source part of a message.
*/
type SourceUIPart = {
type: 'source';
/**
* The source.
*/
source: LanguageModelV1Source;
};
/**
* A file part of a message.
*/
type FileUIPart = {
type: 'file';
mimeType: string;
data: string;
};
/**
* A step boundary part of a message.
*/
type StepStartUIPart = {
type: 'step-start';
};
type CreateMessage = Omit<Message, 'id'> & {
id?: Message['id'];
};
type ChatRequest = {
/**
An optional object of headers to be passed to the API endpoint.
*/
headers?: Record<string, string> | Headers;
/**
An optional object to be passed to the API endpoint.
*/
body?: object;
/**
The messages of the chat.
*/
messages: Message[];
/**
Additional data to be sent to the server.
*/
data?: JSONValue;
};
type RequestOptions = {
/**
An optional object of headers to be passed to the API endpoint.
*/
headers?: Record<string, string> | Headers;
/**
An optional object to be passed to the API endpoint.
*/
body?: object;
};
type ChatRequestOptions = {
/**
Additional headers that should be to be passed to the API endpoint.
*/
headers?: Record<string, string> | Headers;
/**
Additional body JSON properties that should be sent to the API endpoint.
*/
body?: object;
/**
Additional data to be sent to the API endpoint.
*/
data?: JSONValue;
/**
* Additional files to be sent to the server.
*/
experimental_attachments?: FileList | Array<Attachment>;
/**
* Allow submitting an empty message. Defaults to `false`.
*/
allowEmptySubmit?: boolean;
};
type UseChatOptions = {
/**
Keeps the last message when an error happens. Defaults to `true`.
@deprecated This option will be removed in the next major release.
*/
keepLastMessageOnError?: boolean;
/**
* The API endpoint that accepts a `{ messages: Message[] }` object and returns
* a stream of tokens of the AI chat response. Defaults to `/api/chat`.
*/
api?: string;
/**
* A unique identifier for the chat. If not provided, a random one will be
* generated. When provided, the `useChat` hook with the same `id` will
* have shared states across components.
*/
id?: string;
/**
* Initial messages of the chat. Useful to load an existing chat history.
*/
initialMessages?: Message[];
/**
* Initial input of the chat.
*/
initialInput?: string;
/**
Optional callback function that is invoked when a tool call is received.
Intended for automatic client-side tool execution.
You can optionally return a result for the tool call,
either synchronously or asynchronously.
*/
onToolCall?: ({ toolCall, }: {
toolCall: ToolCall<string, unknown>;
}) => void | Promise<unknown> | unknown;
/**
* Callback function to be called when the API response is received.
*/
onResponse?: (response: Response) => void | Promise<void>;
/**
* Optional callback function that is called when the assistant message is finished streaming.
*
* @param message The message that was streamed.
* @param options.usage The token usage of the message.
* @param options.finishReason The finish reason of the message.
*/
onFinish?: (message: Message, options: {
usage: LanguageModelUsage;
finishReason: LanguageModelV1FinishReason;
}) => void;
/**
* Callback function to be called when an error is encountered.
*/
onError?: (error: Error) => void;
/**
* A way to provide a function that is going to be used for ids for messages and the chat.
* If not provided the default AI SDK `generateId` is used.
*/
generateId?: IdGenerator;
/**
* The credentials mode to be used for the fetch request.
* Possible values are: 'omit', 'same-origin', 'include'.
* Defaults to 'same-origin'.
*/
credentials?: RequestCredentials;
/**
* HTTP headers to be sent with the API request.
*/
headers?: Record<string, string> | Headers;
/**
* Extra body object to be sent with the API request.
* @example
* Send a `sessionId` to the API along with the messages.
* ```js
* useChat({
* body: {
* sessionId: '123',
* }
* })
* ```
*/
body?: object;
/**
* Whether to send extra message fields such as `message.id` and `message.createdAt` to the API.
* Defaults to `false`. When set to `true`, the API endpoint might need to
* handle the extra fields before forwarding the request to the AI service.
*/
sendExtraMessageFields?: boolean;
/**
Streaming protocol that is used. Defaults to `data`.
*/
streamProtocol?: 'data' | 'text';
/**
Custom fetch implementation. You can use it as a middleware to intercept requests,
or to provide a custom fetch implementation for e.g. testing.
*/
fetch?: FetchFunction;
};
type UseCompletionOptions = {
/**
* The API endpoint that accepts a `{ prompt: string }` object and returns
* a stream of tokens of the AI completion response. Defaults to `/api/completion`.
*/
api?: string;
/**
* An unique identifier for the chat. If not provided, a random one will be
* generated. When provided, the `useChat` hook with the same `id` will
* have shared states across components.
*/
id?: string;
/**
* Initial prompt input of the completion.
*/
initialInput?: string;
/**
* Initial completion result. Useful to load an existing history.
*/
initialCompletion?: string;
/**
* Callback function to be called when the API response is received.
*/
onResponse?: (response: Response) => void | Promise<void>;
/**
* Callback function to be called when the completion is finished streaming.
*/
onFinish?: (prompt: string, completion: string) => void;
/**
* Callback function to be called when an error is encountered.
*/
onError?: (error: Error) => void;
/**
* The credentials mode to be used for the fetch request.
* Possible values are: 'omit', 'same-origin', 'include'.
* Defaults to 'same-origin'.
*/
credentials?: RequestCredentials;
/**
* HTTP headers to be sent with the API request.
*/
headers?: Record<string, string> | Headers;
/**
* Extra body object to be sent with the API request.
* @example
* Send a `sessionId` to the API along with the prompt.
* ```js
* useChat({
* body: {
* sessionId: '123',
* }
* })
* ```
*/
body?: object;
/**
Streaming protocol that is used. Defaults to `data`.
*/
streamProtocol?: 'data' | 'text';
/**
Custom fetch implementation. You can use it as a middleware to intercept requests,
or to provide a custom fetch implementation for e.g. testing.
*/
fetch?: FetchFunction;
};
/**
A JSON value can be a string, number, boolean, object, array, or null.
JSON values can be serialized and deserialized by the JSON.stringify and JSON.parse methods.
*/
type JSONValue = null | string | number | boolean | {
[value: string]: JSONValue;
} | Array<JSONValue>;
type AssistantMessage = {
id: string;
role: 'assistant';
content: Array<{
type: 'text';
text: {
value: string;
};
}>;
};
type DataMessage = {
id?: string;
role: 'data';
data: JSONValue;
};
type AssistantStreamString = `${(typeof StreamStringPrefixes)[keyof typeof StreamStringPrefixes]}:${string}\n`;
interface AssistantStreamPart<CODE extends string, NAME extends string, TYPE> {
code: CODE;
name: NAME;
parse: (value: JSONValue) => {
type: NAME;
value: TYPE;
};
}
declare const textStreamPart: AssistantStreamPart<'0', 'text', string>;
declare const errorStreamPart: AssistantStreamPart<'3', 'error', string>;
declare const assistantMessageStreamPart: AssistantStreamPart<'4', 'assistant_message', AssistantMessage>;
declare const assistantControlDataStreamPart: AssistantStreamPart<'5', 'assistant_control_data', {
threadId: string;
messageId: string;
}>;
declare const dataMessageStreamPart: AssistantStreamPart<'6', 'data_message', DataMessage>;
type AssistantStreamParts = typeof textStreamPart | typeof errorStreamPart | typeof assistantMessageStreamPart | typeof assistantControlDataStreamPart | typeof dataMessageStreamPart;
type AssistantStreamPartValueType = {
[P in AssistantStreamParts as P['name']]: ReturnType<P['parse']>['value'];
};
type AssistantStreamPartType = ReturnType<typeof textStreamPart.parse> | ReturnType<typeof errorStreamPart.parse> | ReturnType<typeof assistantMessageStreamPart.parse> | ReturnType<typeof assistantControlDataStreamPart.parse> | ReturnType<typeof dataMessageStreamPart.parse>;
declare const StreamStringPrefixes: {
readonly text: "0";
readonly error: "3";
readonly assistant_message: "4";
readonly assistant_control_data: "5";
readonly data_message: "6";
};
declare const parseAssistantStreamPart: (line: string) => AssistantStreamPartType;
declare function formatAssistantStreamPart<T extends keyof AssistantStreamPartValueType>(type: T, value: AssistantStreamPartValueType[T]): AssistantStreamString;
declare const getOriginalFetch$1: () => typeof fetch;
declare function callChatApi({ api, body, streamProtocol, credentials, headers, abortController, restoreMessagesOnFailure, onResponse, onUpdate, onFinish, onToolCall, generateId, fetch, lastMessage, requestType, }: {
api: string;
body: Record<string, any>;
streamProtocol: 'data' | 'text' | undefined;
credentials: RequestCredentials | undefined;
headers: HeadersInit | undefined;
abortController: (() => AbortController | null) | undefined;
restoreMessagesOnFailure: () => void;
onResponse: ((response: Response) => void | Promise<void>) | undefined;
onUpdate: (options: {
message: UIMessage;
data: JSONValue[] | undefined;
replaceLastMessage: boolean;
}) => void;
onFinish: UseChatOptions['onFinish'];
onToolCall: UseChatOptions['onToolCall'];
generateId: IdGenerator;
fetch: ReturnType<typeof getOriginalFetch$1> | undefined;
lastMessage: UIMessage | undefined;
requestType?: 'generate' | 'resume';
}): Promise<void>;
declare const getOriginalFetch: () => typeof fetch;
declare function callCompletionApi({ api, prompt, credentials, headers, body, streamProtocol, setCompletion, setLoading, setError, setAbortController, onResponse, onFinish, onError, onData, fetch, }: {
api: string;
prompt: string;
credentials: RequestCredentials | undefined;
headers: HeadersInit | undefined;
body: Record<string, any>;
streamProtocol: 'data' | 'text' | undefined;
setCompletion: (completion: string) => void;
setLoading: (loading: boolean) => void;
setError: (error: Error | undefined) => void;
setAbortController: (abortController: AbortController | null) => void;
onResponse: ((response: Response) => void | Promise<void>) | undefined;
onFinish: ((prompt: string, completion: string) => void) | undefined;
onError: ((error: Error) => void) | undefined;
onData: ((data: JSONValue[]) => void) | undefined;
fetch: ReturnType<typeof getOriginalFetch> | undefined;
}): Promise<string | null | undefined>;
type DataStreamString = `${(typeof DataStreamStringPrefixes)[keyof typeof DataStreamStringPrefixes]}:${string}\n`;
interface DataStreamPart<CODE extends string, NAME extends string, TYPE> {
code: CODE;
name: NAME;
parse: (value: JSONValue) => {
type: NAME;
value: TYPE;
};
}
declare const dataStreamParts: readonly [DataStreamPart<"0", "text", string>, DataStreamPart<"2", "data", JSONValue[]>, DataStreamPart<"3", "error", string>, DataStreamPart<"8", "message_annotations", JSONValue[]>, DataStreamPart<"9", "tool_call", ToolCall<string, any>>, DataStreamPart<"a", "tool_result", Omit<ToolResult<string, any, any>, "args" | "toolName">>, DataStreamPart<"b", "tool_call_streaming_start", {
toolCallId: string;
toolName: string;
}>, DataStreamPart<"c", "tool_call_delta", {
toolCallId: string;
argsTextDelta: string;
}>, DataStreamPart<"d", "finish_message", {
finishReason: LanguageModelV1FinishReason;
usage?: {
promptTokens: number;
completionTokens: number;
};
}>, DataStreamPart<"e", "finish_step", {
isContinued: boolean;
finishReason: LanguageModelV1FinishReason;
usage?: {
promptTokens: number;
completionTokens: number;
};
}>, DataStreamPart<"f", "start_step", {
messageId: string;
}>, DataStreamPart<"g", "reasoning", string>, DataStreamPart<"h", "source", LanguageModelV1Source>, DataStreamPart<"i", "redacted_reasoning", {
data: string;
}>, DataStreamPart<"j", "reasoning_signature", {
signature: string;
}>, DataStreamPart<"k", "file", {
data: string;
mimeType: string;
}>];
type DataStreamParts = (typeof dataStreamParts)[number];
/**
* Maps the type of a stream part to its value type.
*/
type DataStreamPartValueType = {
[P in DataStreamParts as P['name']]: ReturnType<P['parse']>['value'];
};
type DataStreamPartType = ReturnType<DataStreamParts['parse']>;
/**
* The map of prefixes for data in the stream
*
* - 0: Text from the LLM response
* - 1: (OpenAI) function_call responses
* - 2: custom JSON added by the user using `Data`
* - 6: (OpenAI) tool_call responses
*
* Example:
* ```
* 0:Vercel
* 0:'s
* 0: AI
* 0: AI
* 0: SDK
* 0: is great
* 0:!
* 2: { "someJson": "value" }
* 1: {"function_call": {"name": "get_current_weather", "arguments": "{\\n\\"location\\": \\"Charlottesville, Virginia\\",\\n\\"format\\": \\"celsius\\"\\n}"}}
* 6: {"tool_call": {"id": "tool_0", "type": "function", "function": {"name": "get_current_weather", "arguments": "{\\n\\"location\\": \\"Charlottesville, Virginia\\",\\n\\"format\\": \\"celsius\\"\\n}"}}}
*```
*/
declare const DataStreamStringPrefixes: { [K in DataStreamParts["name"]]: (typeof dataStreamParts)[number]["code"]; };
/**
Parses a stream part from a string.
@param line The string to parse.
@returns The parsed stream part.
@throws An error if the string cannot be parsed.
*/
declare const parseDataStreamPart: (line: string) => DataStreamPartType;
/**
Prepends a string with a prefix from the `StreamChunkPrefixes`, JSON-ifies it,
and appends a new line.
It ensures type-safety for the part type and value.
*/
declare function formatDataStreamPart<T extends keyof DataStreamPartValueType>(type: T, value: DataStreamPartValueType[T]): DataStreamString;
/**
* Converts a data URL of type text/* to a text string.
*/
declare function getTextFromDataUrl(dataUrl: string): string;
/**
Create a type from an object with all keys and nested keys set to optional.
The helper supports normal objects and Zod schemas (which are resolved automatically).
It always recurses into arrays.
Adopted from [type-fest](https://github.com/sindresorhus/type-fest/tree/main) PartialDeep.
*/
type DeepPartial<T> = T extends z.ZodTypeAny ? DeepPartialInternal<z.infer<T>> : DeepPartialInternal<T>;
type DeepPartialInternal<T> = T extends null | undefined | string | number | boolean | symbol | bigint | void | Date | RegExp | ((...arguments_: any[]) => unknown) | (new (...arguments_: any[]) => unknown) ? T : T extends Map<infer KeyType, infer ValueType> ? PartialMap<KeyType, ValueType> : T extends Set<infer ItemType> ? PartialSet<ItemType> : T extends ReadonlyMap<infer KeyType, infer ValueType> ? PartialReadonlyMap<KeyType, ValueType> : T extends ReadonlySet<infer ItemType> ? PartialReadonlySet<ItemType> : T extends object ? T extends ReadonlyArray<infer ItemType> ? ItemType[] extends T ? readonly ItemType[] extends T ? ReadonlyArray<DeepPartialInternal<ItemType | undefined>> : Array<DeepPartialInternal<ItemType | undefined>> : PartialObject<T> : PartialObject<T> : unknown;
type PartialMap<KeyType, ValueType> = {} & Map<DeepPartialInternal<KeyType>, DeepPartialInternal<ValueType>>;
type PartialSet<T> = {} & Set<DeepPartialInternal<T>>;
type PartialReadonlyMap<KeyType, ValueType> = {} & ReadonlyMap<DeepPartialInternal<KeyType>, DeepPartialInternal<ValueType>>;
type PartialReadonlySet<T> = {} & ReadonlySet<DeepPartialInternal<T>>;
type PartialObject<ObjectType extends object> = {
[KeyType in keyof ObjectType]?: DeepPartialInternal<ObjectType[KeyType]>;
};
declare function extractMaxToolInvocationStep(toolInvocations: ToolInvocation[] | undefined): number | undefined;
declare function fillMessageParts(messages: Message[]): UIMessage[];
declare function getMessageParts(message: Message | CreateMessage | UIMessage): (TextUIPart | ReasoningUIPart | ToolInvocationUIPart | SourceUIPart | FileUIPart | StepStartUIPart)[];
/**
* Performs a deep-equal comparison of two parsed JSON objects.
*
* @param {any} obj1 - The first object to compare.
* @param {any} obj2 - The second object to compare.
* @returns {boolean} - Returns true if the two objects are deeply equal, false otherwise.
*/
declare function isDeepEqualData(obj1: any, obj2: any): boolean;
declare function parsePartialJson(jsonText: string | undefined): {
value: JSONValue$1 | undefined;
state: 'undefined-input' | 'successful-parse' | 'repaired-parse' | 'failed-parse';
};
declare function prepareAttachmentsForRequest(attachmentsFromOptions: FileList | Array<Attachment> | undefined): Promise<Attachment[]>;
declare function processAssistantStream({ stream, onTextPart, onErrorPart, onAssistantMessagePart, onAssistantControlDataPart, onDataMessagePart, }: {
stream: ReadableStream<Uint8Array>;
onTextPart?: (streamPart: (AssistantStreamPartType & {
type: 'text';
})['value']) => Promise<void> | void;
onErrorPart?: (streamPart: (AssistantStreamPartType & {
type: 'error';
})['value']) => Promise<void> | void;
onAssistantMessagePart?: (streamPart: (AssistantStreamPartType & {
type: 'assistant_message';
})['value']) => Promise<void> | void;
onAssistantControlDataPart?: (streamPart: (AssistantStreamPartType & {
type: 'assistant_control_data';
})['value']) => Promise<void> | void;
onDataMessagePart?: (streamPart: (AssistantStreamPartType & {
type: 'data_message';
})['value']) => Promise<void> | void;
}): Promise<void>;
declare function processDataStream({ stream, onTextPart, onReasoningPart, onReasoningSignaturePart, onRedactedReasoningPart, onSourcePart, onFilePart, onDataPart, onErrorPart, onToolCallStreamingStartPart, onToolCallDeltaPart, onToolCallPart, onToolResultPart, onMessageAnnotationsPart, onFinishMessagePart, onFinishStepPart, onStartStepPart, }: {
stream: ReadableStream<Uint8Array>;
onTextPart?: (streamPart: (DataStreamPartType & {
type: 'text';
})['value']) => Promise<void> | void;
onReasoningPart?: (streamPart: (DataStreamPartType & {
type: 'reasoning';
})['value']) => Promise<void> | void;
onReasoningSignaturePart?: (streamPart: (DataStreamPartType & {
type: 'reasoning_signature';
})['value']) => Promise<void> | void;
onRedactedReasoningPart?: (streamPart: (DataStreamPartType & {
type: 'redacted_reasoning';
})['value']) => Promise<void> | void;
onFilePart?: (streamPart: (DataStreamPartType & {
type: 'file';
})['value']) => Promise<void> | void;
onSourcePart?: (streamPart: (DataStreamPartType & {
type: 'source';
})['value']) => Promise<void> | void;
onDataPart?: (streamPart: (DataStreamPartType & {
type: 'data';
})['value']) => Promise<void> | void;
onErrorPart?: (streamPart: (DataStreamPartType & {
type: 'error';
})['value']) => Promise<void> | void;
onToolCallStreamingStartPart?: (streamPart: (DataStreamPartType & {
type: 'tool_call_streaming_start';
})['value']) => Promise<void> | void;
onToolCallDeltaPart?: (streamPart: (DataStreamPartType & {
type: 'tool_call_delta';
})['value']) => Promise<void> | void;
onToolCallPart?: (streamPart: (DataStreamPartType & {
type: 'tool_call';
})['value']) => Promise<void> | void;
onToolResultPart?: (streamPart: (DataStreamPartType & {
type: 'tool_result';
})['value']) => Promise<void> | void;
onMessageAnnotationsPart?: (streamPart: (DataStreamPartType & {
type: 'message_annotations';
})['value']) => Promise<void> | void;
onFinishMessagePart?: (streamPart: (DataStreamPartType & {
type: 'finish_message';
})['value']) => Promise<void> | void;
onFinishStepPart?: (streamPart: (DataStreamPartType & {
type: 'finish_step';
})['value']) => Promise<void> | void;
onStartStepPart?: (streamPart: (DataStreamPartType & {
type: 'start_step';
})['value']) => Promise<void> | void;
}): Promise<void>;
declare function processTextStream({ stream, onTextPart, }: {
stream: ReadableStream<Uint8Array>;
onTextPart: (chunk: string) => Promise<void> | void;
}): Promise<void>;
/**
* Used to mark schemas so we can support both Zod and custom schemas.
*/
declare const schemaSymbol: unique symbol;
type Schema<OBJECT = unknown> = Validator<OBJECT> & {
/**
* Used to mark schemas so we can support both Zod and custom schemas.
*/
[schemaSymbol]: true;
/**
* Schema type for inference.
*/
_type: OBJECT;
/**
* The JSON Schema for the schema. It is passed to the providers.
*/
readonly jsonSchema: JSONSchema7;
};
/**
* Create a schema using a JSON Schema.
*
* @param jsonSchema The JSON Schema for the schema.
* @param options.validate Optional. A validation function for the schema.
*/
declare function jsonSchema<OBJECT = unknown>(jsonSchema: JSONSchema7, { validate, }?: {
validate?: (value: unknown) => {
success: true;
value: OBJECT;
} | {
success: false;
error: Error;
};
}): Schema<OBJECT>;
declare function asSchema<OBJECT>(schema: z.Schema<OBJECT, z.ZodTypeDef, any> | Schema<OBJECT>): Schema<OBJECT>;
declare function shouldResubmitMessages({ originalMaxToolInvocationStep, originalMessageCount, maxSteps, messages, }: {
originalMaxToolInvocationStep: number | undefined;
originalMessageCount: number;
maxSteps: number;
messages: UIMessage[];
}): boolean;
/**
Check if the message is an assistant message with completed tool calls.
The last step of the message must have at least one tool invocation and
all tool invocations must have a result.
*/
declare function isAssistantMessageWithCompletedToolCalls(message: UIMessage): message is UIMessage & {
role: 'assistant';
};
/**
* Updates the result of a specific tool invocation in the last message of the given messages array.
*
* @param {object} params - The parameters object.
* @param {UIMessage[]} params.messages - An array of messages, from which the last one is updated.
* @param {string} params.toolCallId - The unique identifier for the tool invocation to update.
* @param {unknown} params.toolResult - The result object to attach to the tool invocation.
* @returns {void} This function does not return anything.
*/
declare function updateToolCallResult({ messages, toolCallId, toolResult: result, }: {
messages: UIMessage[];
toolCallId: string;
toolResult: unknown;
}): void;
declare function zodSchema<OBJECT>(zodSchema: z.Schema<OBJECT, z.ZodTypeDef, any>, options?: {
/**
* Enables support for references in the schema.
* This is required for recursive schemas, e.g. with `z.lazy`.
* However, not all language models and providers support such references.
* Defaults to `false`.
*/
useReferences?: boolean;
}): Schema<OBJECT>;
export { type AssistantMessage, type AssistantStatus, type AssistantStreamPart, type AssistantStreamString, type Attachment, type ChatRequest, type ChatRequestOptions, type CreateMessage, type DataMessage, type DataStreamPart, type DataStreamString, type DeepPartial, type FileUIPart, type IdGenerator, type JSONValue, type Message, type ReasoningUIPart, type RequestOptions, type Schema, type SourceUIPart, type StepStartUIPart, type TextUIPart, type ToolInvocation, type ToolInvocationUIPart, type UIMessage, type UseAssistantOptions, type UseChatOptions, type UseCompletionOptions, asSchema, callChatApi, callCompletionApi, extractMaxToolInvocationStep, fillMessageParts, formatAssistantStreamPart, formatDataStreamPart, getMessageParts, getTextFromDataUrl, isAssistantMessageWithCompletedToolCalls, isDeepEqualData, jsonSchema, parseAssistantStreamPart, parseDataStreamPart, parsePartialJson, prepareAttachmentsForRequest, processAssistantStream, processDataStream, processTextStream, shouldResubmitMessages, updateToolCallResult, zodSchema };

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,73 @@
{
"name": "@ai-sdk/ui-utils",
"version": "1.2.11",
"license": "Apache-2.0",
"sideEffects": false,
"main": "./dist/index.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"dist/**/*",
"test/dist/**/*",
"CHANGELOG.md"
],
"exports": {
"./package.json": "./package.json",
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.mjs",
"require": "./dist/index.js"
},
"./test": {
"types": "./test/dist/index.d.ts",
"import": "./test/dist/index.mjs",
"module": "./test/dist/index.mjs",
"require": "./test/dist/index.js"
}
},
"dependencies": {
"@ai-sdk/provider": "1.1.3",
"@ai-sdk/provider-utils": "2.2.8",
"zod-to-json-schema": "^3.24.1"
},
"devDependencies": {
"@types/json-schema": "7.0.15",
"@types/node": "20.17.24",
"@types/react": "^18",
"tsup": "^8",
"typescript": "5.6.3",
"zod": "3.23.8",
"@vercel/ai-tsconfig": "0.0.0"
},
"peerDependencies": {
"zod": "^3.23.8"
},
"engines": {
"node": ">=18"
},
"publishConfig": {
"access": "public"
},
"homepage": "https://ai-sdk.dev/docs",
"repository": {
"type": "git",
"url": "git+https://github.com/vercel/ai.git"
},
"bugs": {
"url": "https://github.com/vercel/ai/issues"
},
"keywords": [
"ai"
],
"scripts": {
"build": "tsup",
"build:watch": "tsup --watch",
"clean": "rm -rf dist && rm -rf test/dist",
"lint": "eslint \"./**/*.ts*\"",
"type-check": "tsc --noEmit",
"prettier-check": "prettier --check \"./**/*.ts*\"",
"test": "pnpm test:node && pnpm test:edge",
"test:edge": "vitest --config vitest.edge.config.js --run",
"test:node": "vitest --config vitest.node.config.js --run"
}
}

View File

@@ -0,0 +1,24 @@
declare function mockFetchTextStream({ url, chunks, }: {
url: string;
chunks: string[];
}): void;
declare function mockFetchDataStream({ url, chunks, maxCalls, }: {
url: string;
chunks: string[];
maxCalls?: number;
}): {
requestBody: Promise<unknown>;
};
declare function mockFetchDataStreamWithGenerator({ url, chunkGenerator, maxCalls, }: {
url: string;
chunkGenerator: AsyncGenerator<Uint8Array, void, unknown>;
maxCalls?: number;
}): {
requestBody: Promise<unknown>;
};
declare function mockFetchError({ statusCode, errorMessage, }: {
statusCode: number;
errorMessage: string;
}): void;
export { mockFetchDataStream, mockFetchDataStreamWithGenerator, mockFetchError, mockFetchTextStream };

View File

@@ -0,0 +1,24 @@
declare function mockFetchTextStream({ url, chunks, }: {
url: string;
chunks: string[];
}): void;
declare function mockFetchDataStream({ url, chunks, maxCalls, }: {
url: string;
chunks: string[];
maxCalls?: number;
}): {
requestBody: Promise<unknown>;
};
declare function mockFetchDataStreamWithGenerator({ url, chunkGenerator, maxCalls, }: {
url: string;
chunkGenerator: AsyncGenerator<Uint8Array, void, unknown>;
maxCalls?: number;
}): {
requestBody: Promise<unknown>;
};
declare function mockFetchError({ statusCode, errorMessage, }: {
statusCode: number;
errorMessage: string;
}): void;
export { mockFetchDataStream, mockFetchDataStreamWithGenerator, mockFetchError, mockFetchTextStream };

View File

@@ -0,0 +1,150 @@
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/test/index.ts
var test_exports = {};
__export(test_exports, {
mockFetchDataStream: () => mockFetchDataStream,
mockFetchDataStreamWithGenerator: () => mockFetchDataStreamWithGenerator,
mockFetchError: () => mockFetchError,
mockFetchTextStream: () => mockFetchTextStream
});
module.exports = __toCommonJS(test_exports);
// src/test/mock-fetch.ts
var import_vitest = require("vitest");
function mockFetchTextStream({
url,
chunks
}) {
import_vitest.vi.spyOn(global, "fetch").mockImplementation(async () => {
function* generateChunks() {
for (const chunk of chunks) {
yield new TextEncoder().encode(chunk);
}
}
const chunkGenerator = generateChunks();
return {
url,
ok: true,
status: 200,
bodyUsed: false,
headers: /* @__PURE__ */ new Map(),
body: {
getReader() {
return {
read() {
return Promise.resolve(chunkGenerator.next());
},
releaseLock() {
},
cancel() {
}
};
}
}
};
});
}
function mockFetchDataStream({
url,
chunks,
maxCalls
}) {
async function* generateChunks() {
const encoder = new TextEncoder();
for (const chunk of chunks) {
yield encoder.encode(chunk);
}
}
return mockFetchDataStreamWithGenerator({
url,
chunkGenerator: generateChunks(),
maxCalls
});
}
function mockFetchDataStreamWithGenerator({
url,
chunkGenerator,
maxCalls
}) {
let requestBodyResolve;
const requestBodyPromise = new Promise((resolve) => {
requestBodyResolve = resolve;
});
let callCount = 0;
import_vitest.vi.spyOn(global, "fetch").mockImplementation(async (url2, init) => {
if (maxCalls !== void 0 && ++callCount >= maxCalls) {
throw new Error("Too many calls");
}
requestBodyResolve == null ? void 0 : requestBodyResolve(init.body);
return {
url: url2,
ok: true,
status: 200,
bodyUsed: false,
body: new ReadableStream({
async start(controller) {
for await (const chunk of chunkGenerator) {
controller.enqueue(chunk);
}
controller.close();
}
})
};
});
return {
requestBody: requestBodyPromise
};
}
function mockFetchError({
statusCode,
errorMessage
}) {
import_vitest.vi.spyOn(global, "fetch").mockImplementation(async () => {
return {
url: "https://example.com/api/chat",
ok: false,
status: statusCode,
bodyUsed: false,
body: {
getReader() {
return {
read() {
return Promise.resolve(errorMessage);
},
releaseLock() {
},
cancel() {
}
};
}
},
text: () => Promise.resolve(errorMessage)
};
});
}
// Annotate the CommonJS export names for ESM import in node:
0 && (module.exports = {
mockFetchDataStream,
mockFetchDataStreamWithGenerator,
mockFetchError,
mockFetchTextStream
});
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../src/test/index.ts","../../src/test/mock-fetch.ts"],"sourcesContent":["export * from './mock-fetch';\n","import { fail } from 'node:assert';\nimport { vi } from 'vitest';\n\nexport function mockFetchTextStream({\n url,\n chunks,\n}: {\n url: string;\n chunks: string[];\n}) {\n vi.spyOn(global, 'fetch').mockImplementation(async () => {\n function* generateChunks() {\n for (const chunk of chunks) {\n yield new TextEncoder().encode(chunk);\n }\n }\n\n const chunkGenerator = generateChunks();\n\n return {\n url,\n ok: true,\n status: 200,\n bodyUsed: false,\n headers: new Map() as any as Headers,\n body: {\n getReader() {\n return {\n read() {\n return Promise.resolve(chunkGenerator.next());\n },\n releaseLock() {},\n cancel() {},\n };\n },\n },\n } as unknown as Response;\n });\n}\n\nexport function mockFetchDataStream({\n url,\n chunks,\n maxCalls,\n}: {\n url: string;\n chunks: string[];\n maxCalls?: number;\n}) {\n async function* generateChunks() {\n const encoder = new TextEncoder();\n for (const chunk of chunks) {\n yield encoder.encode(chunk);\n }\n }\n\n return mockFetchDataStreamWithGenerator({\n url,\n chunkGenerator: generateChunks(),\n maxCalls,\n });\n}\n\nexport function mockFetchDataStreamWithGenerator({\n url,\n chunkGenerator,\n maxCalls,\n}: {\n url: string;\n chunkGenerator: AsyncGenerator<Uint8Array, void, unknown>;\n maxCalls?: number;\n}) {\n let requestBodyResolve: ((value?: unknown) => void) | undefined;\n const requestBodyPromise = new Promise(resolve => {\n requestBodyResolve = resolve;\n });\n\n let callCount = 0;\n\n vi.spyOn(global, 'fetch').mockImplementation(async (url, init) => {\n if (maxCalls !== undefined && ++callCount >= maxCalls) {\n throw new Error('Too many calls');\n }\n\n requestBodyResolve?.(init!.body as string);\n\n return {\n url,\n ok: true,\n status: 200,\n bodyUsed: false,\n body: new ReadableStream({\n async start(controller) {\n for await (const chunk of chunkGenerator) {\n controller.enqueue(chunk);\n }\n controller.close();\n },\n }),\n } as Response;\n });\n\n return {\n requestBody: requestBodyPromise,\n };\n}\n\nexport function mockFetchError({\n statusCode,\n errorMessage,\n}: {\n statusCode: number;\n errorMessage: string;\n}) {\n vi.spyOn(global, 'fetch').mockImplementation(async () => {\n return {\n url: 'https://example.com/api/chat',\n ok: false,\n status: statusCode,\n bodyUsed: false,\n body: {\n getReader() {\n return {\n read() {\n return Promise.resolve(errorMessage);\n },\n releaseLock() {},\n cancel() {},\n };\n },\n },\n text: () => Promise.resolve(errorMessage),\n } as unknown as Response;\n });\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACCA,oBAAmB;AAEZ,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AACF,GAGG;AACD,mBAAG,MAAM,QAAQ,OAAO,EAAE,mBAAmB,YAAY;AACvD,cAAU,iBAAiB;AACzB,iBAAW,SAAS,QAAQ;AAC1B,cAAM,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,MACtC;AAAA,IACF;AAEA,UAAM,iBAAiB,eAAe;AAEtC,WAAO;AAAA,MACL;AAAA,MACA,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,SAAS,oBAAI,IAAI;AAAA,MACjB,MAAM;AAAA,QACJ,YAAY;AACV,iBAAO;AAAA,YACL,OAAO;AACL,qBAAO,QAAQ,QAAQ,eAAe,KAAK,CAAC;AAAA,YAC9C;AAAA,YACA,cAAc;AAAA,YAAC;AAAA,YACf,SAAS;AAAA,YAAC;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,kBAAgB,iBAAiB;AAC/B,UAAM,UAAU,IAAI,YAAY;AAChC,eAAW,SAAS,QAAQ;AAC1B,YAAM,QAAQ,OAAO,KAAK;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO,iCAAiC;AAAA,IACtC;AAAA,IACA,gBAAgB,eAAe;AAAA,IAC/B;AAAA,EACF,CAAC;AACH;AAEO,SAAS,iCAAiC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,MAAI;AACJ,QAAM,qBAAqB,IAAI,QAAQ,aAAW;AAChD,yBAAqB;AAAA,EACvB,CAAC;AAED,MAAI,YAAY;AAEhB,mBAAG,MAAM,QAAQ,OAAO,EAAE,mBAAmB,OAAOA,MAAK,SAAS;AAChE,QAAI,aAAa,UAAa,EAAE,aAAa,UAAU;AACrD,YAAM,IAAI,MAAM,gBAAgB;AAAA,IAClC;AAEA,6DAAqB,KAAM;AAE3B,WAAO;AAAA,MACL,KAAAA;AAAA,MACA,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM,IAAI,eAAe;AAAA,QACvB,MAAM,MAAM,YAAY;AACtB,2BAAiB,SAAS,gBAAgB;AACxC,uBAAW,QAAQ,KAAK;AAAA,UAC1B;AACA,qBAAW,MAAM;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,aAAa;AAAA,EACf;AACF;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AACF,GAGG;AACD,mBAAG,MAAM,QAAQ,OAAO,EAAE,mBAAmB,YAAY;AACvD,WAAO;AAAA,MACL,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,QACJ,YAAY;AACV,iBAAO;AAAA,YACL,OAAO;AACL,qBAAO,QAAQ,QAAQ,YAAY;AAAA,YACrC;AAAA,YACA,cAAc;AAAA,YAAC;AAAA,YACf,SAAS;AAAA,YAAC;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,MAAM,QAAQ,QAAQ,YAAY;AAAA,IAC1C;AAAA,EACF,CAAC;AACH;","names":["url"]}

View File

@@ -0,0 +1,120 @@
// src/test/mock-fetch.ts
import { vi } from "vitest";
function mockFetchTextStream({
url,
chunks
}) {
vi.spyOn(global, "fetch").mockImplementation(async () => {
function* generateChunks() {
for (const chunk of chunks) {
yield new TextEncoder().encode(chunk);
}
}
const chunkGenerator = generateChunks();
return {
url,
ok: true,
status: 200,
bodyUsed: false,
headers: /* @__PURE__ */ new Map(),
body: {
getReader() {
return {
read() {
return Promise.resolve(chunkGenerator.next());
},
releaseLock() {
},
cancel() {
}
};
}
}
};
});
}
function mockFetchDataStream({
url,
chunks,
maxCalls
}) {
async function* generateChunks() {
const encoder = new TextEncoder();
for (const chunk of chunks) {
yield encoder.encode(chunk);
}
}
return mockFetchDataStreamWithGenerator({
url,
chunkGenerator: generateChunks(),
maxCalls
});
}
function mockFetchDataStreamWithGenerator({
url,
chunkGenerator,
maxCalls
}) {
let requestBodyResolve;
const requestBodyPromise = new Promise((resolve) => {
requestBodyResolve = resolve;
});
let callCount = 0;
vi.spyOn(global, "fetch").mockImplementation(async (url2, init) => {
if (maxCalls !== void 0 && ++callCount >= maxCalls) {
throw new Error("Too many calls");
}
requestBodyResolve == null ? void 0 : requestBodyResolve(init.body);
return {
url: url2,
ok: true,
status: 200,
bodyUsed: false,
body: new ReadableStream({
async start(controller) {
for await (const chunk of chunkGenerator) {
controller.enqueue(chunk);
}
controller.close();
}
})
};
});
return {
requestBody: requestBodyPromise
};
}
function mockFetchError({
statusCode,
errorMessage
}) {
vi.spyOn(global, "fetch").mockImplementation(async () => {
return {
url: "https://example.com/api/chat",
ok: false,
status: statusCode,
bodyUsed: false,
body: {
getReader() {
return {
read() {
return Promise.resolve(errorMessage);
},
releaseLock() {
},
cancel() {
}
};
}
},
text: () => Promise.resolve(errorMessage)
};
});
}
export {
mockFetchDataStream,
mockFetchDataStreamWithGenerator,
mockFetchError,
mockFetchTextStream
};
//# sourceMappingURL=index.mjs.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../src/test/mock-fetch.ts"],"sourcesContent":["import { fail } from 'node:assert';\nimport { vi } from 'vitest';\n\nexport function mockFetchTextStream({\n url,\n chunks,\n}: {\n url: string;\n chunks: string[];\n}) {\n vi.spyOn(global, 'fetch').mockImplementation(async () => {\n function* generateChunks() {\n for (const chunk of chunks) {\n yield new TextEncoder().encode(chunk);\n }\n }\n\n const chunkGenerator = generateChunks();\n\n return {\n url,\n ok: true,\n status: 200,\n bodyUsed: false,\n headers: new Map() as any as Headers,\n body: {\n getReader() {\n return {\n read() {\n return Promise.resolve(chunkGenerator.next());\n },\n releaseLock() {},\n cancel() {},\n };\n },\n },\n } as unknown as Response;\n });\n}\n\nexport function mockFetchDataStream({\n url,\n chunks,\n maxCalls,\n}: {\n url: string;\n chunks: string[];\n maxCalls?: number;\n}) {\n async function* generateChunks() {\n const encoder = new TextEncoder();\n for (const chunk of chunks) {\n yield encoder.encode(chunk);\n }\n }\n\n return mockFetchDataStreamWithGenerator({\n url,\n chunkGenerator: generateChunks(),\n maxCalls,\n });\n}\n\nexport function mockFetchDataStreamWithGenerator({\n url,\n chunkGenerator,\n maxCalls,\n}: {\n url: string;\n chunkGenerator: AsyncGenerator<Uint8Array, void, unknown>;\n maxCalls?: number;\n}) {\n let requestBodyResolve: ((value?: unknown) => void) | undefined;\n const requestBodyPromise = new Promise(resolve => {\n requestBodyResolve = resolve;\n });\n\n let callCount = 0;\n\n vi.spyOn(global, 'fetch').mockImplementation(async (url, init) => {\n if (maxCalls !== undefined && ++callCount >= maxCalls) {\n throw new Error('Too many calls');\n }\n\n requestBodyResolve?.(init!.body as string);\n\n return {\n url,\n ok: true,\n status: 200,\n bodyUsed: false,\n body: new ReadableStream({\n async start(controller) {\n for await (const chunk of chunkGenerator) {\n controller.enqueue(chunk);\n }\n controller.close();\n },\n }),\n } as Response;\n });\n\n return {\n requestBody: requestBodyPromise,\n };\n}\n\nexport function mockFetchError({\n statusCode,\n errorMessage,\n}: {\n statusCode: number;\n errorMessage: string;\n}) {\n vi.spyOn(global, 'fetch').mockImplementation(async () => {\n return {\n url: 'https://example.com/api/chat',\n ok: false,\n status: statusCode,\n bodyUsed: false,\n body: {\n getReader() {\n return {\n read() {\n return Promise.resolve(errorMessage);\n },\n releaseLock() {},\n cancel() {},\n };\n },\n },\n text: () => Promise.resolve(errorMessage),\n } as unknown as Response;\n });\n}\n"],"mappings":";AACA,SAAS,UAAU;AAEZ,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AACF,GAGG;AACD,KAAG,MAAM,QAAQ,OAAO,EAAE,mBAAmB,YAAY;AACvD,cAAU,iBAAiB;AACzB,iBAAW,SAAS,QAAQ;AAC1B,cAAM,IAAI,YAAY,EAAE,OAAO,KAAK;AAAA,MACtC;AAAA,IACF;AAEA,UAAM,iBAAiB,eAAe;AAEtC,WAAO;AAAA,MACL;AAAA,MACA,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,SAAS,oBAAI,IAAI;AAAA,MACjB,MAAM;AAAA,QACJ,YAAY;AACV,iBAAO;AAAA,YACL,OAAO;AACL,qBAAO,QAAQ,QAAQ,eAAe,KAAK,CAAC;AAAA,YAC9C;AAAA,YACA,cAAc;AAAA,YAAC;AAAA,YACf,SAAS;AAAA,YAAC;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEO,SAAS,oBAAoB;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,kBAAgB,iBAAiB;AAC/B,UAAM,UAAU,IAAI,YAAY;AAChC,eAAW,SAAS,QAAQ;AAC1B,YAAM,QAAQ,OAAO,KAAK;AAAA,IAC5B;AAAA,EACF;AAEA,SAAO,iCAAiC;AAAA,IACtC;AAAA,IACA,gBAAgB,eAAe;AAAA,IAC/B;AAAA,EACF,CAAC;AACH;AAEO,SAAS,iCAAiC;AAAA,EAC/C;AAAA,EACA;AAAA,EACA;AACF,GAIG;AACD,MAAI;AACJ,QAAM,qBAAqB,IAAI,QAAQ,aAAW;AAChD,yBAAqB;AAAA,EACvB,CAAC;AAED,MAAI,YAAY;AAEhB,KAAG,MAAM,QAAQ,OAAO,EAAE,mBAAmB,OAAOA,MAAK,SAAS;AAChE,QAAI,aAAa,UAAa,EAAE,aAAa,UAAU;AACrD,YAAM,IAAI,MAAM,gBAAgB;AAAA,IAClC;AAEA,6DAAqB,KAAM;AAE3B,WAAO;AAAA,MACL,KAAAA;AAAA,MACA,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM,IAAI,eAAe;AAAA,QACvB,MAAM,MAAM,YAAY;AACtB,2BAAiB,SAAS,gBAAgB;AACxC,uBAAW,QAAQ,KAAK;AAAA,UAC1B;AACA,qBAAW,MAAM;AAAA,QACnB;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,aAAa;AAAA,EACf;AACF;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AACF,GAGG;AACD,KAAG,MAAM,QAAQ,OAAO,EAAE,mBAAmB,YAAY;AACvD,WAAO;AAAA,MACL,KAAK;AAAA,MACL,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,MAAM;AAAA,QACJ,YAAY;AACV,iBAAO;AAAA,YACL,OAAO;AACL,qBAAO,QAAQ,QAAQ,YAAY;AAAA,YACrC;AAAA,YACA,cAAc;AAAA,YAAC;AAAA,YACf,SAAS;AAAA,YAAC;AAAA,UACZ;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,MAAM,QAAQ,QAAQ,YAAY;AAAA,IAC1C;AAAA,EACF,CAAC;AACH;","names":["url"]}

View File

@@ -0,0 +1,201 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

View File

@@ -0,0 +1,116 @@
# OpenTelemetry API for JavaScript
<p align="center">
<strong>
<a href="https://open-telemetry.github.io/opentelemetry-js/modules/_opentelemetry_api.html">API Reference</a>
&nbsp;&nbsp;&bull;&nbsp;&nbsp;
<a href="https://opentelemetry.io/docs/instrumentation/js/">Documentation</a>
</br>
<a href="https://github.com/open-telemetry/opentelemetry-js/releases">
<img alt="NPM Release" src="https://img.shields.io/npm/v/@opentelemetry/api?color=brightgreen&logo=data%3Aimage%2Fpng%3Bbase64%2CiVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAACQAAAAAQAAAJAAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAABigAwAEAAAAAQAAABgAAAAA8A2UOAAAAAlwSFlzAAAWJQAAFiUBSVIk8AAAAVlpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IlhNUCBDb3JlIDUuNC4wIj4KICAgPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICAgICAgPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIKICAgICAgICAgICAgeG1sbnM6dGlmZj0iaHR0cDovL25zLmFkb2JlLmNvbS90aWZmLzEuMC8iPgogICAgICAgICA8dGlmZjpPcmllbnRhdGlvbj4xPC90aWZmOk9yaWVudGF0aW9uPgogICAgICA8L3JkZjpEZXNjcmlwdGlvbj4KICAgPC9yZGY6UkRGPgo8L3g6eG1wbWV0YT4KTMInWQAABK5JREFUSA2dVm1sFEUYfmd2b%2Ff2Pkqghn5eEQWKrRgjpkYgpoRCLC0oxV5apAiGUDEpJvwxEQ2raWPU%2BKf8INU%2FRtEedwTCR9tYPloxGNJYTTQUwYqJ1aNpaLH3sXu3t7vjvFevpSqt7eSyM%2B%2FczvM8877PzB3APBoLgoDLsNePF56LBwqa07EKlDGg84CcWsI4CEbhNnDpAd951lXE2NkiNknCCTLv4HtzZuvPm1C%2FIKv4oDNXqNDHragety2XVzjECZsJARuBMyRzJrh1O0gQwLXuxofxsPSj4hG8fMLQo7bl9JJD8XZfC1E5yWFOMtd07dvX5kDwg6%2B2%2B%2BChq8txHGtfPoAp0gOFmhYoNFkHjn2TNUmrwRdna7W1QSkU8hvbGk4uThLrapaiLA2E6QY4u%2FlS9ItHfvJkxYsTMVtnAJLipYIWtVrcdX%2B8%2Bb8IVnPl%2FR81prbuPZ1jpYw%2B0aEUGSkdFsgyBIaFTXCm6nyaxMtJ4n%2BTeDhJzGqZtQZcuYDgqDwDbqb0JF9oRpIG1Oea3bC1Y6N3x%2FWV8Zh83emhCs%2B%2BhlaghDw%2B8w5UlYKq2lU7Pl8IkvS9KDqXmKmEwdMppVPKwGSEilmyAwJhRwWcq7wYC6z4wZ1rrEoMWxecdOjZWXeAQClBcYDN3NwVwD9pGwqUSyQgclcmxpNJqCuwLmDh3WtvPqXdlt%2B6Oz70HPGDNSNBee%2FEOen%2BrGbEFqDENBPDbtdCp0ukPANmzO0QQJYUpyS5IJJI3Hqt4maS%2BEB3199ozm8EDU%2F6fVNU2dQpdx3ZnKzeFXyaUTiasEV%2FgZMzJMjr3Z%2BWvAdQ%2Bhs%2Fzw9savimxUntDSaBdZ2f%2BIdbm1rlNY8esFffBit9HtK5%2FMejsrJVxikOXlb1Ukir2X%2BRbdkd1KG2Ixfn2Ql4JRmELnYK9mEM8G36fAA3xEQ89fxXihC8q%2BsAKi9jhHxNqagY2hiaYgRCm0f0QP7H4Fp11LSXiuBY2aYFlh0DeDIVVFUJQn5rCnpiNI2gvLxHnASn9DIVHJJlm5rXvQAGEo4zvKq2w5G1NxENN7jrft1oxMdekETjxdH2Z3x%2BVTVYsPb%2BO0C%2F9%2FauN6v2hNZw5b2UOmSbG5%2FrkC3LBA%2B1PdxFxORjxpQ81GcxKc%2BybVjEBvUJvaGJ7p7n5A5KSwe4AzkasA%2BcrmzFtowoIVTiLjANm8GDsrWW35ScI3JY8Urv83tnkF8JR0yLvEt2hO%2F0qNyy3Jb3YKeHeHeLeOuVLRpNF%2Bpkf85OW7%2FzJxWdXsbsKBUk2TC0BCPwMq5Q%2FCPvaJFkNS%2F1l1qUPe%2BuH3oD59erYGI%2FY4sce6KaXYElAIOLt%2B0O3t2%2B%2FxJDF1XvOlWGC1W1B8VMszbGfOvT5qaRRAIFK3BCO164nZ0uYLH2YjNN8thXS2v2BK9gTfD7jHVxzHr4roOlEvYYz9QIz%2BVl%2FsLDXInsctFsXjqIRnO2ZO387lxmIboLDZCJ59KLFliNIgh9ipt6tLg9SihpRPDO1ia5byw7de1aCQmF5geOQtK509rzfdwxaKOIq%2B73AvwCC5%2F5fcV4vo3%2B3LpMdtWHh0ywsJC%2FZGoCb8%2F9D8F%2FifgLLl8S8QWfU8cAAAAASUVORK5CYII%3D">
</a>
</strong>
</p>
This package provides everything needed to interact with the OpenTelemetry API, including all TypeScript interfaces, enums, and no-op implementations. It is intended for use both on the server and in the browser.
The methods in this package perform no operations by default. This means they can be safely called by a library or end-user application whether there is an SDK registered or not. In order to generate and export telemetry data, you will also need an SDK such as the [OpenTelemetry JS SDK][opentelemetry-js].
## Tracing Quick Start
### You Will Need
- An application you wish to instrument
- [OpenTelemetry JS SDK][opentelemetry-js]
- Node.js >=8.5.0 (14+ is preferred) or an ECMAScript 5+ compatible browser
**Note:** ECMAScript 5+ compatibility is for this package only. Please refer to the documentation for the SDK you are using to determine its minimum ECMAScript version.
**Note for library authors:** Only your end users will need an OpenTelemetry SDK. If you wish to support OpenTelemetry in your library, you only need to use the OpenTelemetry API. For more information, please read the [tracing documentation][docs-tracing].
### Install Dependencies
```sh
npm install @opentelemetry/api @opentelemetry/sdk-trace-base
```
### Trace Your Application
In order to get started with tracing, you will need to first register an SDK. The SDK you are using may provide a convenience method which calls the registration methods for you, but if you would like to call them directly they are documented here: [SDK registration methods][docs-sdk-registration].
Once you have registered an SDK, you can start and end spans. A simple example of basic SDK registration and tracing a simple operation is below. The example should export spans to the console once per second. For more information, see the [tracing documentation][docs-tracing].
```javascript
const { trace } = require("@opentelemetry/api");
const { BasicTracerProvider, ConsoleSpanExporter, SimpleSpanProcessor } = require("@opentelemetry/sdk-trace-base");
// Create and register an SDK
const provider = new BasicTracerProvider();
provider.addSpanProcessor(new SimpleSpanProcessor(new ConsoleSpanExporter()));
trace.setGlobalTracerProvider(provider);
// Acquire a tracer from the global tracer provider which will be used to trace the application
const name = 'my-application-name';
const version = '0.1.0';
const tracer = trace.getTracer(name, version);
// Trace your application by creating spans
async function operation() {
const span = tracer.startSpan("do operation");
// mock some work by sleeping 1 second
await new Promise((resolve, reject) => {
setTimeout(resolve, 1000);
})
span.end();
}
async function main() {
while (true) {
await operation();
}
}
main();
```
## Version Compatibility
Because the npm installer and node module resolution algorithm could potentially allow two or more copies of any given package to exist within the same `node_modules` structure, the OpenTelemetry API takes advantage of a variable on the `global` object to store the global API. When an API method in the API package is called, it checks if this `global` API exists and proxies calls to it if and only if it is a compatible API version. This means if a package has a dependency on an OpenTelemetry API version which is not compatible with the API used by the end user, the package will receive a no-op implementation of the API.
## Upgrade Guidelines
### 0.21.0 to 1.0.0
No breaking changes
### 0.20.0 to 0.21.0
- [#78](https://github.com/open-telemetry/opentelemetry-js-api/issues/78) `api.context.bind` arguments reversed and `context` is now a required argument.
- [#46](https://github.com/open-telemetry/opentelemetry-js-api/issues/46) Noop classes and singletons are no longer exported. To create a noop span it is recommended to use `api.trace.wrapSpanContext` with `INVALID_SPAN_CONTEXT` instead of using the `NOOP_TRACER`.
### 1.0.0-rc.3 to 0.20.0
- Removing `TimedEvent` which was not part of spec
- `HttpBaggage` renamed to `HttpBaggagePropagator`
- [#45](https://github.com/open-telemetry/opentelemetry-js-api/pull/45) `Span#context` renamed to `Span#spanContext`
- [#47](https://github.com/open-telemetry/opentelemetry-js-api/pull/47) `getSpan`/`setSpan`/`getSpanContext`/`setSpanContext` moved to `trace` namespace
- [#55](https://github.com/open-telemetry/opentelemetry-js-api/pull/55) `getBaggage`/`setBaggage`/`createBaggage` moved to `propagation` namespace
## Useful links
- For more information on OpenTelemetry, visit: <https://opentelemetry.io/>
- For more about OpenTelemetry JavaScript: <https://github.com/open-telemetry/opentelemetry-js>
- For help or feedback on this project, join us in [GitHub Discussions][discussions-url]
## License
Apache 2.0 - See [LICENSE][license-url] for more information.
[opentelemetry-js]: https://github.com/open-telemetry/opentelemetry-js
[discussions-url]: https://github.com/open-telemetry/opentelemetry-js/discussions
[license-url]: https://github.com/open-telemetry/opentelemetry-js/blob/main/api/LICENSE
[docs-tracing]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/tracing.md
[docs-sdk-registration]: https://github.com/open-telemetry/opentelemetry-js/blob/main/doc/sdk-registration.md

View File

@@ -0,0 +1,41 @@
import { Context, ContextManager } from '../context/types';
/**
* Singleton object which represents the entry point to the OpenTelemetry Context API
*/
export declare class ContextAPI {
private static _instance?;
/** Empty private constructor prevents end users from constructing a new instance of the API */
private constructor();
/** Get the singleton instance of the Context API */
static getInstance(): ContextAPI;
/**
* Set the current context manager.
*
* @returns true if the context manager was successfully registered, else false
*/
setGlobalContextManager(contextManager: ContextManager): boolean;
/**
* Get the currently active context
*/
active(): Context;
/**
* Execute a function with an active context
*
* @param context context to be active during function execution
* @param fn function to execute in a context
* @param thisArg optional receiver to be used for calling fn
* @param args optional arguments forwarded to fn
*/
with<A extends unknown[], F extends (...args: A) => ReturnType<F>>(context: Context, fn: F, thisArg?: ThisParameterType<F>, ...args: A): ReturnType<F>;
/**
* Bind a context to a target function or event emitter
*
* @param context context to bind to the event emitter or function. Defaults to the currently active context
* @param target function or event emitter to bind
*/
bind<T>(context: Context, target: T): T;
private _getContextManager;
/** Disable and remove the global context manager */
disable(): void;
}
//# sourceMappingURL=context.d.ts.map

View File

@@ -0,0 +1,110 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import { NoopContextManager } from '../context/NoopContextManager';
import { getGlobal, registerGlobal, unregisterGlobal, } from '../internal/global-utils';
import { DiagAPI } from './diag';
var API_NAME = 'context';
var NOOP_CONTEXT_MANAGER = new NoopContextManager();
/**
* Singleton object which represents the entry point to the OpenTelemetry Context API
*/
var ContextAPI = /** @class */ (function () {
/** Empty private constructor prevents end users from constructing a new instance of the API */
function ContextAPI() {
}
/** Get the singleton instance of the Context API */
ContextAPI.getInstance = function () {
if (!this._instance) {
this._instance = new ContextAPI();
}
return this._instance;
};
/**
* Set the current context manager.
*
* @returns true if the context manager was successfully registered, else false
*/
ContextAPI.prototype.setGlobalContextManager = function (contextManager) {
return registerGlobal(API_NAME, contextManager, DiagAPI.instance());
};
/**
* Get the currently active context
*/
ContextAPI.prototype.active = function () {
return this._getContextManager().active();
};
/**
* Execute a function with an active context
*
* @param context context to be active during function execution
* @param fn function to execute in a context
* @param thisArg optional receiver to be used for calling fn
* @param args optional arguments forwarded to fn
*/
ContextAPI.prototype.with = function (context, fn, thisArg) {
var _a;
var args = [];
for (var _i = 3; _i < arguments.length; _i++) {
args[_i - 3] = arguments[_i];
}
return (_a = this._getContextManager()).with.apply(_a, __spreadArray([context, fn, thisArg], __read(args), false));
};
/**
* Bind a context to a target function or event emitter
*
* @param context context to bind to the event emitter or function. Defaults to the currently active context
* @param target function or event emitter to bind
*/
ContextAPI.prototype.bind = function (context, target) {
return this._getContextManager().bind(context, target);
};
ContextAPI.prototype._getContextManager = function () {
return getGlobal(API_NAME) || NOOP_CONTEXT_MANAGER;
};
/** Disable and remove the global context manager */
ContextAPI.prototype.disable = function () {
this._getContextManager().disable();
unregisterGlobal(API_NAME, DiagAPI.instance());
};
return ContextAPI;
}());
export { ContextAPI };
//# sourceMappingURL=context.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/api/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAEnE,OAAO,EACL,SAAS,EACT,cAAc,EACd,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,IAAM,QAAQ,GAAG,SAAS,CAAC;AAC3B,IAAM,oBAAoB,GAAG,IAAI,kBAAkB,EAAE,CAAC;AAEtD;;GAEG;AACH;IAGE,+FAA+F;IAC/F;IAAuB,CAAC;IAExB,oDAAoD;IACtC,sBAAW,GAAzB;QACE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,IAAI,CAAC,SAAS,GAAG,IAAI,UAAU,EAAE,CAAC;SACnC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACI,4CAAuB,GAA9B,UAA+B,cAA8B;QAC3D,OAAO,cAAc,CAAC,QAAQ,EAAE,cAAc,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACtE,CAAC;IAED;;OAEG;IACI,2BAAM,GAAb;QACE,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC,MAAM,EAAE,CAAC;IAC5C,CAAC;IAED;;;;;;;OAOG;IACI,yBAAI,GAAX,UACE,OAAgB,EAChB,EAAK,EACL,OAA8B;;QAC9B,cAAU;aAAV,UAAU,EAAV,qBAAU,EAAV,IAAU;YAAV,6BAAU;;QAEV,OAAO,CAAA,KAAA,IAAI,CAAC,kBAAkB,EAAE,CAAA,CAAC,IAAI,0BAAC,OAAO,EAAE,EAAE,EAAE,OAAO,UAAK,IAAI,WAAE;IACvE,CAAC;IAED;;;;;OAKG;IACI,yBAAI,GAAX,UAAe,OAAgB,EAAE,MAAS;QACxC,OAAO,IAAI,CAAC,kBAAkB,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IACzD,CAAC;IAEO,uCAAkB,GAA1B;QACE,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,oBAAoB,CAAC;IACrD,CAAC;IAED,oDAAoD;IAC7C,4BAAO,GAAd;QACE,IAAI,CAAC,kBAAkB,EAAE,CAAC,OAAO,EAAE,CAAC;QACpC,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACjD,CAAC;IACH,iBAAC;AAAD,CAAC,AAnED,IAmEC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { NoopContextManager } from '../context/NoopContextManager';\nimport { Context, ContextManager } from '../context/types';\nimport {\n getGlobal,\n registerGlobal,\n unregisterGlobal,\n} from '../internal/global-utils';\nimport { DiagAPI } from './diag';\n\nconst API_NAME = 'context';\nconst NOOP_CONTEXT_MANAGER = new NoopContextManager();\n\n/**\n * Singleton object which represents the entry point to the OpenTelemetry Context API\n */\nexport class ContextAPI {\n private static _instance?: ContextAPI;\n\n /** Empty private constructor prevents end users from constructing a new instance of the API */\n private constructor() {}\n\n /** Get the singleton instance of the Context API */\n public static getInstance(): ContextAPI {\n if (!this._instance) {\n this._instance = new ContextAPI();\n }\n\n return this._instance;\n }\n\n /**\n * Set the current context manager.\n *\n * @returns true if the context manager was successfully registered, else false\n */\n public setGlobalContextManager(contextManager: ContextManager): boolean {\n return registerGlobal(API_NAME, contextManager, DiagAPI.instance());\n }\n\n /**\n * Get the currently active context\n */\n public active(): Context {\n return this._getContextManager().active();\n }\n\n /**\n * Execute a function with an active context\n *\n * @param context context to be active during function execution\n * @param fn function to execute in a context\n * @param thisArg optional receiver to be used for calling fn\n * @param args optional arguments forwarded to fn\n */\n public with<A extends unknown[], F extends (...args: A) => ReturnType<F>>(\n context: Context,\n fn: F,\n thisArg?: ThisParameterType<F>,\n ...args: A\n ): ReturnType<F> {\n return this._getContextManager().with(context, fn, thisArg, ...args);\n }\n\n /**\n * Bind a context to a target function or event emitter\n *\n * @param context context to bind to the event emitter or function. Defaults to the currently active context\n * @param target function or event emitter to bind\n */\n public bind<T>(context: Context, target: T): T {\n return this._getContextManager().bind(context, target);\n }\n\n private _getContextManager(): ContextManager {\n return getGlobal(API_NAME) || NOOP_CONTEXT_MANAGER;\n }\n\n /** Disable and remove the global context manager */\n public disable() {\n this._getContextManager().disable();\n unregisterGlobal(API_NAME, DiagAPI.instance());\n }\n}\n"]}

View File

@@ -0,0 +1,30 @@
import { ComponentLoggerOptions, DiagLogFunction, DiagLogger, DiagLoggerApi } from '../diag/types';
/**
* Singleton object which represents the entry point to the OpenTelemetry internal
* diagnostic API
*/
export declare class DiagAPI implements DiagLogger, DiagLoggerApi {
private static _instance?;
/** Get the singleton instance of the DiagAPI API */
static instance(): DiagAPI;
/**
* Private internal constructor
* @private
*/
private constructor();
setLogger: DiagLoggerApi['setLogger'];
/**
*
*/
createComponentLogger: (options: ComponentLoggerOptions) => DiagLogger;
verbose: DiagLogFunction;
debug: DiagLogFunction;
info: DiagLogFunction;
warn: DiagLogFunction;
error: DiagLogFunction;
/**
* Unregister the global logger and return to Noop
*/
disable: () => void;
}
//# sourceMappingURL=diag.d.ts.map

View File

@@ -0,0 +1,121 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
if (ar || !(i in from)) {
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
ar[i] = from[i];
}
}
return to.concat(ar || Array.prototype.slice.call(from));
};
import { DiagComponentLogger } from '../diag/ComponentLogger';
import { createLogLevelDiagLogger } from '../diag/internal/logLevelLogger';
import { DiagLogLevel, } from '../diag/types';
import { getGlobal, registerGlobal, unregisterGlobal, } from '../internal/global-utils';
var API_NAME = 'diag';
/**
* Singleton object which represents the entry point to the OpenTelemetry internal
* diagnostic API
*/
var DiagAPI = /** @class */ (function () {
/**
* Private internal constructor
* @private
*/
function DiagAPI() {
function _logProxy(funcName) {
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var logger = getGlobal('diag');
// shortcut if logger not set
if (!logger)
return;
return logger[funcName].apply(logger, __spreadArray([], __read(args), false));
};
}
// Using self local variable for minification purposes as 'this' cannot be minified
var self = this;
// DiagAPI specific functions
var setLogger = function (logger, optionsOrLogLevel) {
var _a, _b, _c;
if (optionsOrLogLevel === void 0) { optionsOrLogLevel = { logLevel: DiagLogLevel.INFO }; }
if (logger === self) {
// There isn't much we can do here.
// Logging to the console might break the user application.
// Try to log to self. If a logger was previously registered it will receive the log.
var err = new Error('Cannot use diag as the logger for itself. Please use a DiagLogger implementation like ConsoleDiagLogger or a custom implementation');
self.error((_a = err.stack) !== null && _a !== void 0 ? _a : err.message);
return false;
}
if (typeof optionsOrLogLevel === 'number') {
optionsOrLogLevel = {
logLevel: optionsOrLogLevel,
};
}
var oldLogger = getGlobal('diag');
var newLogger = createLogLevelDiagLogger((_b = optionsOrLogLevel.logLevel) !== null && _b !== void 0 ? _b : DiagLogLevel.INFO, logger);
// There already is an logger registered. We'll let it know before overwriting it.
if (oldLogger && !optionsOrLogLevel.suppressOverrideMessage) {
var stack = (_c = new Error().stack) !== null && _c !== void 0 ? _c : '<failed to generate stacktrace>';
oldLogger.warn("Current logger will be overwritten from " + stack);
newLogger.warn("Current logger will overwrite one already registered from " + stack);
}
return registerGlobal('diag', newLogger, self, true);
};
self.setLogger = setLogger;
self.disable = function () {
unregisterGlobal(API_NAME, self);
};
self.createComponentLogger = function (options) {
return new DiagComponentLogger(options);
};
self.verbose = _logProxy('verbose');
self.debug = _logProxy('debug');
self.info = _logProxy('info');
self.warn = _logProxy('warn');
self.error = _logProxy('error');
}
/** Get the singleton instance of the DiagAPI API */
DiagAPI.instance = function () {
if (!this._instance) {
this._instance = new DiagAPI();
}
return this._instance;
};
return DiagAPI;
}());
export { DiagAPI };
//# sourceMappingURL=diag.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,28 @@
import { Meter, MeterOptions } from '../metrics/Meter';
import { MeterProvider } from '../metrics/MeterProvider';
/**
* Singleton object which represents the entry point to the OpenTelemetry Metrics API
*/
export declare class MetricsAPI {
private static _instance?;
/** Empty private constructor prevents end users from constructing a new instance of the API */
private constructor();
/** Get the singleton instance of the Metrics API */
static getInstance(): MetricsAPI;
/**
* Set the current global meter provider.
* Returns true if the meter provider was successfully registered, else false.
*/
setGlobalMeterProvider(provider: MeterProvider): boolean;
/**
* Returns the global meter provider.
*/
getMeterProvider(): MeterProvider;
/**
* Returns a meter from the global meter provider.
*/
getMeter(name: string, version?: string, options?: MeterOptions): Meter;
/** Remove the global meter provider */
disable(): void;
}
//# sourceMappingURL=metrics.d.ts.map

View File

@@ -0,0 +1,60 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { NOOP_METER_PROVIDER } from '../metrics/NoopMeterProvider';
import { getGlobal, registerGlobal, unregisterGlobal, } from '../internal/global-utils';
import { DiagAPI } from './diag';
var API_NAME = 'metrics';
/**
* Singleton object which represents the entry point to the OpenTelemetry Metrics API
*/
var MetricsAPI = /** @class */ (function () {
/** Empty private constructor prevents end users from constructing a new instance of the API */
function MetricsAPI() {
}
/** Get the singleton instance of the Metrics API */
MetricsAPI.getInstance = function () {
if (!this._instance) {
this._instance = new MetricsAPI();
}
return this._instance;
};
/**
* Set the current global meter provider.
* Returns true if the meter provider was successfully registered, else false.
*/
MetricsAPI.prototype.setGlobalMeterProvider = function (provider) {
return registerGlobal(API_NAME, provider, DiagAPI.instance());
};
/**
* Returns the global meter provider.
*/
MetricsAPI.prototype.getMeterProvider = function () {
return getGlobal(API_NAME) || NOOP_METER_PROVIDER;
};
/**
* Returns a meter from the global meter provider.
*/
MetricsAPI.prototype.getMeter = function (name, version, options) {
return this.getMeterProvider().getMeter(name, version, options);
};
/** Remove the global meter provider */
MetricsAPI.prototype.disable = function () {
unregisterGlobal(API_NAME, DiagAPI.instance());
};
return MetricsAPI;
}());
export { MetricsAPI };
//# sourceMappingURL=metrics.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"metrics.js","sourceRoot":"","sources":["../../../src/api/metrics.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EACL,SAAS,EACT,cAAc,EACd,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,IAAM,QAAQ,GAAG,SAAS,CAAC;AAE3B;;GAEG;AACH;IAGE,+FAA+F;IAC/F;IAAuB,CAAC;IAExB,oDAAoD;IACtC,sBAAW,GAAzB;QACE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,IAAI,CAAC,SAAS,GAAG,IAAI,UAAU,EAAE,CAAC;SACnC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;OAGG;IACI,2CAAsB,GAA7B,UAA8B,QAAuB;QACnD,OAAO,cAAc,CAAC,QAAQ,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IAChE,CAAC;IAED;;OAEG;IACI,qCAAgB,GAAvB;QACE,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,mBAAmB,CAAC;IACpD,CAAC;IAED;;OAEG;IACI,6BAAQ,GAAf,UACE,IAAY,EACZ,OAAgB,EAChB,OAAsB;QAEtB,OAAO,IAAI,CAAC,gBAAgB,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAClE,CAAC;IAED,uCAAuC;IAChC,4BAAO,GAAd;QACE,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;IACjD,CAAC;IACH,iBAAC;AAAD,CAAC,AA7CD,IA6CC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { Meter, MeterOptions } from '../metrics/Meter';\nimport { MeterProvider } from '../metrics/MeterProvider';\nimport { NOOP_METER_PROVIDER } from '../metrics/NoopMeterProvider';\nimport {\n getGlobal,\n registerGlobal,\n unregisterGlobal,\n} from '../internal/global-utils';\nimport { DiagAPI } from './diag';\n\nconst API_NAME = 'metrics';\n\n/**\n * Singleton object which represents the entry point to the OpenTelemetry Metrics API\n */\nexport class MetricsAPI {\n private static _instance?: MetricsAPI;\n\n /** Empty private constructor prevents end users from constructing a new instance of the API */\n private constructor() {}\n\n /** Get the singleton instance of the Metrics API */\n public static getInstance(): MetricsAPI {\n if (!this._instance) {\n this._instance = new MetricsAPI();\n }\n\n return this._instance;\n }\n\n /**\n * Set the current global meter provider.\n * Returns true if the meter provider was successfully registered, else false.\n */\n public setGlobalMeterProvider(provider: MeterProvider): boolean {\n return registerGlobal(API_NAME, provider, DiagAPI.instance());\n }\n\n /**\n * Returns the global meter provider.\n */\n public getMeterProvider(): MeterProvider {\n return getGlobal(API_NAME) || NOOP_METER_PROVIDER;\n }\n\n /**\n * Returns a meter from the global meter provider.\n */\n public getMeter(\n name: string,\n version?: string,\n options?: MeterOptions\n ): Meter {\n return this.getMeterProvider().getMeter(name, version, options);\n }\n\n /** Remove the global meter provider */\n public disable(): void {\n unregisterGlobal(API_NAME, DiagAPI.instance());\n }\n}\n"]}

View File

@@ -0,0 +1,49 @@
import { Context } from '../context/types';
import { TextMapGetter, TextMapPropagator, TextMapSetter } from '../propagation/TextMapPropagator';
import { getBaggage, getActiveBaggage, setBaggage, deleteBaggage } from '../baggage/context-helpers';
import { createBaggage } from '../baggage/utils';
/**
* Singleton object which represents the entry point to the OpenTelemetry Propagation API
*/
export declare class PropagationAPI {
private static _instance?;
/** Empty private constructor prevents end users from constructing a new instance of the API */
private constructor();
/** Get the singleton instance of the Propagator API */
static getInstance(): PropagationAPI;
/**
* Set the current propagator.
*
* @returns true if the propagator was successfully registered, else false
*/
setGlobalPropagator(propagator: TextMapPropagator): boolean;
/**
* Inject context into a carrier to be propagated inter-process
*
* @param context Context carrying tracing data to inject
* @param carrier carrier to inject context into
* @param setter Function used to set values on the carrier
*/
inject<Carrier>(context: Context, carrier: Carrier, setter?: TextMapSetter<Carrier>): void;
/**
* Extract context from a carrier
*
* @param context Context which the newly created context will inherit from
* @param carrier Carrier to extract context from
* @param getter Function used to extract keys from a carrier
*/
extract<Carrier>(context: Context, carrier: Carrier, getter?: TextMapGetter<Carrier>): Context;
/**
* Return a list of all fields which may be used by the propagator.
*/
fields(): string[];
/** Remove the global propagator */
disable(): void;
createBaggage: typeof createBaggage;
getBaggage: typeof getBaggage;
getActiveBaggage: typeof getActiveBaggage;
setBaggage: typeof setBaggage;
deleteBaggage: typeof deleteBaggage;
private _getGlobalPropagator;
}
//# sourceMappingURL=propagation.d.ts.map

View File

@@ -0,0 +1,89 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getGlobal, registerGlobal, unregisterGlobal, } from '../internal/global-utils';
import { NoopTextMapPropagator } from '../propagation/NoopTextMapPropagator';
import { defaultTextMapGetter, defaultTextMapSetter, } from '../propagation/TextMapPropagator';
import { getBaggage, getActiveBaggage, setBaggage, deleteBaggage, } from '../baggage/context-helpers';
import { createBaggage } from '../baggage/utils';
import { DiagAPI } from './diag';
var API_NAME = 'propagation';
var NOOP_TEXT_MAP_PROPAGATOR = new NoopTextMapPropagator();
/**
* Singleton object which represents the entry point to the OpenTelemetry Propagation API
*/
var PropagationAPI = /** @class */ (function () {
/** Empty private constructor prevents end users from constructing a new instance of the API */
function PropagationAPI() {
this.createBaggage = createBaggage;
this.getBaggage = getBaggage;
this.getActiveBaggage = getActiveBaggage;
this.setBaggage = setBaggage;
this.deleteBaggage = deleteBaggage;
}
/** Get the singleton instance of the Propagator API */
PropagationAPI.getInstance = function () {
if (!this._instance) {
this._instance = new PropagationAPI();
}
return this._instance;
};
/**
* Set the current propagator.
*
* @returns true if the propagator was successfully registered, else false
*/
PropagationAPI.prototype.setGlobalPropagator = function (propagator) {
return registerGlobal(API_NAME, propagator, DiagAPI.instance());
};
/**
* Inject context into a carrier to be propagated inter-process
*
* @param context Context carrying tracing data to inject
* @param carrier carrier to inject context into
* @param setter Function used to set values on the carrier
*/
PropagationAPI.prototype.inject = function (context, carrier, setter) {
if (setter === void 0) { setter = defaultTextMapSetter; }
return this._getGlobalPropagator().inject(context, carrier, setter);
};
/**
* Extract context from a carrier
*
* @param context Context which the newly created context will inherit from
* @param carrier Carrier to extract context from
* @param getter Function used to extract keys from a carrier
*/
PropagationAPI.prototype.extract = function (context, carrier, getter) {
if (getter === void 0) { getter = defaultTextMapGetter; }
return this._getGlobalPropagator().extract(context, carrier, getter);
};
/**
* Return a list of all fields which may be used by the propagator.
*/
PropagationAPI.prototype.fields = function () {
return this._getGlobalPropagator().fields();
};
/** Remove the global propagator */
PropagationAPI.prototype.disable = function () {
unregisterGlobal(API_NAME, DiagAPI.instance());
};
PropagationAPI.prototype._getGlobalPropagator = function () {
return getGlobal(API_NAME) || NOOP_TEXT_MAP_PROPAGATOR;
};
return PropagationAPI;
}());
export { PropagationAPI };
//# sourceMappingURL=propagation.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,40 @@
import { isSpanContextValid, wrapSpanContext } from '../trace/spancontext-utils';
import { Tracer } from '../trace/tracer';
import { TracerProvider } from '../trace/tracer_provider';
import { deleteSpan, getActiveSpan, getSpan, getSpanContext, setSpan, setSpanContext } from '../trace/context-utils';
/**
* Singleton object which represents the entry point to the OpenTelemetry Tracing API
*/
export declare class TraceAPI {
private static _instance?;
private _proxyTracerProvider;
/** Empty private constructor prevents end users from constructing a new instance of the API */
private constructor();
/** Get the singleton instance of the Trace API */
static getInstance(): TraceAPI;
/**
* Set the current global tracer.
*
* @returns true if the tracer provider was successfully registered, else false
*/
setGlobalTracerProvider(provider: TracerProvider): boolean;
/**
* Returns the global tracer provider.
*/
getTracerProvider(): TracerProvider;
/**
* Returns a tracer from the global tracer provider.
*/
getTracer(name: string, version?: string): Tracer;
/** Remove the global tracer provider */
disable(): void;
wrapSpanContext: typeof wrapSpanContext;
isSpanContextValid: typeof isSpanContextValid;
deleteSpan: typeof deleteSpan;
getSpan: typeof getSpan;
getActiveSpan: typeof getActiveSpan;
getSpanContext: typeof getSpanContext;
setSpan: typeof setSpan;
setSpanContext: typeof setSpanContext;
}
//# sourceMappingURL=trace.d.ts.map

View File

@@ -0,0 +1,77 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getGlobal, registerGlobal, unregisterGlobal, } from '../internal/global-utils';
import { ProxyTracerProvider } from '../trace/ProxyTracerProvider';
import { isSpanContextValid, wrapSpanContext, } from '../trace/spancontext-utils';
import { deleteSpan, getActiveSpan, getSpan, getSpanContext, setSpan, setSpanContext, } from '../trace/context-utils';
import { DiagAPI } from './diag';
var API_NAME = 'trace';
/**
* Singleton object which represents the entry point to the OpenTelemetry Tracing API
*/
var TraceAPI = /** @class */ (function () {
/** Empty private constructor prevents end users from constructing a new instance of the API */
function TraceAPI() {
this._proxyTracerProvider = new ProxyTracerProvider();
this.wrapSpanContext = wrapSpanContext;
this.isSpanContextValid = isSpanContextValid;
this.deleteSpan = deleteSpan;
this.getSpan = getSpan;
this.getActiveSpan = getActiveSpan;
this.getSpanContext = getSpanContext;
this.setSpan = setSpan;
this.setSpanContext = setSpanContext;
}
/** Get the singleton instance of the Trace API */
TraceAPI.getInstance = function () {
if (!this._instance) {
this._instance = new TraceAPI();
}
return this._instance;
};
/**
* Set the current global tracer.
*
* @returns true if the tracer provider was successfully registered, else false
*/
TraceAPI.prototype.setGlobalTracerProvider = function (provider) {
var success = registerGlobal(API_NAME, this._proxyTracerProvider, DiagAPI.instance());
if (success) {
this._proxyTracerProvider.setDelegate(provider);
}
return success;
};
/**
* Returns the global tracer provider.
*/
TraceAPI.prototype.getTracerProvider = function () {
return getGlobal(API_NAME) || this._proxyTracerProvider;
};
/**
* Returns a tracer from the global tracer provider.
*/
TraceAPI.prototype.getTracer = function (name, version) {
return this.getTracerProvider().getTracer(name, version);
};
/** Remove the global tracer provider */
TraceAPI.prototype.disable = function () {
unregisterGlobal(API_NAME, DiagAPI.instance());
this._proxyTracerProvider = new ProxyTracerProvider();
};
return TraceAPI;
}());
export { TraceAPI };
//# sourceMappingURL=trace.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"trace.js","sourceRoot":"","sources":["../../../src/api/trace.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,SAAS,EACT,cAAc,EACd,gBAAgB,GACjB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EACL,kBAAkB,EAClB,eAAe,GAChB,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EACL,UAAU,EACV,aAAa,EACb,OAAO,EACP,cAAc,EACd,OAAO,EACP,cAAc,GACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAEjC,IAAM,QAAQ,GAAG,OAAO,CAAC;AAEzB;;GAEG;AACH;IAKE,+FAA+F;IAC/F;QAHQ,yBAAoB,GAAG,IAAI,mBAAmB,EAAE,CAAC;QAmDlD,oBAAe,GAAG,eAAe,CAAC;QAElC,uBAAkB,GAAG,kBAAkB,CAAC;QAExC,eAAU,GAAG,UAAU,CAAC;QAExB,YAAO,GAAG,OAAO,CAAC;QAElB,kBAAa,GAAG,aAAa,CAAC;QAE9B,mBAAc,GAAG,cAAc,CAAC;QAEhC,YAAO,GAAG,OAAO,CAAC;QAElB,mBAAc,GAAG,cAAc,CAAC;IA9DhB,CAAC;IAExB,kDAAkD;IACpC,oBAAW,GAAzB;QACE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE;YACnB,IAAI,CAAC,SAAS,GAAG,IAAI,QAAQ,EAAE,CAAC;SACjC;QAED,OAAO,IAAI,CAAC,SAAS,CAAC;IACxB,CAAC;IAED;;;;OAIG;IACI,0CAAuB,GAA9B,UAA+B,QAAwB;QACrD,IAAM,OAAO,GAAG,cAAc,CAC5B,QAAQ,EACR,IAAI,CAAC,oBAAoB,EACzB,OAAO,CAAC,QAAQ,EAAE,CACnB,CAAC;QACF,IAAI,OAAO,EAAE;YACX,IAAI,CAAC,oBAAoB,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;SACjD;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED;;OAEG;IACI,oCAAiB,GAAxB;QACE,OAAO,SAAS,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,oBAAoB,CAAC;IAC1D,CAAC;IAED;;OAEG;IACI,4BAAS,GAAhB,UAAiB,IAAY,EAAE,OAAgB;QAC7C,OAAO,IAAI,CAAC,iBAAiB,EAAE,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC3D,CAAC;IAED,wCAAwC;IACjC,0BAAO,GAAd;QACE,gBAAgB,CAAC,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC/C,IAAI,CAAC,oBAAoB,GAAG,IAAI,mBAAmB,EAAE,CAAC;IACxD,CAAC;IAiBH,eAAC;AAAD,CAAC,AArED,IAqEC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n getGlobal,\n registerGlobal,\n unregisterGlobal,\n} from '../internal/global-utils';\nimport { ProxyTracerProvider } from '../trace/ProxyTracerProvider';\nimport {\n isSpanContextValid,\n wrapSpanContext,\n} from '../trace/spancontext-utils';\nimport { Tracer } from '../trace/tracer';\nimport { TracerProvider } from '../trace/tracer_provider';\nimport {\n deleteSpan,\n getActiveSpan,\n getSpan,\n getSpanContext,\n setSpan,\n setSpanContext,\n} from '../trace/context-utils';\nimport { DiagAPI } from './diag';\n\nconst API_NAME = 'trace';\n\n/**\n * Singleton object which represents the entry point to the OpenTelemetry Tracing API\n */\nexport class TraceAPI {\n private static _instance?: TraceAPI;\n\n private _proxyTracerProvider = new ProxyTracerProvider();\n\n /** Empty private constructor prevents end users from constructing a new instance of the API */\n private constructor() {}\n\n /** Get the singleton instance of the Trace API */\n public static getInstance(): TraceAPI {\n if (!this._instance) {\n this._instance = new TraceAPI();\n }\n\n return this._instance;\n }\n\n /**\n * Set the current global tracer.\n *\n * @returns true if the tracer provider was successfully registered, else false\n */\n public setGlobalTracerProvider(provider: TracerProvider): boolean {\n const success = registerGlobal(\n API_NAME,\n this._proxyTracerProvider,\n DiagAPI.instance()\n );\n if (success) {\n this._proxyTracerProvider.setDelegate(provider);\n }\n return success;\n }\n\n /**\n * Returns the global tracer provider.\n */\n public getTracerProvider(): TracerProvider {\n return getGlobal(API_NAME) || this._proxyTracerProvider;\n }\n\n /**\n * Returns a tracer from the global tracer provider.\n */\n public getTracer(name: string, version?: string): Tracer {\n return this.getTracerProvider().getTracer(name, version);\n }\n\n /** Remove the global tracer provider */\n public disable() {\n unregisterGlobal(API_NAME, DiagAPI.instance());\n this._proxyTracerProvider = new ProxyTracerProvider();\n }\n\n public wrapSpanContext = wrapSpanContext;\n\n public isSpanContextValid = isSpanContextValid;\n\n public deleteSpan = deleteSpan;\n\n public getSpan = getSpan;\n\n public getActiveSpan = getActiveSpan;\n\n public getSpanContext = getSpanContext;\n\n public setSpan = setSpan;\n\n public setSpanContext = setSpanContext;\n}\n"]}

View File

@@ -0,0 +1,29 @@
import { Context } from '../context/types';
import { Baggage } from './types';
/**
* Retrieve the current baggage from the given context
*
* @param {Context} Context that manage all context values
* @returns {Baggage} Extracted baggage from the context
*/
export declare function getBaggage(context: Context): Baggage | undefined;
/**
* Retrieve the current baggage from the active/current context
*
* @returns {Baggage} Extracted baggage from the context
*/
export declare function getActiveBaggage(): Baggage | undefined;
/**
* Store a baggage in the given context
*
* @param {Context} Context that manage all context values
* @param {Baggage} baggage that will be set in the actual context
*/
export declare function setBaggage(context: Context, baggage: Baggage): Context;
/**
* Delete the baggage stored in the given context
*
* @param {Context} Context that manage all context values
*/
export declare function deleteBaggage(context: Context): Context;
//# sourceMappingURL=context-helpers.d.ts.map

View File

@@ -0,0 +1,56 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { ContextAPI } from '../api/context';
import { createContextKey } from '../context/context';
/**
* Baggage key
*/
var BAGGAGE_KEY = createContextKey('OpenTelemetry Baggage Key');
/**
* Retrieve the current baggage from the given context
*
* @param {Context} Context that manage all context values
* @returns {Baggage} Extracted baggage from the context
*/
export function getBaggage(context) {
return context.getValue(BAGGAGE_KEY) || undefined;
}
/**
* Retrieve the current baggage from the active/current context
*
* @returns {Baggage} Extracted baggage from the context
*/
export function getActiveBaggage() {
return getBaggage(ContextAPI.getInstance().active());
}
/**
* Store a baggage in the given context
*
* @param {Context} Context that manage all context values
* @param {Baggage} baggage that will be set in the actual context
*/
export function setBaggage(context, baggage) {
return context.setValue(BAGGAGE_KEY, baggage);
}
/**
* Delete the baggage stored in the given context
*
* @param {Context} Context that manage all context values
*/
export function deleteBaggage(context) {
return context.deleteValue(BAGGAGE_KEY);
}
//# sourceMappingURL=context-helpers.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"context-helpers.js","sourceRoot":"","sources":["../../../src/baggage/context-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAItD;;GAEG;AACH,IAAM,WAAW,GAAG,gBAAgB,CAAC,2BAA2B,CAAC,CAAC;AAElE;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,OAAgB;IACzC,OAAQ,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAa,IAAI,SAAS,CAAC;AACjE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB;IAC9B,OAAO,UAAU,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,CAAC,CAAC;AACvD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,UAAU,CAAC,OAAgB,EAAE,OAAgB;IAC3D,OAAO,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;AAChD,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,OAAgB;IAC5C,OAAO,OAAO,CAAC,WAAW,CAAC,WAAW,CAAC,CAAC;AAC1C,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ContextAPI } from '../api/context';\nimport { createContextKey } from '../context/context';\nimport { Context } from '../context/types';\nimport { Baggage } from './types';\n\n/**\n * Baggage key\n */\nconst BAGGAGE_KEY = createContextKey('OpenTelemetry Baggage Key');\n\n/**\n * Retrieve the current baggage from the given context\n *\n * @param {Context} Context that manage all context values\n * @returns {Baggage} Extracted baggage from the context\n */\nexport function getBaggage(context: Context): Baggage | undefined {\n return (context.getValue(BAGGAGE_KEY) as Baggage) || undefined;\n}\n\n/**\n * Retrieve the current baggage from the active/current context\n *\n * @returns {Baggage} Extracted baggage from the context\n */\nexport function getActiveBaggage(): Baggage | undefined {\n return getBaggage(ContextAPI.getInstance().active());\n}\n\n/**\n * Store a baggage in the given context\n *\n * @param {Context} Context that manage all context values\n * @param {Baggage} baggage that will be set in the actual context\n */\nexport function setBaggage(context: Context, baggage: Baggage): Context {\n return context.setValue(BAGGAGE_KEY, baggage);\n}\n\n/**\n * Delete the baggage stored in the given context\n *\n * @param {Context} Context that manage all context values\n */\nexport function deleteBaggage(context: Context): Context {\n return context.deleteValue(BAGGAGE_KEY);\n}\n"]}

View File

@@ -0,0 +1,12 @@
import type { Baggage, BaggageEntry } from '../types';
export declare class BaggageImpl implements Baggage {
private _entries;
constructor(entries?: Map<string, BaggageEntry>);
getEntry(key: string): BaggageEntry | undefined;
getAllEntries(): [string, BaggageEntry][];
setEntry(key: string, entry: BaggageEntry): BaggageImpl;
removeEntry(key: string): BaggageImpl;
removeEntries(...keys: string[]): BaggageImpl;
clear(): BaggageImpl;
}
//# sourceMappingURL=baggage-impl.d.ts.map

View File

@@ -0,0 +1,98 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var __read = (this && this.__read) || function (o, n) {
var m = typeof Symbol === "function" && o[Symbol.iterator];
if (!m) return o;
var i = m.call(o), r, ar = [], e;
try {
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
}
catch (error) { e = { error: error }; }
finally {
try {
if (r && !r.done && (m = i["return"])) m.call(i);
}
finally { if (e) throw e.error; }
}
return ar;
};
var __values = (this && this.__values) || function(o) {
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
if (m) return m.call(o);
if (o && typeof o.length === "number") return {
next: function () {
if (o && i >= o.length) o = void 0;
return { value: o && o[i++], done: !o };
}
};
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
};
var BaggageImpl = /** @class */ (function () {
function BaggageImpl(entries) {
this._entries = entries ? new Map(entries) : new Map();
}
BaggageImpl.prototype.getEntry = function (key) {
var entry = this._entries.get(key);
if (!entry) {
return undefined;
}
return Object.assign({}, entry);
};
BaggageImpl.prototype.getAllEntries = function () {
return Array.from(this._entries.entries()).map(function (_a) {
var _b = __read(_a, 2), k = _b[0], v = _b[1];
return [k, v];
});
};
BaggageImpl.prototype.setEntry = function (key, entry) {
var newBaggage = new BaggageImpl(this._entries);
newBaggage._entries.set(key, entry);
return newBaggage;
};
BaggageImpl.prototype.removeEntry = function (key) {
var newBaggage = new BaggageImpl(this._entries);
newBaggage._entries.delete(key);
return newBaggage;
};
BaggageImpl.prototype.removeEntries = function () {
var e_1, _a;
var keys = [];
for (var _i = 0; _i < arguments.length; _i++) {
keys[_i] = arguments[_i];
}
var newBaggage = new BaggageImpl(this._entries);
try {
for (var keys_1 = __values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
var key = keys_1_1.value;
newBaggage._entries.delete(key);
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1);
}
finally { if (e_1) throw e_1.error; }
}
return newBaggage;
};
BaggageImpl.prototype.clear = function () {
return new BaggageImpl();
};
return BaggageImpl;
}());
export { BaggageImpl };
//# sourceMappingURL=baggage-impl.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"baggage-impl.js","sourceRoot":"","sources":["../../../../src/baggage/internal/baggage-impl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIH;IAGE,qBAAY,OAAmC;QAC7C,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;IACzD,CAAC;IAED,8BAAQ,GAAR,UAAS,GAAW;QAClB,IAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,CAAC,KAAK,EAAE;YACV,OAAO,SAAS,CAAC;SAClB;QAED,OAAO,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;IAED,mCAAa,GAAb;QACE,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAAC,UAAC,EAAM;gBAAN,KAAA,aAAM,EAAL,CAAC,QAAA,EAAE,CAAC,QAAA;YAAM,OAAA,CAAC,CAAC,EAAE,CAAC,CAAC;QAAN,CAAM,CAAC,CAAC;IACrE,CAAC;IAED,8BAAQ,GAAR,UAAS,GAAW,EAAE,KAAmB;QACvC,IAAM,UAAU,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClD,UAAU,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACpC,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,iCAAW,GAAX,UAAY,GAAW;QACrB,IAAM,UAAU,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QAClD,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAChC,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,mCAAa,GAAb;;QAAc,cAAiB;aAAjB,UAAiB,EAAjB,qBAAiB,EAAjB,IAAiB;YAAjB,yBAAiB;;QAC7B,IAAM,UAAU,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;;YAClD,KAAkB,IAAA,SAAA,SAAA,IAAI,CAAA,0BAAA,4CAAE;gBAAnB,IAAM,GAAG,iBAAA;gBACZ,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;aACjC;;;;;;;;;QACD,OAAO,UAAU,CAAC;IACpB,CAAC;IAED,2BAAK,GAAL;QACE,OAAO,IAAI,WAAW,EAAE,CAAC;IAC3B,CAAC;IACH,kBAAC;AAAD,CAAC,AA3CD,IA2CC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport type { Baggage, BaggageEntry } from '../types';\n\nexport class BaggageImpl implements Baggage {\n private _entries: Map<string, BaggageEntry>;\n\n constructor(entries?: Map<string, BaggageEntry>) {\n this._entries = entries ? new Map(entries) : new Map();\n }\n\n getEntry(key: string): BaggageEntry | undefined {\n const entry = this._entries.get(key);\n if (!entry) {\n return undefined;\n }\n\n return Object.assign({}, entry);\n }\n\n getAllEntries(): [string, BaggageEntry][] {\n return Array.from(this._entries.entries()).map(([k, v]) => [k, v]);\n }\n\n setEntry(key: string, entry: BaggageEntry): BaggageImpl {\n const newBaggage = new BaggageImpl(this._entries);\n newBaggage._entries.set(key, entry);\n return newBaggage;\n }\n\n removeEntry(key: string): BaggageImpl {\n const newBaggage = new BaggageImpl(this._entries);\n newBaggage._entries.delete(key);\n return newBaggage;\n }\n\n removeEntries(...keys: string[]): BaggageImpl {\n const newBaggage = new BaggageImpl(this._entries);\n for (const key of keys) {\n newBaggage._entries.delete(key);\n }\n return newBaggage;\n }\n\n clear(): BaggageImpl {\n return new BaggageImpl();\n }\n}\n"]}

View File

@@ -0,0 +1,5 @@
/**
* Symbol used to make BaggageEntryMetadata an opaque type
*/
export declare const baggageEntryMetadataSymbol: unique symbol;
//# sourceMappingURL=symbol.d.ts.map

View File

@@ -0,0 +1,20 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Symbol used to make BaggageEntryMetadata an opaque type
*/
export var baggageEntryMetadataSymbol = Symbol('BaggageEntryMetadata');
//# sourceMappingURL=symbol.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"symbol.js","sourceRoot":"","sources":["../../../../src/baggage/internal/symbol.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;GAEG;AACH,MAAM,CAAC,IAAM,0BAA0B,GAAG,MAAM,CAAC,sBAAsB,CAAC,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Symbol used to make BaggageEntryMetadata an opaque type\n */\nexport const baggageEntryMetadataSymbol = Symbol('BaggageEntryMetadata');\n"]}

View File

@@ -0,0 +1,60 @@
import { baggageEntryMetadataSymbol } from './internal/symbol';
export interface BaggageEntry {
/** `String` value of the `BaggageEntry`. */
value: string;
/**
* Metadata is an optional string property defined by the W3C baggage specification.
* It currently has no special meaning defined by the specification.
*/
metadata?: BaggageEntryMetadata;
}
/**
* Serializable Metadata defined by the W3C baggage specification.
* It currently has no special meaning defined by the OpenTelemetry or W3C.
*/
export declare type BaggageEntryMetadata = {
toString(): string;
} & {
__TYPE__: typeof baggageEntryMetadataSymbol;
};
/**
* Baggage represents collection of key-value pairs with optional metadata.
* Each key of Baggage is associated with exactly one value.
* Baggage may be used to annotate and enrich telemetry data.
*/
export interface Baggage {
/**
* Get an entry from Baggage if it exists
*
* @param key The key which identifies the BaggageEntry
*/
getEntry(key: string): BaggageEntry | undefined;
/**
* Get a list of all entries in the Baggage
*/
getAllEntries(): [string, BaggageEntry][];
/**
* Returns a new baggage with the entries from the current bag and the specified entry
*
* @param key string which identifies the baggage entry
* @param entry BaggageEntry for the given key
*/
setEntry(key: string, entry: BaggageEntry): Baggage;
/**
* Returns a new baggage with the entries from the current bag except the removed entry
*
* @param key key identifying the entry to be removed
*/
removeEntry(key: string): Baggage;
/**
* Returns a new baggage with the entries from the current bag except the removed entries
*
* @param key keys identifying the entries to be removed
*/
removeEntries(...key: string[]): Baggage;
/**
* Returns a new baggage with no entries
*/
clear(): Baggage;
}
//# sourceMappingURL=types.d.ts.map

View File

@@ -0,0 +1,17 @@
/*
* Copyright The OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export {};
//# sourceMappingURL=types.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/baggage/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { baggageEntryMetadataSymbol } from './internal/symbol';\n\n/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nexport interface BaggageEntry {\n /** `String` value of the `BaggageEntry`. */\n value: string;\n /**\n * Metadata is an optional string property defined by the W3C baggage specification.\n * It currently has no special meaning defined by the specification.\n */\n metadata?: BaggageEntryMetadata;\n}\n\n/**\n * Serializable Metadata defined by the W3C baggage specification.\n * It currently has no special meaning defined by the OpenTelemetry or W3C.\n */\nexport type BaggageEntryMetadata = { toString(): string } & {\n __TYPE__: typeof baggageEntryMetadataSymbol;\n};\n\n/**\n * Baggage represents collection of key-value pairs with optional metadata.\n * Each key of Baggage is associated with exactly one value.\n * Baggage may be used to annotate and enrich telemetry data.\n */\nexport interface Baggage {\n /**\n * Get an entry from Baggage if it exists\n *\n * @param key The key which identifies the BaggageEntry\n */\n getEntry(key: string): BaggageEntry | undefined;\n\n /**\n * Get a list of all entries in the Baggage\n */\n getAllEntries(): [string, BaggageEntry][];\n\n /**\n * Returns a new baggage with the entries from the current bag and the specified entry\n *\n * @param key string which identifies the baggage entry\n * @param entry BaggageEntry for the given key\n */\n setEntry(key: string, entry: BaggageEntry): Baggage;\n\n /**\n * Returns a new baggage with the entries from the current bag except the removed entry\n *\n * @param key key identifying the entry to be removed\n */\n removeEntry(key: string): Baggage;\n\n /**\n * Returns a new baggage with the entries from the current bag except the removed entries\n *\n * @param key keys identifying the entries to be removed\n */\n removeEntries(...key: string[]): Baggage;\n\n /**\n * Returns a new baggage with no entries\n */\n clear(): Baggage;\n}\n"]}

Some files were not shown because too many files have changed in this diff Show More