@agentfield/sdk 0.1.136 → 0.1.137-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +198 -191
- package/dist/index.js +568 -523
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -20,11 +20,11 @@ import { createXai } from '@ai-sdk/xai';
|
|
|
20
20
|
import { createDeepSeek } from '@ai-sdk/deepseek';
|
|
21
21
|
import { createCohere } from '@ai-sdk/cohere';
|
|
22
22
|
import os from 'os';
|
|
23
|
+
import { readFile } from 'fs/promises';
|
|
23
24
|
import WebSocket from 'ws';
|
|
24
25
|
import { Buffer as Buffer$1 } from 'buffer';
|
|
25
26
|
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
26
27
|
import { generateKeyPair, exportJWK, importJWK, CompactEncrypt, compactDecrypt } from 'jose';
|
|
27
|
-
import { readFile } from 'fs/promises';
|
|
28
28
|
import { fileURLToPath } from 'url';
|
|
29
29
|
|
|
30
30
|
var __defProp = Object.defineProperty;
|
|
@@ -2987,150 +2987,439 @@ function withOpenRouterUsageInclude(baseFetch) {
|
|
|
2987
2987
|
return impl(input, init);
|
|
2988
2988
|
};
|
|
2989
2989
|
}
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2990
|
+
var IMAGE_MIME_TYPES = {
|
|
2991
|
+
".jpg": "image/jpeg",
|
|
2992
|
+
".jpeg": "image/jpeg",
|
|
2993
|
+
".png": "image/png",
|
|
2994
|
+
".gif": "image/gif",
|
|
2995
|
+
".webp": "image/webp",
|
|
2996
|
+
".bmp": "image/bmp"
|
|
2997
|
+
};
|
|
2998
|
+
var AUDIO_MIME_TYPES = {
|
|
2999
|
+
".wav": "audio/wav",
|
|
3000
|
+
".mp3": "audio/mpeg",
|
|
3001
|
+
".flac": "audio/flac",
|
|
3002
|
+
".ogg": "audio/ogg"
|
|
3003
|
+
};
|
|
3004
|
+
var VIDEO_MIME_TYPES = {
|
|
3005
|
+
".mp4": "video/mp4",
|
|
3006
|
+
".mpeg": "video/mpeg",
|
|
3007
|
+
".mpg": "video/mpeg",
|
|
3008
|
+
".mov": "video/quicktime",
|
|
3009
|
+
".webm": "video/webm"
|
|
3010
|
+
};
|
|
3011
|
+
var Text = class {
|
|
3012
|
+
type = "text";
|
|
3013
|
+
text;
|
|
3014
|
+
constructor(text2) {
|
|
3015
|
+
this.text = text2;
|
|
2997
3016
|
}
|
|
2998
|
-
|
|
2999
|
-
|
|
3000
|
-
|
|
3017
|
+
};
|
|
3018
|
+
var Image = class _Image {
|
|
3019
|
+
type = "image_url";
|
|
3020
|
+
imageUrl;
|
|
3021
|
+
constructor(imageUrl) {
|
|
3022
|
+
this.imageUrl = imageUrl;
|
|
3001
3023
|
}
|
|
3002
|
-
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3007
|
-
|
|
3024
|
+
/**
|
|
3025
|
+
* Create Image from a local file by converting to base64 data URL.
|
|
3026
|
+
*/
|
|
3027
|
+
static async fromFile(filePath, detail = "high") {
|
|
3028
|
+
const absolutePath = resolve(filePath);
|
|
3029
|
+
const buffer = await readFile(absolutePath);
|
|
3030
|
+
const base64Data = buffer.toString("base64");
|
|
3031
|
+
const ext = getExtension(absolutePath).toLowerCase();
|
|
3032
|
+
const mimeType = IMAGE_MIME_TYPES[ext] || "image/jpeg";
|
|
3033
|
+
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
3034
|
+
return new _Image({ url: dataUrl, detail });
|
|
3008
3035
|
}
|
|
3009
|
-
|
|
3010
|
-
|
|
3011
|
-
|
|
3012
|
-
|
|
3013
|
-
|
|
3014
|
-
this.config = {
|
|
3015
|
-
enableRateLimitRetry: true,
|
|
3016
|
-
rateLimitMaxRetries: 20,
|
|
3017
|
-
rateLimitBaseDelay: 1,
|
|
3018
|
-
rateLimitMaxDelay: 300,
|
|
3019
|
-
rateLimitJitterFactor: 0.25,
|
|
3020
|
-
rateLimitCircuitBreakerThreshold: 10,
|
|
3021
|
-
rateLimitCircuitBreakerTimeout: 300,
|
|
3022
|
-
...config
|
|
3023
|
-
};
|
|
3036
|
+
/**
|
|
3037
|
+
* Create Image from a URL.
|
|
3038
|
+
*/
|
|
3039
|
+
static fromUrl(url, detail = "high") {
|
|
3040
|
+
return new _Image({ url, detail });
|
|
3024
3041
|
}
|
|
3025
|
-
|
|
3026
|
-
|
|
3027
|
-
|
|
3028
|
-
|
|
3029
|
-
|
|
3030
|
-
|
|
3031
|
-
|
|
3032
|
-
|
|
3033
|
-
|
|
3034
|
-
|
|
3035
|
-
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3042
|
+
/**
|
|
3043
|
+
* Create Image from a buffer.
|
|
3044
|
+
*/
|
|
3045
|
+
static async fromBuffer(buffer, mimeType = "image/jpeg", detail = "high") {
|
|
3046
|
+
const base64Data = Buffer.from(buffer).toString("base64");
|
|
3047
|
+
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
3048
|
+
return new _Image({ url: dataUrl, detail });
|
|
3049
|
+
}
|
|
3050
|
+
/**
|
|
3051
|
+
* Create Image from a base64 string.
|
|
3052
|
+
*/
|
|
3053
|
+
static async fromBase64(base64Data, mimeType = "image/jpeg", detail = "high") {
|
|
3054
|
+
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
3055
|
+
return new _Image({ url: dataUrl, detail });
|
|
3056
|
+
}
|
|
3057
|
+
};
|
|
3058
|
+
var Audio = class _Audio {
|
|
3059
|
+
type = "input_audio";
|
|
3060
|
+
audio;
|
|
3061
|
+
constructor(audio) {
|
|
3062
|
+
this.audio = audio;
|
|
3063
|
+
}
|
|
3064
|
+
/**
|
|
3065
|
+
* Create Audio from a local file by converting to base64.
|
|
3066
|
+
*/
|
|
3067
|
+
static async fromFile(filePath, format) {
|
|
3068
|
+
const absolutePath = resolve(filePath);
|
|
3069
|
+
const ext = getExtension(absolutePath).toLowerCase().replace(".", "");
|
|
3070
|
+
const audioFormat = format || (["wav", "mp3", "flac", "ogg"].includes(ext) ? ext : "wav");
|
|
3071
|
+
const buffer = await readFile(absolutePath);
|
|
3072
|
+
const base64Data = buffer.toString("base64");
|
|
3073
|
+
return new _Audio({ data: base64Data, format: audioFormat });
|
|
3074
|
+
}
|
|
3075
|
+
/**
|
|
3076
|
+
* Create Audio from a URL (downloads and converts to base64).
|
|
3077
|
+
*/
|
|
3078
|
+
static async fromUrl(url, format = "wav") {
|
|
3079
|
+
try {
|
|
3080
|
+
const response = await fetch(url);
|
|
3081
|
+
if (!response.ok) {
|
|
3082
|
+
throw new Error(`Failed to fetch audio from URL: ${response.status} ${response.statusText}`);
|
|
3083
|
+
}
|
|
3084
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
3085
|
+
const base64Data = Buffer.from(arrayBuffer).toString("base64");
|
|
3086
|
+
return new _Audio({ data: base64Data, format });
|
|
3087
|
+
} catch (error) {
|
|
3088
|
+
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
3089
|
+
throw new Error("URL download requires a fetch-compatible environment");
|
|
3090
|
+
}
|
|
3091
|
+
throw error;
|
|
3043
3092
|
}
|
|
3044
|
-
const call = async () => generateText({
|
|
3045
|
-
model,
|
|
3046
|
-
prompt,
|
|
3047
|
-
system: options.system,
|
|
3048
|
-
temperature: options.temperature ?? this.config.temperature,
|
|
3049
|
-
maxOutputTokens: options.maxTokens ?? this.config.maxTokens
|
|
3050
|
-
});
|
|
3051
|
-
const response = await this.withRateLimitRetry(call);
|
|
3052
|
-
recordAiSdkUsage({ source: response, model: modelName, provider });
|
|
3053
|
-
return response.text;
|
|
3054
3093
|
}
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
|
|
3060
|
-
|
|
3061
|
-
const streamResult = streamText({
|
|
3062
|
-
model,
|
|
3063
|
-
prompt,
|
|
3064
|
-
system: options.system,
|
|
3065
|
-
temperature: options.temperature ?? this.config.temperature,
|
|
3066
|
-
maxOutputTokens: options.maxTokens ?? this.config.maxTokens
|
|
3067
|
-
});
|
|
3068
|
-
return streamResult.textStream;
|
|
3094
|
+
/**
|
|
3095
|
+
* Create Audio from a buffer.
|
|
3096
|
+
*/
|
|
3097
|
+
static async fromBuffer(buffer, format = "wav") {
|
|
3098
|
+
const base64Data = Buffer.from(buffer).toString("base64");
|
|
3099
|
+
return new _Audio({ data: base64Data, format });
|
|
3069
3100
|
}
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
value
|
|
3076
|
-
})
|
|
3077
|
-
);
|
|
3078
|
-
return result.embedding;
|
|
3101
|
+
/**
|
|
3102
|
+
* Create Audio from a base64 string.
|
|
3103
|
+
*/
|
|
3104
|
+
static async fromBase64(base64Data, format = "wav") {
|
|
3105
|
+
return new _Audio({ data: base64Data, format });
|
|
3079
3106
|
}
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
})
|
|
3087
|
-
);
|
|
3088
|
-
return result.embeddings;
|
|
3107
|
+
};
|
|
3108
|
+
var Video = class _Video {
|
|
3109
|
+
type = "video_url";
|
|
3110
|
+
videoUrl;
|
|
3111
|
+
constructor(videoUrl) {
|
|
3112
|
+
this.videoUrl = videoUrl;
|
|
3089
3113
|
}
|
|
3090
3114
|
/**
|
|
3091
|
-
*
|
|
3092
|
-
* Exposed for use by the tool-calling loop.
|
|
3115
|
+
* Create Video from a local file by converting to a base64 data URL.
|
|
3093
3116
|
*/
|
|
3094
|
-
|
|
3095
|
-
|
|
3117
|
+
static async fromFile(filePath) {
|
|
3118
|
+
const absolutePath = resolve(filePath);
|
|
3119
|
+
const buffer = await readFile(absolutePath);
|
|
3120
|
+
const base64Data = buffer.toString("base64");
|
|
3121
|
+
const ext = getExtension(absolutePath).toLowerCase();
|
|
3122
|
+
const mimeType = VIDEO_MIME_TYPES[ext] || "video/mp4";
|
|
3123
|
+
return new _Video({ url: `data:${mimeType};base64,${base64Data}` });
|
|
3096
3124
|
}
|
|
3097
3125
|
/**
|
|
3098
|
-
*
|
|
3099
|
-
* the model. Used by usage tracking to attribute token/cost entries to the
|
|
3100
|
-
* model actually called.
|
|
3126
|
+
* Create Video from a URL.
|
|
3101
3127
|
*/
|
|
3102
|
-
|
|
3103
|
-
return {
|
|
3104
|
-
provider: options.provider ?? this.config.provider ?? "openai",
|
|
3105
|
-
modelName: options.model ?? this.config.model ?? "gpt-4o"
|
|
3106
|
-
};
|
|
3128
|
+
static fromUrl(url) {
|
|
3129
|
+
return new _Video({ url });
|
|
3107
3130
|
}
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3131
|
+
/**
|
|
3132
|
+
* Create Video from a buffer.
|
|
3133
|
+
*/
|
|
3134
|
+
static async fromBuffer(buffer, mimeType = "video/mp4") {
|
|
3135
|
+
const base64Data = Buffer.from(buffer).toString("base64");
|
|
3136
|
+
return new _Video({ url: `data:${mimeType};base64,${base64Data}` });
|
|
3137
|
+
}
|
|
3138
|
+
/**
|
|
3139
|
+
* Create Video from a base64 string.
|
|
3140
|
+
*/
|
|
3141
|
+
static async fromBase64(base64Data, mimeType = "video/mp4") {
|
|
3142
|
+
return new _Video({ url: `data:${mimeType};base64,${base64Data}` });
|
|
3143
|
+
}
|
|
3144
|
+
};
|
|
3145
|
+
var File = class _File {
|
|
3146
|
+
type = "file";
|
|
3147
|
+
file;
|
|
3148
|
+
constructor(file) {
|
|
3149
|
+
this.file = file;
|
|
3150
|
+
}
|
|
3151
|
+
/**
|
|
3152
|
+
* Create File from a local file path.
|
|
3153
|
+
*/
|
|
3154
|
+
static async fromFile(filePath, mimeType) {
|
|
3155
|
+
const absolutePath = resolve(filePath);
|
|
3156
|
+
const detectedMimeType = mimeType || guessMimeType(absolutePath) || "application/octet-stream";
|
|
3157
|
+
const buffer = await readFile(absolutePath);
|
|
3158
|
+
const base64Data = buffer.toString("base64");
|
|
3159
|
+
const dataUrl = `data:${detectedMimeType};base64,${base64Data}`;
|
|
3160
|
+
return new _File({ url: dataUrl, mimeType: detectedMimeType });
|
|
3161
|
+
}
|
|
3162
|
+
/**
|
|
3163
|
+
* Create File from a URL.
|
|
3164
|
+
*/
|
|
3165
|
+
static fromUrl(url, mimeType) {
|
|
3166
|
+
return new _File({ url, mimeType });
|
|
3167
|
+
}
|
|
3168
|
+
/**
|
|
3169
|
+
* Create File from a buffer.
|
|
3170
|
+
*/
|
|
3171
|
+
static async fromBuffer(buffer, mimeType) {
|
|
3172
|
+
const base64Data = Buffer.from(buffer).toString("base64");
|
|
3173
|
+
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
3174
|
+
return new _File({ url: dataUrl, mimeType });
|
|
3175
|
+
}
|
|
3176
|
+
/**
|
|
3177
|
+
* Create File from a base64 string.
|
|
3178
|
+
*/
|
|
3179
|
+
static async fromBase64(base64Data, mimeType) {
|
|
3180
|
+
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
3181
|
+
return new _File({ url: dataUrl, mimeType });
|
|
3182
|
+
}
|
|
3183
|
+
};
|
|
3184
|
+
function getExtension(filePath) {
|
|
3185
|
+
const lastDot = filePath.lastIndexOf(".");
|
|
3186
|
+
if (lastDot === -1) {
|
|
3187
|
+
return "";
|
|
3188
|
+
}
|
|
3189
|
+
return filePath.slice(lastDot);
|
|
3190
|
+
}
|
|
3191
|
+
function guessMimeType(filePath) {
|
|
3192
|
+
const ext = getExtension(filePath).toLowerCase();
|
|
3193
|
+
if (ext in IMAGE_MIME_TYPES) {
|
|
3194
|
+
return IMAGE_MIME_TYPES[ext];
|
|
3195
|
+
}
|
|
3196
|
+
if (ext in AUDIO_MIME_TYPES) {
|
|
3197
|
+
return AUDIO_MIME_TYPES[ext];
|
|
3198
|
+
}
|
|
3199
|
+
if (ext in VIDEO_MIME_TYPES) {
|
|
3200
|
+
return VIDEO_MIME_TYPES[ext];
|
|
3201
|
+
}
|
|
3202
|
+
const documentMimeTypes = {
|
|
3203
|
+
".pdf": "application/pdf",
|
|
3204
|
+
".doc": "application/msword",
|
|
3205
|
+
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
3206
|
+
".xls": "application/vnd.ms-excel",
|
|
3207
|
+
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
3208
|
+
".txt": "text/plain",
|
|
3209
|
+
".csv": "text/csv",
|
|
3210
|
+
".html": "text/html",
|
|
3211
|
+
".json": "application/json",
|
|
3212
|
+
".xml": "application/xml",
|
|
3213
|
+
".zip": "application/zip"
|
|
3214
|
+
};
|
|
3215
|
+
return documentMimeTypes[ext] || null;
|
|
3216
|
+
}
|
|
3217
|
+
function getDataUrlMimeType(url) {
|
|
3218
|
+
const match = /^data:([^;,]+)(?:;[^,]*)?,/i.exec(url);
|
|
3219
|
+
return match?.[1] || null;
|
|
3220
|
+
}
|
|
3221
|
+
function guessUrlMimeType(url) {
|
|
3222
|
+
return getDataUrlMimeType(url) ?? guessMimeType(url.split(/[?#]/, 1)[0]);
|
|
3223
|
+
}
|
|
3224
|
+
function audioMediaType(format) {
|
|
3225
|
+
return AUDIO_MIME_TYPES[`.${format.toLowerCase()}`] ?? `audio/${format}`;
|
|
3226
|
+
}
|
|
3227
|
+
function text(content) {
|
|
3228
|
+
return new Text(content);
|
|
3229
|
+
}
|
|
3230
|
+
async function imageFromFile(filePath, detail = "high") {
|
|
3231
|
+
return Image.fromFile(filePath, detail);
|
|
3232
|
+
}
|
|
3233
|
+
function imageFromUrl(url, detail = "high") {
|
|
3234
|
+
return Image.fromUrl(url, detail);
|
|
3235
|
+
}
|
|
3236
|
+
async function imageFromBuffer(buffer, mimeType = "image/jpeg", detail = "high") {
|
|
3237
|
+
return Image.fromBuffer(buffer, mimeType, detail);
|
|
3238
|
+
}
|
|
3239
|
+
async function imageFromBase64(base64Data, mimeType, detail = "high") {
|
|
3240
|
+
return Image.fromBase64(base64Data, mimeType, detail);
|
|
3241
|
+
}
|
|
3242
|
+
async function audioFromFile(filePath, format) {
|
|
3243
|
+
return Audio.fromFile(filePath, format);
|
|
3244
|
+
}
|
|
3245
|
+
async function audioFromUrl(url, format = "wav") {
|
|
3246
|
+
return Audio.fromUrl(url, format);
|
|
3247
|
+
}
|
|
3248
|
+
async function audioFromBuffer(buffer, format = "wav") {
|
|
3249
|
+
return Audio.fromBuffer(buffer, format);
|
|
3250
|
+
}
|
|
3251
|
+
async function audioFromBase64(base64Data, format = "wav") {
|
|
3252
|
+
return Audio.fromBase64(base64Data, format);
|
|
3253
|
+
}
|
|
3254
|
+
async function videoFromFile(filePath) {
|
|
3255
|
+
return Video.fromFile(filePath);
|
|
3256
|
+
}
|
|
3257
|
+
function videoFromUrl(url) {
|
|
3258
|
+
return Video.fromUrl(url);
|
|
3259
|
+
}
|
|
3260
|
+
async function videoFromBuffer(buffer, mimeType = "video/mp4") {
|
|
3261
|
+
return Video.fromBuffer(buffer, mimeType);
|
|
3262
|
+
}
|
|
3263
|
+
async function videoFromBase64(base64Data, mimeType = "video/mp4") {
|
|
3264
|
+
return Video.fromBase64(base64Data, mimeType);
|
|
3265
|
+
}
|
|
3266
|
+
async function fileFromPath(filePath, mimeType) {
|
|
3267
|
+
return File.fromFile(filePath, mimeType);
|
|
3268
|
+
}
|
|
3269
|
+
function fileFromUrl(url, mimeType) {
|
|
3270
|
+
return File.fromUrl(url, mimeType);
|
|
3271
|
+
}
|
|
3272
|
+
async function fileFromBuffer(buffer, mimeType) {
|
|
3273
|
+
return File.fromBuffer(buffer, mimeType);
|
|
3274
|
+
}
|
|
3275
|
+
async function fileFromBase64(base64Data, mimeType) {
|
|
3276
|
+
return File.fromBase64(base64Data, mimeType);
|
|
3277
|
+
}
|
|
3278
|
+
|
|
3279
|
+
// src/ai/AIClient.ts
|
|
3280
|
+
function repairJsonText(text2) {
|
|
3281
|
+
let cleaned = text2.trim();
|
|
3282
|
+
const codeBlockMatch = cleaned.match(/```(?:json)?\s*([\s\S]*?)```/);
|
|
3283
|
+
if (codeBlockMatch) {
|
|
3284
|
+
cleaned = codeBlockMatch[1].trim();
|
|
3285
|
+
}
|
|
3286
|
+
const jsonMatch = cleaned.match(/(\{[\s\S]*\}|\[[\s\S]*\])/);
|
|
3287
|
+
if (jsonMatch) {
|
|
3288
|
+
cleaned = jsonMatch[1];
|
|
3289
|
+
}
|
|
3290
|
+
cleaned = cleaned.replace(/,(\s*[}\]])/g, "$1");
|
|
3291
|
+
try {
|
|
3292
|
+
JSON.parse(cleaned);
|
|
3293
|
+
return cleaned;
|
|
3294
|
+
} catch {
|
|
3295
|
+
return null;
|
|
3296
|
+
}
|
|
3297
|
+
}
|
|
3298
|
+
var AIClient = class {
|
|
3299
|
+
config;
|
|
3300
|
+
rateLimiter;
|
|
3301
|
+
constructor(config = {}) {
|
|
3302
|
+
this.config = {
|
|
3303
|
+
enableRateLimitRetry: true,
|
|
3304
|
+
rateLimitMaxRetries: 20,
|
|
3305
|
+
rateLimitBaseDelay: 1,
|
|
3306
|
+
rateLimitMaxDelay: 300,
|
|
3307
|
+
rateLimitJitterFactor: 0.25,
|
|
3308
|
+
rateLimitCircuitBreakerThreshold: 10,
|
|
3309
|
+
rateLimitCircuitBreakerTimeout: 300,
|
|
3310
|
+
...config
|
|
3311
|
+
};
|
|
3312
|
+
}
|
|
3313
|
+
async generate(prompt, options = {}) {
|
|
3314
|
+
const { provider, modelName } = this.resolveModelChoice(options);
|
|
3315
|
+
const model = this.buildModel(options);
|
|
3316
|
+
const requestPrompt = this.buildPrompt(prompt, options.content);
|
|
3317
|
+
if (options.schema) {
|
|
3318
|
+
const schema = options.schema;
|
|
3319
|
+
const call2 = async () => generateObject({
|
|
3320
|
+
model,
|
|
3321
|
+
prompt: requestPrompt,
|
|
3322
|
+
output: "object",
|
|
3323
|
+
system: options.system,
|
|
3324
|
+
temperature: options.temperature ?? this.config.temperature,
|
|
3325
|
+
maxOutputTokens: options.maxTokens ?? this.config.maxTokens,
|
|
3326
|
+
schema,
|
|
3327
|
+
experimental_repairText: async ({ text: text2 }) => repairJsonText(text2)
|
|
3328
|
+
});
|
|
3329
|
+
const response2 = await this.withRateLimitRetry(call2);
|
|
3330
|
+
recordAiSdkUsage({ source: response2, model: modelName, provider });
|
|
3331
|
+
return response2.object;
|
|
3332
|
+
}
|
|
3333
|
+
const call = async () => generateText({
|
|
3334
|
+
model,
|
|
3335
|
+
prompt: requestPrompt,
|
|
3336
|
+
system: options.system,
|
|
3337
|
+
temperature: options.temperature ?? this.config.temperature,
|
|
3338
|
+
maxOutputTokens: options.maxTokens ?? this.config.maxTokens
|
|
3339
|
+
});
|
|
3340
|
+
const response = await this.withRateLimitRetry(call);
|
|
3341
|
+
recordAiSdkUsage({ source: response, model: modelName, provider });
|
|
3342
|
+
return response.text;
|
|
3343
|
+
}
|
|
3344
|
+
// NOTE: stream() usage is deliberately NOT captured. The AI SDK's
|
|
3345
|
+
// streamResult.usage/.totalUsage promises "automatically consume the
|
|
3346
|
+
// stream": attaching to them would force full background consumption of a
|
|
3347
|
+
// stream the caller may abandon early, changing stream semantics.
|
|
3348
|
+
async stream(prompt, options = {}) {
|
|
3349
|
+
const model = this.buildModel(options);
|
|
3350
|
+
const streamResult = streamText({
|
|
3351
|
+
model,
|
|
3352
|
+
prompt: this.buildPrompt(prompt, options.content),
|
|
3353
|
+
system: options.system,
|
|
3354
|
+
temperature: options.temperature ?? this.config.temperature,
|
|
3355
|
+
maxOutputTokens: options.maxTokens ?? this.config.maxTokens
|
|
3356
|
+
});
|
|
3357
|
+
return streamResult.textStream;
|
|
3358
|
+
}
|
|
3359
|
+
async embed(value, options = {}) {
|
|
3360
|
+
const model = this.buildEmbeddingModel(options);
|
|
3361
|
+
const result = await this.withRateLimitRetry(
|
|
3362
|
+
() => embed({
|
|
3363
|
+
model,
|
|
3364
|
+
value
|
|
3365
|
+
})
|
|
3366
|
+
);
|
|
3367
|
+
return result.embedding;
|
|
3368
|
+
}
|
|
3369
|
+
async embedMany(values, options = {}) {
|
|
3370
|
+
const model = this.buildEmbeddingModel(options);
|
|
3371
|
+
const result = await this.withRateLimitRetry(
|
|
3372
|
+
() => embedMany({
|
|
3373
|
+
model,
|
|
3374
|
+
values
|
|
3375
|
+
})
|
|
3376
|
+
);
|
|
3377
|
+
return result.embeddings;
|
|
3378
|
+
}
|
|
3379
|
+
/**
|
|
3380
|
+
* Build and return the AI model instance for a given set of options.
|
|
3381
|
+
* Exposed for use by the tool-calling loop.
|
|
3382
|
+
*/
|
|
3383
|
+
getModel(options = {}) {
|
|
3384
|
+
return this.buildModel(options);
|
|
3385
|
+
}
|
|
3386
|
+
/**
|
|
3387
|
+
* Resolve the effective provider/model pair for a request without building
|
|
3388
|
+
* the model. Used by usage tracking to attribute token/cost entries to the
|
|
3389
|
+
* model actually called.
|
|
3390
|
+
*/
|
|
3391
|
+
resolveModelChoice(options = {}) {
|
|
3392
|
+
return {
|
|
3393
|
+
provider: options.provider ?? this.config.provider ?? "openai",
|
|
3394
|
+
modelName: options.model ?? this.config.model ?? "gpt-4o"
|
|
3395
|
+
};
|
|
3396
|
+
}
|
|
3397
|
+
buildModel(options) {
|
|
3398
|
+
const { provider, modelName } = this.resolveModelChoice(options);
|
|
3399
|
+
const openRouterHeaders = this.openRouterHeaders(provider, modelName);
|
|
3400
|
+
switch (provider) {
|
|
3401
|
+
case "anthropic": {
|
|
3402
|
+
const anthropic = createAnthropic({
|
|
3403
|
+
apiKey: this.config.apiKey,
|
|
3404
|
+
baseURL: this.config.baseUrl
|
|
3405
|
+
});
|
|
3406
|
+
return anthropic(modelName);
|
|
3407
|
+
}
|
|
3408
|
+
case "google": {
|
|
3409
|
+
const google = createGoogleGenerativeAI({
|
|
3410
|
+
apiKey: this.config.apiKey,
|
|
3411
|
+
baseURL: this.config.baseUrl
|
|
3412
|
+
});
|
|
3413
|
+
return google(modelName);
|
|
3414
|
+
}
|
|
3415
|
+
case "mistral": {
|
|
3416
|
+
const mistral = createMistral({
|
|
3417
|
+
apiKey: this.config.apiKey,
|
|
3418
|
+
baseURL: this.config.baseUrl
|
|
3419
|
+
});
|
|
3420
|
+
return mistral(modelName);
|
|
3421
|
+
}
|
|
3422
|
+
case "groq": {
|
|
3134
3423
|
const groq = createGroq({
|
|
3135
3424
|
apiKey: this.config.apiKey,
|
|
3136
3425
|
baseURL: this.config.baseUrl
|
|
@@ -3186,6 +3475,40 @@ var AIClient = class {
|
|
|
3186
3475
|
}
|
|
3187
3476
|
}
|
|
3188
3477
|
}
|
|
3478
|
+
buildPrompt(prompt, content) {
|
|
3479
|
+
if (!content?.length) return prompt;
|
|
3480
|
+
const messageContent = [
|
|
3481
|
+
{ type: "text", text: prompt },
|
|
3482
|
+
...content.map((part) => {
|
|
3483
|
+
if (part.type === "text") return { type: "text", text: part.text };
|
|
3484
|
+
if (part.type === "image_url") return { type: "image", image: part.imageUrl.url };
|
|
3485
|
+
if (part.type === "video_url") {
|
|
3486
|
+
return {
|
|
3487
|
+
type: "file",
|
|
3488
|
+
data: part.videoUrl.url,
|
|
3489
|
+
mediaType: guessUrlMimeType(part.videoUrl.url) ?? "video/mp4"
|
|
3490
|
+
};
|
|
3491
|
+
}
|
|
3492
|
+
if (part.type === "input_audio") {
|
|
3493
|
+
return {
|
|
3494
|
+
type: "file",
|
|
3495
|
+
data: part.audio.data,
|
|
3496
|
+
mediaType: audioMediaType(part.audio.format)
|
|
3497
|
+
};
|
|
3498
|
+
}
|
|
3499
|
+
return {
|
|
3500
|
+
type: "file",
|
|
3501
|
+
data: part.file.url,
|
|
3502
|
+
mediaType: part.file.mimeType ?? guessUrlMimeType(part.file.url) ?? "application/octet-stream"
|
|
3503
|
+
};
|
|
3504
|
+
})
|
|
3505
|
+
];
|
|
3506
|
+
const messages = [{
|
|
3507
|
+
role: "user",
|
|
3508
|
+
content: messageContent
|
|
3509
|
+
}];
|
|
3510
|
+
return messages;
|
|
3511
|
+
}
|
|
3189
3512
|
buildEmbeddingModel(options) {
|
|
3190
3513
|
const provider = options.provider ?? this.config.provider ?? "openai";
|
|
3191
3514
|
const modelName = options.model ?? this.config.embeddingModel ?? "text-embedding-3-small";
|
|
@@ -7141,416 +7464,138 @@ var Agent = class {
|
|
|
7141
7464
|
}
|
|
7142
7465
|
});
|
|
7143
7466
|
}
|
|
7144
|
-
parseTarget(target) {
|
|
7145
|
-
if (!target.includes(".")) {
|
|
7146
|
-
return { name: target };
|
|
7147
|
-
}
|
|
7148
|
-
const [agentId, remainder] = target.split(".", 2);
|
|
7149
|
-
const name = remainder.replace(":", "/");
|
|
7150
|
-
return { agentId, name };
|
|
7151
|
-
}
|
|
7152
|
-
};
|
|
7153
|
-
|
|
7154
|
-
// src/router/AgentRouter.ts
|
|
7155
|
-
var AgentRouter = class {
|
|
7156
|
-
prefix;
|
|
7157
|
-
tags;
|
|
7158
|
-
reasoners = [];
|
|
7159
|
-
skills = [];
|
|
7160
|
-
constructor(options = {}) {
|
|
7161
|
-
this.prefix = options.prefix;
|
|
7162
|
-
this.tags = options.tags;
|
|
7163
|
-
}
|
|
7164
|
-
reasoner(name, handler, options) {
|
|
7165
|
-
const fullName = this.prefix ? `${sanitize(this.prefix)}_${name}` : name;
|
|
7166
|
-
this.reasoners.push({ name: fullName, handler, options });
|
|
7167
|
-
return this;
|
|
7168
|
-
}
|
|
7169
|
-
skill(name, handler, options) {
|
|
7170
|
-
const fullName = this.prefix ? `${sanitize(this.prefix)}_${name}` : name;
|
|
7171
|
-
this.skills.push({ name: fullName, handler, options });
|
|
7172
|
-
return this;
|
|
7173
|
-
}
|
|
7174
|
-
};
|
|
7175
|
-
function sanitize(value) {
|
|
7176
|
-
return value.replace(/[^0-9a-zA-Z]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
|
|
7177
|
-
}
|
|
7178
|
-
var JWE_ALG = "ECDH-ES";
|
|
7179
|
-
var JWE_ENC = "A256GCM";
|
|
7180
|
-
var KEY_AGREEMENT_TYPE = "X25519KeyAgreementKey2020";
|
|
7181
|
-
var PayloadEncryptionError = class extends Error {
|
|
7182
|
-
constructor(message) {
|
|
7183
|
-
super(message);
|
|
7184
|
-
this.name = "PayloadEncryptionError";
|
|
7185
|
-
}
|
|
7186
|
-
};
|
|
7187
|
-
var encoder = new TextEncoder();
|
|
7188
|
-
function payloadToBytes(payload) {
|
|
7189
|
-
if (payload instanceof Uint8Array) return payload;
|
|
7190
|
-
if (typeof payload === "string") return encoder.encode(payload);
|
|
7191
|
-
return encoder.encode(JSON.stringify(payload));
|
|
7192
|
-
}
|
|
7193
|
-
async function generateX25519KeyPair() {
|
|
7194
|
-
const { privateKey, publicKey } = await generateKeyPair("ECDH-ES", {
|
|
7195
|
-
crv: "X25519",
|
|
7196
|
-
extractable: true
|
|
7197
|
-
});
|
|
7198
|
-
const privateJwk = await exportJWK(privateKey);
|
|
7199
|
-
const publicJwk = await exportJWK(publicKey);
|
|
7200
|
-
return { privateJwk, publicJwk };
|
|
7201
|
-
}
|
|
7202
|
-
function extractKeyAgreementJwk(didDocument) {
|
|
7203
|
-
if (typeof didDocument !== "object" || didDocument === null) {
|
|
7204
|
-
throw new PayloadEncryptionError("DID document must be an object");
|
|
7205
|
-
}
|
|
7206
|
-
const doc = didDocument["did_document"] ?? didDocument;
|
|
7207
|
-
const flat = doc["key_agreement"];
|
|
7208
|
-
if (flat && typeof flat === "object" && flat.crv === "X25519") {
|
|
7209
|
-
return flat;
|
|
7210
|
-
}
|
|
7211
|
-
const keyAgreement = doc["keyAgreement"];
|
|
7212
|
-
if (!keyAgreement || Array.isArray(keyAgreement) && keyAgreement.length === 0) {
|
|
7213
|
-
throw new PayloadEncryptionError(
|
|
7214
|
-
"DID document has no keyAgreement key; the agent has not published an X25519 encryption key"
|
|
7215
|
-
);
|
|
7216
|
-
}
|
|
7217
|
-
const verificationMethods = /* @__PURE__ */ new Map();
|
|
7218
|
-
for (const vm2 of doc["verificationMethod"] ?? []) {
|
|
7219
|
-
if (vm2 && typeof vm2 === "object" && typeof vm2["id"] === "string") {
|
|
7220
|
-
verificationMethods.set(vm2["id"], vm2);
|
|
7221
|
-
}
|
|
7222
|
-
}
|
|
7223
|
-
const entry = Array.isArray(keyAgreement) ? keyAgreement[0] : keyAgreement;
|
|
7224
|
-
let vm;
|
|
7225
|
-
if (typeof entry === "string") {
|
|
7226
|
-
vm = verificationMethods.get(entry);
|
|
7227
|
-
if (!vm) {
|
|
7228
|
-
throw new PayloadEncryptionError(
|
|
7229
|
-
`keyAgreement references unknown verification method ${entry}`
|
|
7230
|
-
);
|
|
7231
|
-
}
|
|
7232
|
-
} else if (entry && typeof entry === "object") {
|
|
7233
|
-
vm = entry;
|
|
7234
|
-
} else {
|
|
7235
|
-
throw new PayloadEncryptionError("unsupported keyAgreement entry shape");
|
|
7236
|
-
}
|
|
7237
|
-
const jwk = vm["publicKeyJwk"];
|
|
7238
|
-
if (!jwk || jwk.crv !== "X25519") {
|
|
7239
|
-
throw new PayloadEncryptionError(
|
|
7240
|
-
"keyAgreement verification method does not carry an X25519 publicKeyJwk"
|
|
7241
|
-
);
|
|
7242
|
-
}
|
|
7243
|
-
return jwk;
|
|
7244
|
-
}
|
|
7245
|
-
async function encryptToJwk(publicJwk, payload) {
|
|
7246
|
-
if (!publicJwk || publicJwk.crv !== "X25519") {
|
|
7247
|
-
throw new PayloadEncryptionError("publicJwk must be an X25519 OKP JWK");
|
|
7248
|
-
}
|
|
7249
|
-
try {
|
|
7250
|
-
const key = await importJWK(publicJwk, JWE_ALG);
|
|
7251
|
-
return await new CompactEncrypt(payloadToBytes(payload)).setProtectedHeader({ alg: JWE_ALG, enc: JWE_ENC }).encrypt(key);
|
|
7252
|
-
} catch (err) {
|
|
7253
|
-
if (err instanceof PayloadEncryptionError) throw err;
|
|
7254
|
-
throw new PayloadEncryptionError(`encryption failed: ${err.message}`);
|
|
7255
|
-
}
|
|
7256
|
-
}
|
|
7257
|
-
async function encryptForDid(did, payload, resolver) {
|
|
7258
|
-
const document = await resolver(did);
|
|
7259
|
-
if (!document) {
|
|
7260
|
-
throw new PayloadEncryptionError(`could not resolve DID ${did}`);
|
|
7261
|
-
}
|
|
7262
|
-
const publicJwk = extractKeyAgreementJwk(document);
|
|
7263
|
-
return encryptToJwk(publicJwk, payload);
|
|
7264
|
-
}
|
|
7265
|
-
async function decrypt(token, privateJwk) {
|
|
7266
|
-
try {
|
|
7267
|
-
const key = await importJWK(privateJwk, JWE_ALG);
|
|
7268
|
-
const { plaintext } = await compactDecrypt(token, key);
|
|
7269
|
-
return Uint8Array.from(plaintext);
|
|
7270
|
-
} catch (err) {
|
|
7271
|
-
throw new PayloadEncryptionError(`decryption failed: ${err.message}`);
|
|
7272
|
-
}
|
|
7273
|
-
}
|
|
7274
|
-
async function decryptToString(token, privateJwk) {
|
|
7275
|
-
return new TextDecoder().decode(await decrypt(token, privateJwk));
|
|
7276
|
-
}
|
|
7277
|
-
var IMAGE_MIME_TYPES = {
|
|
7278
|
-
".jpg": "image/jpeg",
|
|
7279
|
-
".jpeg": "image/jpeg",
|
|
7280
|
-
".png": "image/png",
|
|
7281
|
-
".gif": "image/gif",
|
|
7282
|
-
".webp": "image/webp",
|
|
7283
|
-
".bmp": "image/bmp"
|
|
7284
|
-
};
|
|
7285
|
-
var AUDIO_MIME_TYPES = {
|
|
7286
|
-
".wav": "audio/wav",
|
|
7287
|
-
".mp3": "audio/mpeg",
|
|
7288
|
-
".flac": "audio/flac",
|
|
7289
|
-
".ogg": "audio/ogg"
|
|
7290
|
-
};
|
|
7291
|
-
var VIDEO_MIME_TYPES = {
|
|
7292
|
-
".mp4": "video/mp4",
|
|
7293
|
-
".mpeg": "video/mpeg",
|
|
7294
|
-
".mpg": "video/mpeg",
|
|
7295
|
-
".mov": "video/quicktime",
|
|
7296
|
-
".webm": "video/webm"
|
|
7297
|
-
};
|
|
7298
|
-
var Text = class {
|
|
7299
|
-
type = "text";
|
|
7300
|
-
text;
|
|
7301
|
-
constructor(text2) {
|
|
7302
|
-
this.text = text2;
|
|
7303
|
-
}
|
|
7304
|
-
};
|
|
7305
|
-
var Image = class _Image {
|
|
7306
|
-
type = "image_url";
|
|
7307
|
-
imageUrl;
|
|
7308
|
-
constructor(imageUrl) {
|
|
7309
|
-
this.imageUrl = imageUrl;
|
|
7310
|
-
}
|
|
7311
|
-
/**
|
|
7312
|
-
* Create Image from a local file by converting to base64 data URL.
|
|
7313
|
-
*/
|
|
7314
|
-
static async fromFile(filePath, detail = "high") {
|
|
7315
|
-
const absolutePath = resolve(filePath);
|
|
7316
|
-
const buffer = await readFile(absolutePath);
|
|
7317
|
-
const base64Data = buffer.toString("base64");
|
|
7318
|
-
const ext = getExtension(absolutePath).toLowerCase();
|
|
7319
|
-
const mimeType = IMAGE_MIME_TYPES[ext] || "image/jpeg";
|
|
7320
|
-
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
7321
|
-
return new _Image({ url: dataUrl, detail });
|
|
7322
|
-
}
|
|
7323
|
-
/**
|
|
7324
|
-
* Create Image from a URL.
|
|
7325
|
-
*/
|
|
7326
|
-
static fromUrl(url, detail = "high") {
|
|
7327
|
-
return new _Image({ url, detail });
|
|
7328
|
-
}
|
|
7329
|
-
/**
|
|
7330
|
-
* Create Image from a buffer.
|
|
7331
|
-
*/
|
|
7332
|
-
static async fromBuffer(buffer, mimeType = "image/jpeg", detail = "high") {
|
|
7333
|
-
const base64Data = Buffer.from(buffer).toString("base64");
|
|
7334
|
-
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
7335
|
-
return new _Image({ url: dataUrl, detail });
|
|
7336
|
-
}
|
|
7337
|
-
/**
|
|
7338
|
-
* Create Image from a base64 string.
|
|
7339
|
-
*/
|
|
7340
|
-
static async fromBase64(base64Data, mimeType = "image/jpeg", detail = "high") {
|
|
7341
|
-
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
7342
|
-
return new _Image({ url: dataUrl, detail });
|
|
7343
|
-
}
|
|
7344
|
-
};
|
|
7345
|
-
var Audio = class _Audio {
|
|
7346
|
-
type = "input_audio";
|
|
7347
|
-
audio;
|
|
7348
|
-
constructor(audio) {
|
|
7349
|
-
this.audio = audio;
|
|
7350
|
-
}
|
|
7351
|
-
/**
|
|
7352
|
-
* Create Audio from a local file by converting to base64.
|
|
7353
|
-
*/
|
|
7354
|
-
static async fromFile(filePath, format) {
|
|
7355
|
-
const absolutePath = resolve(filePath);
|
|
7356
|
-
const ext = getExtension(absolutePath).toLowerCase().replace(".", "");
|
|
7357
|
-
const audioFormat = format || (["wav", "mp3", "flac", "ogg"].includes(ext) ? ext : "wav");
|
|
7358
|
-
const buffer = await readFile(absolutePath);
|
|
7359
|
-
const base64Data = buffer.toString("base64");
|
|
7360
|
-
return new _Audio({ data: base64Data, format: audioFormat });
|
|
7361
|
-
}
|
|
7362
|
-
/**
|
|
7363
|
-
* Create Audio from a URL (downloads and converts to base64).
|
|
7364
|
-
*/
|
|
7365
|
-
static async fromUrl(url, format = "wav") {
|
|
7366
|
-
try {
|
|
7367
|
-
const response = await fetch(url);
|
|
7368
|
-
if (!response.ok) {
|
|
7369
|
-
throw new Error(`Failed to fetch audio from URL: ${response.status} ${response.statusText}`);
|
|
7370
|
-
}
|
|
7371
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
7372
|
-
const base64Data = Buffer.from(arrayBuffer).toString("base64");
|
|
7373
|
-
return new _Audio({ data: base64Data, format });
|
|
7374
|
-
} catch (error) {
|
|
7375
|
-
if (error instanceof TypeError && error.message.includes("fetch")) {
|
|
7376
|
-
throw new Error("URL download requires a fetch-compatible environment");
|
|
7377
|
-
}
|
|
7378
|
-
throw error;
|
|
7379
|
-
}
|
|
7380
|
-
}
|
|
7381
|
-
/**
|
|
7382
|
-
* Create Audio from a buffer.
|
|
7383
|
-
*/
|
|
7384
|
-
static async fromBuffer(buffer, format = "wav") {
|
|
7385
|
-
const base64Data = Buffer.from(buffer).toString("base64");
|
|
7386
|
-
return new _Audio({ data: base64Data, format });
|
|
7387
|
-
}
|
|
7388
|
-
/**
|
|
7389
|
-
* Create Audio from a base64 string.
|
|
7390
|
-
*/
|
|
7391
|
-
static async fromBase64(base64Data, format = "wav") {
|
|
7392
|
-
return new _Audio({ data: base64Data, format });
|
|
7393
|
-
}
|
|
7394
|
-
};
|
|
7395
|
-
var Video = class _Video {
|
|
7396
|
-
type = "video_url";
|
|
7397
|
-
videoUrl;
|
|
7398
|
-
constructor(videoUrl) {
|
|
7399
|
-
this.videoUrl = videoUrl;
|
|
7467
|
+
parseTarget(target) {
|
|
7468
|
+
if (!target.includes(".")) {
|
|
7469
|
+
return { name: target };
|
|
7470
|
+
}
|
|
7471
|
+
const [agentId, remainder] = target.split(".", 2);
|
|
7472
|
+
const name = remainder.replace(":", "/");
|
|
7473
|
+
return { agentId, name };
|
|
7400
7474
|
}
|
|
7401
|
-
|
|
7402
|
-
|
|
7403
|
-
|
|
7404
|
-
|
|
7405
|
-
|
|
7406
|
-
|
|
7407
|
-
|
|
7408
|
-
|
|
7409
|
-
|
|
7410
|
-
|
|
7475
|
+
};
|
|
7476
|
+
|
|
7477
|
+
// src/router/AgentRouter.ts
|
|
7478
|
+
var AgentRouter = class {
|
|
7479
|
+
prefix;
|
|
7480
|
+
tags;
|
|
7481
|
+
reasoners = [];
|
|
7482
|
+
skills = [];
|
|
7483
|
+
constructor(options = {}) {
|
|
7484
|
+
this.prefix = options.prefix;
|
|
7485
|
+
this.tags = options.tags;
|
|
7411
7486
|
}
|
|
7412
|
-
|
|
7413
|
-
|
|
7414
|
-
|
|
7415
|
-
|
|
7416
|
-
return new _Video({ url });
|
|
7487
|
+
reasoner(name, handler, options) {
|
|
7488
|
+
const fullName = this.prefix ? `${sanitize(this.prefix)}_${name}` : name;
|
|
7489
|
+
this.reasoners.push({ name: fullName, handler, options });
|
|
7490
|
+
return this;
|
|
7417
7491
|
}
|
|
7418
|
-
|
|
7419
|
-
|
|
7420
|
-
|
|
7421
|
-
|
|
7422
|
-
const base64Data = Buffer.from(buffer).toString("base64");
|
|
7423
|
-
return new _Video({ url: `data:${mimeType};base64,${base64Data}` });
|
|
7492
|
+
skill(name, handler, options) {
|
|
7493
|
+
const fullName = this.prefix ? `${sanitize(this.prefix)}_${name}` : name;
|
|
7494
|
+
this.skills.push({ name: fullName, handler, options });
|
|
7495
|
+
return this;
|
|
7424
7496
|
}
|
|
7425
|
-
|
|
7426
|
-
|
|
7427
|
-
|
|
7428
|
-
|
|
7429
|
-
|
|
7497
|
+
};
|
|
7498
|
+
function sanitize(value) {
|
|
7499
|
+
return value.replace(/[^0-9a-zA-Z]+/g, "_").replace(/_+/g, "_").replace(/^_+|_+$/g, "");
|
|
7500
|
+
}
|
|
7501
|
+
var JWE_ALG = "ECDH-ES";
|
|
7502
|
+
var JWE_ENC = "A256GCM";
|
|
7503
|
+
var KEY_AGREEMENT_TYPE = "X25519KeyAgreementKey2020";
|
|
7504
|
+
var PayloadEncryptionError = class extends Error {
|
|
7505
|
+
constructor(message) {
|
|
7506
|
+
super(message);
|
|
7507
|
+
this.name = "PayloadEncryptionError";
|
|
7430
7508
|
}
|
|
7431
7509
|
};
|
|
7432
|
-
var
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7510
|
+
var encoder = new TextEncoder();
|
|
7511
|
+
function payloadToBytes(payload) {
|
|
7512
|
+
if (payload instanceof Uint8Array) return payload;
|
|
7513
|
+
if (typeof payload === "string") return encoder.encode(payload);
|
|
7514
|
+
return encoder.encode(JSON.stringify(payload));
|
|
7515
|
+
}
|
|
7516
|
+
async function generateX25519KeyPair() {
|
|
7517
|
+
const { privateKey, publicKey } = await generateKeyPair("ECDH-ES", {
|
|
7518
|
+
crv: "X25519",
|
|
7519
|
+
extractable: true
|
|
7520
|
+
});
|
|
7521
|
+
const privateJwk = await exportJWK(privateKey);
|
|
7522
|
+
const publicJwk = await exportJWK(publicKey);
|
|
7523
|
+
return { privateJwk, publicJwk };
|
|
7524
|
+
}
|
|
7525
|
+
function extractKeyAgreementJwk(didDocument) {
|
|
7526
|
+
if (typeof didDocument !== "object" || didDocument === null) {
|
|
7527
|
+
throw new PayloadEncryptionError("DID document must be an object");
|
|
7437
7528
|
}
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
const absolutePath = resolve(filePath);
|
|
7443
|
-
const detectedMimeType = mimeType || guessMimeType(absolutePath) || "application/octet-stream";
|
|
7444
|
-
const buffer = await readFile(absolutePath);
|
|
7445
|
-
const base64Data = buffer.toString("base64");
|
|
7446
|
-
const dataUrl = `data:${detectedMimeType};base64,${base64Data}`;
|
|
7447
|
-
return new _File({ url: dataUrl, mimeType: detectedMimeType });
|
|
7529
|
+
const doc = didDocument["did_document"] ?? didDocument;
|
|
7530
|
+
const flat = doc["key_agreement"];
|
|
7531
|
+
if (flat && typeof flat === "object" && flat.crv === "X25519") {
|
|
7532
|
+
return flat;
|
|
7448
7533
|
}
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7534
|
+
const keyAgreement = doc["keyAgreement"];
|
|
7535
|
+
if (!keyAgreement || Array.isArray(keyAgreement) && keyAgreement.length === 0) {
|
|
7536
|
+
throw new PayloadEncryptionError(
|
|
7537
|
+
"DID document has no keyAgreement key; the agent has not published an X25519 encryption key"
|
|
7538
|
+
);
|
|
7454
7539
|
}
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
const dataUrl = `data:${mimeType};base64,${base64Data}`;
|
|
7461
|
-
return new _File({ url: dataUrl, mimeType });
|
|
7540
|
+
const verificationMethods = /* @__PURE__ */ new Map();
|
|
7541
|
+
for (const vm2 of doc["verificationMethod"] ?? []) {
|
|
7542
|
+
if (vm2 && typeof vm2 === "object" && typeof vm2["id"] === "string") {
|
|
7543
|
+
verificationMethods.set(vm2["id"], vm2);
|
|
7544
|
+
}
|
|
7462
7545
|
}
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7546
|
+
const entry = Array.isArray(keyAgreement) ? keyAgreement[0] : keyAgreement;
|
|
7547
|
+
let vm;
|
|
7548
|
+
if (typeof entry === "string") {
|
|
7549
|
+
vm = verificationMethods.get(entry);
|
|
7550
|
+
if (!vm) {
|
|
7551
|
+
throw new PayloadEncryptionError(
|
|
7552
|
+
`keyAgreement references unknown verification method ${entry}`
|
|
7553
|
+
);
|
|
7554
|
+
}
|
|
7555
|
+
} else if (entry && typeof entry === "object") {
|
|
7556
|
+
vm = entry;
|
|
7557
|
+
} else {
|
|
7558
|
+
throw new PayloadEncryptionError("unsupported keyAgreement entry shape");
|
|
7469
7559
|
}
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7560
|
+
const jwk = vm["publicKeyJwk"];
|
|
7561
|
+
if (!jwk || jwk.crv !== "X25519") {
|
|
7562
|
+
throw new PayloadEncryptionError(
|
|
7563
|
+
"keyAgreement verification method does not carry an X25519 publicKeyJwk"
|
|
7564
|
+
);
|
|
7475
7565
|
}
|
|
7476
|
-
return
|
|
7566
|
+
return jwk;
|
|
7477
7567
|
}
|
|
7478
|
-
function
|
|
7479
|
-
|
|
7480
|
-
|
|
7481
|
-
return IMAGE_MIME_TYPES[ext];
|
|
7482
|
-
}
|
|
7483
|
-
if (ext in AUDIO_MIME_TYPES) {
|
|
7484
|
-
return AUDIO_MIME_TYPES[ext];
|
|
7568
|
+
async function encryptToJwk(publicJwk, payload) {
|
|
7569
|
+
if (!publicJwk || publicJwk.crv !== "X25519") {
|
|
7570
|
+
throw new PayloadEncryptionError("publicJwk must be an X25519 OKP JWK");
|
|
7485
7571
|
}
|
|
7486
|
-
|
|
7487
|
-
|
|
7572
|
+
try {
|
|
7573
|
+
const key = await importJWK(publicJwk, JWE_ALG);
|
|
7574
|
+
return await new CompactEncrypt(payloadToBytes(payload)).setProtectedHeader({ alg: JWE_ALG, enc: JWE_ENC }).encrypt(key);
|
|
7575
|
+
} catch (err) {
|
|
7576
|
+
if (err instanceof PayloadEncryptionError) throw err;
|
|
7577
|
+
throw new PayloadEncryptionError(`encryption failed: ${err.message}`);
|
|
7488
7578
|
}
|
|
7489
|
-
const documentMimeTypes = {
|
|
7490
|
-
".pdf": "application/pdf",
|
|
7491
|
-
".doc": "application/msword",
|
|
7492
|
-
".docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
|
7493
|
-
".xls": "application/vnd.ms-excel",
|
|
7494
|
-
".xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
7495
|
-
".txt": "text/plain",
|
|
7496
|
-
".csv": "text/csv",
|
|
7497
|
-
".html": "text/html",
|
|
7498
|
-
".json": "application/json",
|
|
7499
|
-
".xml": "application/xml",
|
|
7500
|
-
".zip": "application/zip"
|
|
7501
|
-
};
|
|
7502
|
-
return documentMimeTypes[ext] || null;
|
|
7503
|
-
}
|
|
7504
|
-
function text(content) {
|
|
7505
|
-
return new Text(content);
|
|
7506
|
-
}
|
|
7507
|
-
async function imageFromFile(filePath, detail = "high") {
|
|
7508
|
-
return Image.fromFile(filePath, detail);
|
|
7509
|
-
}
|
|
7510
|
-
function imageFromUrl(url, detail = "high") {
|
|
7511
|
-
return Image.fromUrl(url, detail);
|
|
7512
|
-
}
|
|
7513
|
-
async function imageFromBuffer(buffer, mimeType = "image/jpeg", detail = "high") {
|
|
7514
|
-
return Image.fromBuffer(buffer, mimeType, detail);
|
|
7515
|
-
}
|
|
7516
|
-
async function imageFromBase64(base64Data, mimeType, detail = "high") {
|
|
7517
|
-
return Image.fromBase64(base64Data, mimeType, detail);
|
|
7518
|
-
}
|
|
7519
|
-
async function audioFromFile(filePath, format) {
|
|
7520
|
-
return Audio.fromFile(filePath, format);
|
|
7521
|
-
}
|
|
7522
|
-
async function audioFromUrl(url, format = "wav") {
|
|
7523
|
-
return Audio.fromUrl(url, format);
|
|
7524
|
-
}
|
|
7525
|
-
async function audioFromBuffer(buffer, format = "wav") {
|
|
7526
|
-
return Audio.fromBuffer(buffer, format);
|
|
7527
|
-
}
|
|
7528
|
-
async function audioFromBase64(base64Data, format = "wav") {
|
|
7529
|
-
return Audio.fromBase64(base64Data, format);
|
|
7530
|
-
}
|
|
7531
|
-
async function videoFromFile(filePath) {
|
|
7532
|
-
return Video.fromFile(filePath);
|
|
7533
|
-
}
|
|
7534
|
-
function videoFromUrl(url) {
|
|
7535
|
-
return Video.fromUrl(url);
|
|
7536
7579
|
}
|
|
7537
|
-
async function
|
|
7538
|
-
|
|
7539
|
-
|
|
7540
|
-
|
|
7541
|
-
|
|
7542
|
-
|
|
7543
|
-
|
|
7544
|
-
return File.fromFile(filePath, mimeType);
|
|
7545
|
-
}
|
|
7546
|
-
function fileFromUrl(url, mimeType) {
|
|
7547
|
-
return File.fromUrl(url, mimeType);
|
|
7580
|
+
async function encryptForDid(did, payload, resolver) {
|
|
7581
|
+
const document = await resolver(did);
|
|
7582
|
+
if (!document) {
|
|
7583
|
+
throw new PayloadEncryptionError(`could not resolve DID ${did}`);
|
|
7584
|
+
}
|
|
7585
|
+
const publicJwk = extractKeyAgreementJwk(document);
|
|
7586
|
+
return encryptToJwk(publicJwk, payload);
|
|
7548
7587
|
}
|
|
7549
|
-
async function
|
|
7550
|
-
|
|
7588
|
+
async function decrypt(token, privateJwk) {
|
|
7589
|
+
try {
|
|
7590
|
+
const key = await importJWK(privateJwk, JWE_ALG);
|
|
7591
|
+
const { plaintext } = await compactDecrypt(token, key);
|
|
7592
|
+
return Uint8Array.from(plaintext);
|
|
7593
|
+
} catch (err) {
|
|
7594
|
+
throw new PayloadEncryptionError(`decryption failed: ${err.message}`);
|
|
7595
|
+
}
|
|
7551
7596
|
}
|
|
7552
|
-
async function
|
|
7553
|
-
return
|
|
7597
|
+
async function decryptToString(token, privateJwk) {
|
|
7598
|
+
return new TextDecoder().decode(await decrypt(token, privateJwk));
|
|
7554
7599
|
}
|
|
7555
7600
|
var MultimodalResponse = class {
|
|
7556
7601
|
_text;
|
|
@@ -8589,6 +8634,6 @@ function loadFixture(source) {
|
|
|
8589
8634
|
);
|
|
8590
8635
|
}
|
|
8591
8636
|
|
|
8592
|
-
export { ACTIVE_STATUSES, AIClient, Agent, AgentRouter, ApprovalClient, ApprovalResult, Audio, CANONICAL_STATUSES, CostTracker, DIDAuthenticator, DidClient, DidInterface, DidManager, ExecutionContext, ExecutionLogger, ExecutionStatus, File, HEADER_CALLER_DID, HEADER_DID_NONCE, HEADER_DID_SIGNATURE, HEADER_DID_TIMESTAMP, HarnessRunner, Image, JWE_ALG, JWE_ENC, KEY_AGREEMENT_TYPE, MODEL_VARIANT_SEP, MediaProviderError, MediaRouter, MemoryClient, MemoryClientBase, MemoryEventClient, MemoryInterface, MultimodalResponse, OpenRouterMediaProvider, PauseClock, PauseManager, PayloadEncryptionError, RateLimitError, RealtimeSession, ReasonerContext, SUPPORTED_PROVIDERS, SUPPORTED_SESSION_TRANSPORTS, SessionTransportError, SkillContext, StatelessRateLimiter, TERMINAL_STATUSES, Text, USAGE_ENVELOPE_KEY, Video, WorkflowReporter, applyTriggerTransform, attachUsageToSyncResult, audioFromBase64, audioFromBuffer, audioFromFile, audioFromUrl, buildProvider, buildSessionDefinition, buildToolConfig, capabilitiesToTools, capabilityToMetadataTool, capabilityToTool, createExecutionLogger, createHarnessResult, createMetrics, createMultimodalResponse, createRawResult, decrypt, decryptToString, deriveProvider, encryptForDid, encryptToJwk, eventTrigger, executeToolCallLoop, extractKeyAgreementJwk, fileFromBase64, fileFromBuffer, fileFromPath, fileFromUrl, generateX25519KeyPair, getCurrentContext, getCurrentSkillContext, imageFromBase64, imageFromBuffer, imageFromFile, imageFromUrl, installApprovalWebhookRoute, isActive, isExecutionLogBatchPayload, isTerminal, isTriggerEnvelope, loadFixture, normalizeExecutionLogEntry, normalizeSessionTransportValue, normalizeStatus, resolveModelAndVariant, scheduleTrigger, serializeExecutionLogEntry, simulateSchedule, simulateTrigger, splitModelVariant, text, triggerToPayload, unwrapEnvelope, usageSummaryOrNull, validateSessionTransport, videoFromBase64, videoFromBuffer, videoFromFile, videoFromUrl };
|
|
8637
|
+
export { ACTIVE_STATUSES, AIClient, Agent, AgentRouter, ApprovalClient, ApprovalResult, Audio, CANONICAL_STATUSES, CostTracker, DIDAuthenticator, DidClient, DidInterface, DidManager, ExecutionContext, ExecutionLogger, ExecutionStatus, File, HEADER_CALLER_DID, HEADER_DID_NONCE, HEADER_DID_SIGNATURE, HEADER_DID_TIMESTAMP, HarnessRunner, Image, JWE_ALG, JWE_ENC, KEY_AGREEMENT_TYPE, MODEL_VARIANT_SEP, MediaProviderError, MediaRouter, MemoryClient, MemoryClientBase, MemoryEventClient, MemoryInterface, MultimodalResponse, OpenRouterMediaProvider, PauseClock, PauseManager, PayloadEncryptionError, RateLimitError, RealtimeSession, ReasonerContext, SUPPORTED_PROVIDERS, SUPPORTED_SESSION_TRANSPORTS, SessionTransportError, SkillContext, StatelessRateLimiter, TERMINAL_STATUSES, Text, USAGE_ENVELOPE_KEY, Video, WorkflowReporter, applyTriggerTransform, attachUsageToSyncResult, audioFromBase64, audioFromBuffer, audioFromFile, audioFromUrl, audioMediaType, buildProvider, buildSessionDefinition, buildToolConfig, capabilitiesToTools, capabilityToMetadataTool, capabilityToTool, createExecutionLogger, createHarnessResult, createMetrics, createMultimodalResponse, createRawResult, decrypt, decryptToString, deriveProvider, encryptForDid, encryptToJwk, eventTrigger, executeToolCallLoop, extractKeyAgreementJwk, fileFromBase64, fileFromBuffer, fileFromPath, fileFromUrl, generateX25519KeyPair, getCurrentContext, getCurrentSkillContext, guessUrlMimeType, imageFromBase64, imageFromBuffer, imageFromFile, imageFromUrl, installApprovalWebhookRoute, isActive, isExecutionLogBatchPayload, isTerminal, isTriggerEnvelope, loadFixture, normalizeExecutionLogEntry, normalizeSessionTransportValue, normalizeStatus, resolveModelAndVariant, scheduleTrigger, serializeExecutionLogEntry, simulateSchedule, simulateTrigger, splitModelVariant, text, triggerToPayload, unwrapEnvelope, usageSummaryOrNull, validateSessionTransport, videoFromBase64, videoFromBuffer, videoFromFile, videoFromUrl };
|
|
8593
8638
|
//# sourceMappingURL=index.js.map
|
|
8594
8639
|
//# sourceMappingURL=index.js.map
|