@perstack/runtime 0.0.71 → 0.0.72

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.
@@ -12,17 +12,17 @@ import { createVertex } from '@ai-sdk/google-vertex';
12
12
  import { createOpenAI } from '@ai-sdk/openai';
13
13
  import { createOllama } from 'ollama-ai-provider-v2';
14
14
  import { ProxyAgent, fetch } from 'undici';
15
- import { ApiV1Client } from '@perstack/api-client/v1';
15
+ import { createApiClient } from '@perstack/api-client';
16
16
  import { setup, assign, createActor } from 'xstate';
17
17
  import { readFile } from 'fs/promises';
18
18
  import { createId } from '@paralleldrive/cuid2';
19
19
  import { dedent } from 'ts-dedent';
20
- import { generateText, streamText } from 'ai';
20
+ import { APICallError, generateText, streamText } from 'ai';
21
21
 
22
22
  // package.json
23
23
  var package_default = {
24
24
  name: "@perstack/runtime",
25
- version: "0.0.71",
25
+ version: "0.0.72",
26
26
  description: "Perstack Runtime",
27
27
  author: "Wintermute Technologies, Inc.",
28
28
  license: "Apache-2.0",
@@ -63,18 +63,9 @@ var package_default = {
63
63
  "@ai-sdk/openai": "^2.0.0",
64
64
  "@modelcontextprotocol/sdk": "^1.25.1",
65
65
  "@paralleldrive/cuid2": "^3.0.4",
66
- "@perstack/anthropic-provider": "workspace:*",
67
66
  "@perstack/api-client": "workspace:*",
68
67
  "@perstack/base": "workspace:*",
69
- "@perstack/azure-openai-provider": "workspace:*",
70
- "@perstack/bedrock-provider": "workspace:*",
71
68
  "@perstack/core": "workspace:*",
72
- "@perstack/deepseek-provider": "workspace:*",
73
- "@perstack/google-provider": "workspace:*",
74
- "@perstack/ollama-provider": "workspace:*",
75
- "@perstack/openai-provider": "workspace:*",
76
- "@perstack/provider-core": "workspace:*",
77
- "@perstack/vertex-provider": "workspace:*",
78
69
  ai: "^5.0.115",
79
70
  "ollama-ai-provider-v2": "^1.5.5",
80
71
  commander: "^14.0.2",
@@ -345,12 +336,15 @@ async function resolveExpertToRun(expertKey, experts, clientOptions) {
345
336
  if (experts[expertKey]) {
346
337
  return experts[expertKey];
347
338
  }
348
- const client = new ApiV1Client({
339
+ const client = createApiClient({
349
340
  baseUrl: clientOptions.perstackApiBaseUrl,
350
341
  apiKey: clientOptions.perstackApiKey
351
342
  });
352
- const { expert } = await client.registry.experts.get({ expertKey });
353
- return toRuntimeExpert(expert);
343
+ const result = await client.registry.experts.get(expertKey);
344
+ if (!result.ok) {
345
+ throw new Error(`Failed to resolve expert "${expertKey}": ${result.error.message}`);
346
+ }
347
+ return toRuntimeExpert(result.data);
354
348
  }
355
349
  function toRuntimeExpert(expert) {
356
350
  const skills = Object.fromEntries(
@@ -2276,40 +2270,1066 @@ async function createProviderAdapter(config, options) {
2276
2270
  pendingCreations.set(cacheKey, creationPromise);
2277
2271
  return creationPromise;
2278
2272
  }
2273
+ var BaseProviderAdapter = class {
2274
+ options;
2275
+ constructor(options) {
2276
+ this.options = options;
2277
+ }
2278
+ getProviderTools(_toolNames, _options) {
2279
+ return {};
2280
+ }
2281
+ getProviderOptions(_config) {
2282
+ return void 0;
2283
+ }
2284
+ getReasoningOptions(_budget) {
2285
+ return void 0;
2286
+ }
2287
+ normalizeError(error) {
2288
+ if (error instanceof Error) {
2289
+ return {
2290
+ name: error.name,
2291
+ message: error.message,
2292
+ isRetryable: this.isRetryable(error),
2293
+ provider: this.providerName,
2294
+ originalError: error
2295
+ };
2296
+ }
2297
+ return {
2298
+ name: "UnknownError",
2299
+ message: String(error),
2300
+ isRetryable: false,
2301
+ provider: this.providerName,
2302
+ originalError: error
2303
+ };
2304
+ }
2305
+ isRetryable(error) {
2306
+ if (error instanceof Error) {
2307
+ const retryablePatterns = [
2308
+ /rate limit/i,
2309
+ /timeout/i,
2310
+ /overloaded/i,
2311
+ /service unavailable/i,
2312
+ /internal server error/i,
2313
+ /bad gateway/i,
2314
+ /gateway timeout/i
2315
+ ];
2316
+ return retryablePatterns.some((pattern) => pattern.test(error.message));
2317
+ }
2318
+ return false;
2319
+ }
2320
+ createProxyFetch(proxyUrl) {
2321
+ const agent = new ProxyAgent(proxyUrl);
2322
+ return (input, init) => {
2323
+ return fetch(input, { ...init, dispatcher: agent });
2324
+ };
2325
+ }
2326
+ };
2327
+ function normalizeAnthropicError(error) {
2328
+ if (error instanceof APICallError) {
2329
+ return {
2330
+ name: error.name,
2331
+ message: error.message,
2332
+ statusCode: error.statusCode,
2333
+ isRetryable: isAnthropicRetryable(error),
2334
+ provider: "anthropic",
2335
+ originalError: error
2336
+ };
2337
+ }
2338
+ if (error instanceof Error) {
2339
+ return {
2340
+ name: error.name,
2341
+ message: error.message,
2342
+ isRetryable: isAnthropicRetryable(error),
2343
+ provider: "anthropic",
2344
+ originalError: error
2345
+ };
2346
+ }
2347
+ return {
2348
+ name: "UnknownError",
2349
+ message: String(error),
2350
+ isRetryable: false,
2351
+ provider: "anthropic",
2352
+ originalError: error
2353
+ };
2354
+ }
2355
+ function isAnthropicRetryable(error) {
2356
+ if (error instanceof APICallError) {
2357
+ if (error.isRetryable) return true;
2358
+ const statusCode = error.statusCode;
2359
+ if (statusCode === 429) return true;
2360
+ if (statusCode === 500) return true;
2361
+ if (statusCode === 502) return true;
2362
+ if (statusCode === 503) return true;
2363
+ if (statusCode === 504) return true;
2364
+ }
2365
+ if (error instanceof Error) {
2366
+ const message = error.message.toLowerCase();
2367
+ if (message.includes("rate limit")) return true;
2368
+ if (message.includes("overloaded")) return true;
2369
+ if (message.includes("timeout")) return true;
2370
+ if (message.includes("service unavailable")) return true;
2371
+ }
2372
+ return false;
2373
+ }
2374
+
2375
+ // ../../packages/providers/anthropic/src/skills.ts
2376
+ function convertSkill(skill) {
2377
+ if (skill.type === "builtin") {
2378
+ return {
2379
+ type: "builtin",
2380
+ name: skill.skillId
2381
+ };
2382
+ }
2383
+ try {
2384
+ return {
2385
+ type: "custom",
2386
+ name: skill.name,
2387
+ mcp_config: JSON.parse(skill.definition)
2388
+ };
2389
+ } catch (error) {
2390
+ throw new Error(
2391
+ `Invalid JSON in custom skill definition for "${skill.name}": ${error instanceof Error ? error.message : String(error)}`
2392
+ );
2393
+ }
2394
+ }
2395
+ function buildProviderOptions(skills) {
2396
+ if (!skills || skills.length === 0) {
2397
+ return void 0;
2398
+ }
2399
+ return {
2400
+ anthropic: {
2401
+ container: {
2402
+ skills: skills.map(convertSkill)
2403
+ }
2404
+ }
2405
+ };
2406
+ }
2407
+
2408
+ // ../../packages/providers/anthropic/src/tools.ts
2409
+ function buildAnthropicTools(client, toolNames, options) {
2410
+ const tools = {};
2411
+ for (const name of toolNames) {
2412
+ switch (name) {
2413
+ case "webSearch": {
2414
+ const webSearchTool = client.tools.webSearch_20250305({
2415
+ maxUses: options?.webSearch?.maxUses,
2416
+ allowedDomains: options?.webSearch?.allowedDomains
2417
+ });
2418
+ tools["web_search"] = webSearchTool;
2419
+ break;
2420
+ }
2421
+ case "webFetch": {
2422
+ const webFetchTool = client.tools.webFetch_20250910({
2423
+ maxUses: options?.webFetch?.maxUses
2424
+ });
2425
+ tools["web_fetch"] = webFetchTool;
2426
+ break;
2427
+ }
2428
+ case "codeExecution": {
2429
+ const codeExecutionTool = client.tools.codeExecution_20250522();
2430
+ tools["code_execution"] = codeExecutionTool;
2431
+ break;
2432
+ }
2433
+ }
2434
+ }
2435
+ return tools;
2436
+ }
2437
+
2438
+ // ../../packages/providers/anthropic/src/adapter.ts
2439
+ var AnthropicProviderAdapter = class extends BaseProviderAdapter {
2440
+ constructor(config, options) {
2441
+ super(options);
2442
+ this.config = config;
2443
+ this.client = createAnthropic({
2444
+ apiKey: config.apiKey,
2445
+ baseURL: config.baseUrl,
2446
+ headers: config.headers,
2447
+ fetch: options?.proxyUrl ? this.createProxyFetch(options.proxyUrl) : void 0
2448
+ });
2449
+ }
2450
+ providerName = "anthropic";
2451
+ client;
2452
+ createModel(modelId) {
2453
+ return this.client(modelId);
2454
+ }
2455
+ getProviderTools(toolNames, options) {
2456
+ return buildAnthropicTools(this.client, toolNames, options);
2457
+ }
2458
+ getProviderOptions(config) {
2459
+ return buildProviderOptions(config?.skills);
2460
+ }
2461
+ getReasoningOptions(budget) {
2462
+ const budgetTokens = this.budgetToTokens(budget);
2463
+ return {
2464
+ anthropic: {
2465
+ thinking: { type: "enabled", budgetTokens }
2466
+ }
2467
+ };
2468
+ }
2469
+ budgetToTokens(budget) {
2470
+ if (typeof budget === "number") return budget;
2471
+ const map = {
2472
+ minimal: 1024,
2473
+ low: 2048,
2474
+ medium: 5e3,
2475
+ high: 1e4
2476
+ };
2477
+ return map[budget] ?? 5e3;
2478
+ }
2479
+ normalizeError(error) {
2480
+ return normalizeAnthropicError(error);
2481
+ }
2482
+ isRetryable(error) {
2483
+ return isAnthropicRetryable(error);
2484
+ }
2485
+ };
2486
+ function normalizeAzureOpenAIError(error) {
2487
+ if (error instanceof APICallError) {
2488
+ return {
2489
+ name: error.name,
2490
+ message: error.message,
2491
+ statusCode: error.statusCode,
2492
+ isRetryable: isAzureOpenAIRetryable(error),
2493
+ provider: "azure-openai",
2494
+ originalError: error
2495
+ };
2496
+ }
2497
+ if (error instanceof Error) {
2498
+ return {
2499
+ name: error.name,
2500
+ message: error.message,
2501
+ isRetryable: isAzureOpenAIRetryable(error),
2502
+ provider: "azure-openai",
2503
+ originalError: error
2504
+ };
2505
+ }
2506
+ return {
2507
+ name: "UnknownError",
2508
+ message: String(error),
2509
+ isRetryable: false,
2510
+ provider: "azure-openai",
2511
+ originalError: error
2512
+ };
2513
+ }
2514
+ function isAzureOpenAIRetryable(error) {
2515
+ if (error instanceof APICallError) {
2516
+ if (error.isRetryable) return true;
2517
+ const statusCode = error.statusCode;
2518
+ if (statusCode === 429) return true;
2519
+ if (statusCode === 500) return true;
2520
+ if (statusCode === 502) return true;
2521
+ if (statusCode === 503) return true;
2522
+ if (statusCode === 504) return true;
2523
+ }
2524
+ if (error instanceof Error) {
2525
+ const message = error.message.toLowerCase();
2526
+ if (message.includes("rate limit")) return true;
2527
+ if (message.includes("timeout")) return true;
2528
+ if (message.includes("service unavailable")) return true;
2529
+ }
2530
+ return false;
2531
+ }
2532
+
2533
+ // ../../packages/providers/azure-openai/src/tools.ts
2534
+ function buildAzureOpenAITools(client, toolNames, options) {
2535
+ const tools = {};
2536
+ for (const name of toolNames) {
2537
+ switch (name) {
2538
+ case "webSearchPreview": {
2539
+ const webSearchTool = client.tools.webSearchPreview({});
2540
+ tools["web_search_preview"] = webSearchTool;
2541
+ break;
2542
+ }
2543
+ case "fileSearch": {
2544
+ const vectorStoreIds = options?.fileSearch?.vectorStoreIds;
2545
+ if (!vectorStoreIds || vectorStoreIds.length === 0) {
2546
+ console.warn(
2547
+ "Azure OpenAI fileSearch tool requires vectorStoreIds. Set providerToolOptions.fileSearch.vectorStoreIds to use this tool."
2548
+ );
2549
+ break;
2550
+ }
2551
+ const fileSearchTool = client.tools.fileSearch({
2552
+ vectorStoreIds,
2553
+ maxNumResults: options?.fileSearch?.maxNumResults
2554
+ });
2555
+ tools["file_search"] = fileSearchTool;
2556
+ break;
2557
+ }
2558
+ case "codeInterpreter": {
2559
+ const codeInterpreterTool = client.tools.codeInterpreter();
2560
+ tools["code_interpreter"] = codeInterpreterTool;
2561
+ break;
2562
+ }
2563
+ case "imageGeneration": {
2564
+ const imageGenerationTool = client.tools.imageGeneration();
2565
+ tools["image_generation"] = imageGenerationTool;
2566
+ break;
2567
+ }
2568
+ }
2569
+ }
2570
+ return tools;
2571
+ }
2572
+
2573
+ // ../../packages/providers/azure-openai/src/adapter.ts
2574
+ var AzureOpenAIProviderAdapter = class extends BaseProviderAdapter {
2575
+ constructor(config, options) {
2576
+ super(options);
2577
+ this.config = config;
2578
+ this.client = createAzure({
2579
+ apiKey: config.apiKey,
2580
+ resourceName: config.resourceName,
2581
+ apiVersion: config.apiVersion,
2582
+ baseURL: config.baseUrl,
2583
+ headers: config.headers,
2584
+ useDeploymentBasedUrls: config.useDeploymentBasedUrls,
2585
+ fetch: options?.proxyUrl ? this.createProxyFetch(options.proxyUrl) : void 0
2586
+ });
2587
+ }
2588
+ providerName = "azure-openai";
2589
+ client;
2590
+ createModel(modelId) {
2591
+ return this.client(modelId);
2592
+ }
2593
+ getProviderTools(toolNames, options) {
2594
+ return buildAzureOpenAITools(this.client, toolNames, options);
2595
+ }
2596
+ normalizeError(error) {
2597
+ return normalizeAzureOpenAIError(error);
2598
+ }
2599
+ isRetryable(error) {
2600
+ return isAzureOpenAIRetryable(error);
2601
+ }
2602
+ };
2603
+ function normalizeBedrockError(error) {
2604
+ if (error instanceof APICallError) {
2605
+ return {
2606
+ name: error.name,
2607
+ message: error.message,
2608
+ statusCode: error.statusCode,
2609
+ isRetryable: isBedrockRetryable(error),
2610
+ provider: "amazon-bedrock",
2611
+ originalError: error
2612
+ };
2613
+ }
2614
+ if (error instanceof Error) {
2615
+ return {
2616
+ name: error.name,
2617
+ message: error.message,
2618
+ isRetryable: isBedrockRetryable(error),
2619
+ provider: "amazon-bedrock",
2620
+ originalError: error
2621
+ };
2622
+ }
2623
+ return {
2624
+ name: "UnknownError",
2625
+ message: String(error),
2626
+ isRetryable: false,
2627
+ provider: "amazon-bedrock",
2628
+ originalError: error
2629
+ };
2630
+ }
2631
+ function isBedrockRetryable(error) {
2632
+ if (error instanceof APICallError) {
2633
+ if (error.isRetryable) return true;
2634
+ const statusCode = error.statusCode;
2635
+ if (statusCode === 429) return true;
2636
+ if (statusCode === 500) return true;
2637
+ if (statusCode === 502) return true;
2638
+ if (statusCode === 503) return true;
2639
+ if (statusCode === 504) return true;
2640
+ }
2641
+ if (error instanceof Error) {
2642
+ const message = error.message.toLowerCase();
2643
+ if (message.includes("rate limit")) return true;
2644
+ if (message.includes("throttl")) return true;
2645
+ if (message.includes("timeout")) return true;
2646
+ if (message.includes("service unavailable")) return true;
2647
+ }
2648
+ return false;
2649
+ }
2650
+
2651
+ // ../../packages/providers/bedrock/src/adapter.ts
2652
+ var BedrockProviderAdapter = class extends BaseProviderAdapter {
2653
+ constructor(config, options) {
2654
+ super(options);
2655
+ this.config = config;
2656
+ this.client = createAmazonBedrock({
2657
+ accessKeyId: config.accessKeyId,
2658
+ secretAccessKey: config.secretAccessKey,
2659
+ region: config.region,
2660
+ sessionToken: config.sessionToken,
2661
+ fetch: options?.proxyUrl ? this.createProxyFetch(options.proxyUrl) : void 0
2662
+ });
2663
+ }
2664
+ providerName = "amazon-bedrock";
2665
+ client;
2666
+ createModel(modelId) {
2667
+ return this.client(modelId);
2668
+ }
2669
+ getProviderOptions(config) {
2670
+ if (!config?.guardrails && !config?.cachePoint) {
2671
+ return void 0;
2672
+ }
2673
+ const bedrockOptions = {};
2674
+ if (config.guardrails) {
2675
+ const guardrailConfig = {
2676
+ guardrailIdentifier: config.guardrails.guardrailIdentifier,
2677
+ guardrailVersion: config.guardrails.guardrailVersion
2678
+ };
2679
+ if (config.guardrails.trace) {
2680
+ guardrailConfig["trace"] = config.guardrails.trace;
2681
+ }
2682
+ bedrockOptions["guardrailConfig"] = guardrailConfig;
2683
+ }
2684
+ if (config.cachePoint) {
2685
+ bedrockOptions["cachePoint"] = { type: config.cachePoint.type };
2686
+ }
2687
+ return { bedrock: bedrockOptions };
2688
+ }
2689
+ getReasoningOptions(budget) {
2690
+ if (budget === "none" || budget === 0) {
2691
+ return void 0;
2692
+ }
2693
+ const budgetTokens = this.budgetToTokens(budget);
2694
+ return {
2695
+ bedrock: {
2696
+ reasoning: {
2697
+ budgetTokens
2698
+ }
2699
+ }
2700
+ };
2701
+ }
2702
+ budgetToTokens(budget) {
2703
+ if (typeof budget === "number") return budget;
2704
+ const map = {
2705
+ minimal: 1024,
2706
+ low: 2048,
2707
+ medium: 5e3,
2708
+ high: 1e4
2709
+ };
2710
+ return map[budget] ?? 5e3;
2711
+ }
2712
+ normalizeError(error) {
2713
+ return normalizeBedrockError(error);
2714
+ }
2715
+ isRetryable(error) {
2716
+ return isBedrockRetryable(error);
2717
+ }
2718
+ };
2719
+ function normalizeDeepSeekError(error) {
2720
+ if (error instanceof APICallError) {
2721
+ return {
2722
+ name: error.name,
2723
+ message: error.message,
2724
+ statusCode: error.statusCode,
2725
+ isRetryable: isDeepSeekRetryable(error),
2726
+ provider: "deepseek",
2727
+ originalError: error
2728
+ };
2729
+ }
2730
+ if (error instanceof Error) {
2731
+ return {
2732
+ name: error.name,
2733
+ message: error.message,
2734
+ isRetryable: isDeepSeekRetryable(error),
2735
+ provider: "deepseek",
2736
+ originalError: error
2737
+ };
2738
+ }
2739
+ return {
2740
+ name: "UnknownError",
2741
+ message: String(error),
2742
+ isRetryable: false,
2743
+ provider: "deepseek",
2744
+ originalError: error
2745
+ };
2746
+ }
2747
+ function isDeepSeekRetryable(error) {
2748
+ if (error instanceof APICallError) {
2749
+ if (error.isRetryable) return true;
2750
+ const statusCode = error.statusCode;
2751
+ if (statusCode === 429) return true;
2752
+ if (statusCode === 500) return true;
2753
+ if (statusCode === 502) return true;
2754
+ if (statusCode === 503) return true;
2755
+ if (statusCode === 504) return true;
2756
+ }
2757
+ if (error instanceof Error) {
2758
+ const message = error.message.toLowerCase();
2759
+ if (message.includes("rate limit")) return true;
2760
+ if (message.includes("timeout")) return true;
2761
+ if (message.includes("service unavailable")) return true;
2762
+ }
2763
+ return false;
2764
+ }
2765
+
2766
+ // ../../packages/providers/deepseek/src/adapter.ts
2767
+ var DeepseekProviderAdapter = class extends BaseProviderAdapter {
2768
+ constructor(config, options) {
2769
+ super(options);
2770
+ this.config = config;
2771
+ this.client = createDeepSeek({
2772
+ apiKey: config.apiKey,
2773
+ baseURL: config.baseUrl,
2774
+ headers: config.headers,
2775
+ fetch: options?.proxyUrl ? this.createProxyFetch(options.proxyUrl) : void 0
2776
+ });
2777
+ }
2778
+ providerName = "deepseek";
2779
+ client;
2780
+ createModel(modelId) {
2781
+ return this.client(modelId);
2782
+ }
2783
+ normalizeError(error) {
2784
+ return normalizeDeepSeekError(error);
2785
+ }
2786
+ isRetryable(error) {
2787
+ return isDeepSeekRetryable(error);
2788
+ }
2789
+ };
2790
+ function normalizeGoogleError(error) {
2791
+ if (error instanceof APICallError) {
2792
+ return {
2793
+ name: error.name,
2794
+ message: error.message,
2795
+ statusCode: error.statusCode,
2796
+ isRetryable: isGoogleRetryable(error),
2797
+ provider: "google",
2798
+ originalError: error
2799
+ };
2800
+ }
2801
+ if (error instanceof Error) {
2802
+ return {
2803
+ name: error.name,
2804
+ message: error.message,
2805
+ isRetryable: isGoogleRetryable(error),
2806
+ provider: "google",
2807
+ originalError: error
2808
+ };
2809
+ }
2810
+ return {
2811
+ name: "UnknownError",
2812
+ message: String(error),
2813
+ isRetryable: false,
2814
+ provider: "google",
2815
+ originalError: error
2816
+ };
2817
+ }
2818
+ function isGoogleRetryable(error) {
2819
+ if (error instanceof APICallError) {
2820
+ if (error.isRetryable) return true;
2821
+ const statusCode = error.statusCode;
2822
+ if (statusCode === 429) return true;
2823
+ if (statusCode === 500) return true;
2824
+ if (statusCode === 502) return true;
2825
+ if (statusCode === 503) return true;
2826
+ if (statusCode === 504) return true;
2827
+ }
2828
+ if (error instanceof Error) {
2829
+ const message = error.message.toLowerCase();
2830
+ if (message.includes("rate limit")) return true;
2831
+ if (message.includes("quota exceeded")) return true;
2832
+ if (message.includes("timeout")) return true;
2833
+ if (message.includes("service unavailable")) return true;
2834
+ }
2835
+ return false;
2836
+ }
2837
+
2838
+ // ../../packages/providers/google/src/tools.ts
2839
+ function buildGoogleTools(client, toolNames, options) {
2840
+ const tools = {};
2841
+ for (const name of toolNames) {
2842
+ switch (name) {
2843
+ case "googleSearch": {
2844
+ const googleSearchTool = client.tools.googleSearch({});
2845
+ tools["google_search"] = googleSearchTool;
2846
+ break;
2847
+ }
2848
+ case "codeExecution": {
2849
+ const codeExecutionTool = client.tools.codeExecution({});
2850
+ tools["code_execution"] = codeExecutionTool;
2851
+ break;
2852
+ }
2853
+ case "urlContext": {
2854
+ const urlContextTool = client.tools.urlContext({});
2855
+ tools["url_context"] = urlContextTool;
2856
+ break;
2857
+ }
2858
+ case "fileSearch": {
2859
+ const storeNames = options?.fileSearch?.vectorStoreIds;
2860
+ if (!storeNames || storeNames.length === 0) {
2861
+ console.warn(
2862
+ "Google fileSearch tool requires fileSearchStoreNames. Set providerToolOptions.fileSearch.vectorStoreIds to use this tool."
2863
+ );
2864
+ break;
2865
+ }
2866
+ const fileSearchTool = client.tools.fileSearch({
2867
+ fileSearchStoreNames: storeNames,
2868
+ topK: options?.fileSearch?.maxNumResults
2869
+ });
2870
+ tools["file_search"] = fileSearchTool;
2871
+ break;
2872
+ }
2873
+ case "googleMaps": {
2874
+ const googleMapsTool = client.tools.googleMaps(options?.googleMaps?.retrievalConfig ?? {});
2875
+ tools["google_maps"] = googleMapsTool;
2876
+ break;
2877
+ }
2878
+ }
2879
+ }
2880
+ return tools;
2881
+ }
2882
+
2883
+ // ../../packages/providers/google/src/adapter.ts
2884
+ var GoogleProviderAdapter = class extends BaseProviderAdapter {
2885
+ constructor(config, options) {
2886
+ super(options);
2887
+ this.config = config;
2888
+ this.client = createGoogleGenerativeAI({
2889
+ apiKey: config.apiKey,
2890
+ baseURL: config.baseUrl,
2891
+ headers: config.headers,
2892
+ fetch: options?.proxyUrl ? this.createProxyFetch(options.proxyUrl) : void 0
2893
+ });
2894
+ }
2895
+ providerName = "google";
2896
+ client;
2897
+ createModel(modelId) {
2898
+ return this.client(modelId);
2899
+ }
2900
+ getProviderTools(toolNames, options) {
2901
+ return buildGoogleTools(this.client, toolNames, options);
2902
+ }
2903
+ normalizeError(error) {
2904
+ return normalizeGoogleError(error);
2905
+ }
2906
+ isRetryable(error) {
2907
+ return isGoogleRetryable(error);
2908
+ }
2909
+ getReasoningOptions(budget) {
2910
+ const budgetTokens = this.budgetToTokens(budget);
2911
+ return {
2912
+ google: {
2913
+ thinkingConfig: {
2914
+ thinkingBudget: budgetTokens,
2915
+ includeThoughts: true
2916
+ }
2917
+ }
2918
+ };
2919
+ }
2920
+ budgetToTokens(budget) {
2921
+ if (typeof budget === "number") return budget;
2922
+ const map = {
2923
+ minimal: 1024,
2924
+ low: 2048,
2925
+ medium: 5e3,
2926
+ high: 1e4
2927
+ };
2928
+ return map[budget] ?? 5e3;
2929
+ }
2930
+ };
2931
+ function normalizeOllamaError(error) {
2932
+ if (error instanceof APICallError) {
2933
+ return {
2934
+ name: error.name,
2935
+ message: error.message,
2936
+ statusCode: error.statusCode,
2937
+ isRetryable: isOllamaRetryable(error),
2938
+ provider: "ollama",
2939
+ originalError: error
2940
+ };
2941
+ }
2942
+ if (error instanceof Error) {
2943
+ return {
2944
+ name: error.name,
2945
+ message: error.message,
2946
+ isRetryable: isOllamaRetryable(error),
2947
+ provider: "ollama",
2948
+ originalError: error
2949
+ };
2950
+ }
2951
+ return {
2952
+ name: "UnknownError",
2953
+ message: String(error),
2954
+ isRetryable: false,
2955
+ provider: "ollama",
2956
+ originalError: error
2957
+ };
2958
+ }
2959
+ function isOllamaRetryable(error) {
2960
+ if (error instanceof APICallError) {
2961
+ if (error.isRetryable) return true;
2962
+ const statusCode = error.statusCode;
2963
+ if (statusCode === 429) return true;
2964
+ if (statusCode === 500) return true;
2965
+ if (statusCode === 502) return true;
2966
+ if (statusCode === 503) return true;
2967
+ if (statusCode === 504) return true;
2968
+ }
2969
+ if (error instanceof Error) {
2970
+ const message = error.message.toLowerCase();
2971
+ if (message.includes("rate limit")) return true;
2972
+ if (message.includes("timeout")) return true;
2973
+ if (message.includes("service unavailable")) return true;
2974
+ if (message.includes("connection refused")) return true;
2975
+ }
2976
+ return false;
2977
+ }
2978
+
2979
+ // ../../packages/providers/ollama/src/adapter.ts
2980
+ var OllamaProviderAdapter = class extends BaseProviderAdapter {
2981
+ constructor(config, options) {
2982
+ super(options);
2983
+ this.config = config;
2984
+ this.client = createOllama({
2985
+ baseURL: config.baseUrl,
2986
+ headers: config.headers,
2987
+ fetch: options?.proxyUrl ? this.createProxyFetch(options.proxyUrl) : void 0
2988
+ });
2989
+ }
2990
+ providerName = "ollama";
2991
+ client;
2992
+ createModel(modelId) {
2993
+ return this.client(modelId);
2994
+ }
2995
+ getProviderOptions(config) {
2996
+ if (config?.think === void 0) {
2997
+ return void 0;
2998
+ }
2999
+ return {
3000
+ ollama: {
3001
+ think: config.think
3002
+ }
3003
+ };
3004
+ }
3005
+ getReasoningOptions(budget) {
3006
+ if (budget === "none" || budget === 0) {
3007
+ return void 0;
3008
+ }
3009
+ return {
3010
+ ollama: {
3011
+ think: true
3012
+ }
3013
+ };
3014
+ }
3015
+ normalizeError(error) {
3016
+ return normalizeOllamaError(error);
3017
+ }
3018
+ isRetryable(error) {
3019
+ return isOllamaRetryable(error);
3020
+ }
3021
+ };
3022
+ function normalizeOpenAIError(error) {
3023
+ if (error instanceof APICallError) {
3024
+ return {
3025
+ name: error.name,
3026
+ message: error.message,
3027
+ statusCode: error.statusCode,
3028
+ isRetryable: isOpenAIRetryable(error),
3029
+ provider: "openai",
3030
+ originalError: error
3031
+ };
3032
+ }
3033
+ if (error instanceof Error) {
3034
+ return {
3035
+ name: error.name,
3036
+ message: error.message,
3037
+ isRetryable: isOpenAIRetryable(error),
3038
+ provider: "openai",
3039
+ originalError: error
3040
+ };
3041
+ }
3042
+ return {
3043
+ name: "UnknownError",
3044
+ message: String(error),
3045
+ isRetryable: false,
3046
+ provider: "openai",
3047
+ originalError: error
3048
+ };
3049
+ }
3050
+ function isOpenAIRetryable(error) {
3051
+ if (error instanceof APICallError) {
3052
+ if (error.isRetryable) return true;
3053
+ const statusCode = error.statusCode;
3054
+ if (statusCode === 429) return true;
3055
+ if (statusCode === 500) return true;
3056
+ if (statusCode === 502) return true;
3057
+ if (statusCode === 503) return true;
3058
+ if (statusCode === 504) return true;
3059
+ }
3060
+ if (error instanceof Error) {
3061
+ const message = error.message.toLowerCase();
3062
+ if (message.includes("rate limit")) return true;
3063
+ if (message.includes("timeout")) return true;
3064
+ if (message.includes("service unavailable")) return true;
3065
+ }
3066
+ return false;
3067
+ }
3068
+
3069
+ // ../../packages/providers/openai/src/tools.ts
3070
+ function buildOpenAITools(client, toolNames, options) {
3071
+ const tools = {};
3072
+ for (const name of toolNames) {
3073
+ switch (name) {
3074
+ case "webSearch": {
3075
+ const webSearchTool = client.tools.webSearch();
3076
+ tools["web_search"] = webSearchTool;
3077
+ break;
3078
+ }
3079
+ case "fileSearch": {
3080
+ const vectorStoreIds = options?.fileSearch?.vectorStoreIds;
3081
+ if (!vectorStoreIds || vectorStoreIds.length === 0) {
3082
+ console.warn(
3083
+ "OpenAI fileSearch tool requires vectorStoreIds. Set providerToolOptions.fileSearch.vectorStoreIds to use this tool."
3084
+ );
3085
+ break;
3086
+ }
3087
+ const fileSearchTool = client.tools.fileSearch({
3088
+ vectorStoreIds,
3089
+ maxNumResults: options?.fileSearch?.maxNumResults
3090
+ });
3091
+ tools["file_search"] = fileSearchTool;
3092
+ break;
3093
+ }
3094
+ case "codeInterpreter": {
3095
+ const codeInterpreterTool = client.tools.codeInterpreter();
3096
+ tools["code_interpreter"] = codeInterpreterTool;
3097
+ break;
3098
+ }
3099
+ case "imageGeneration": {
3100
+ const imageGenerationTool = client.tools.imageGeneration();
3101
+ tools["image_generation"] = imageGenerationTool;
3102
+ break;
3103
+ }
3104
+ }
3105
+ }
3106
+ return tools;
3107
+ }
3108
+
3109
+ // ../../packages/providers/openai/src/adapter.ts
3110
+ var OpenAIProviderAdapter = class extends BaseProviderAdapter {
3111
+ constructor(config, options) {
3112
+ super(options);
3113
+ this.config = config;
3114
+ this.client = createOpenAI({
3115
+ apiKey: config.apiKey,
3116
+ baseURL: config.baseUrl,
3117
+ organization: config.organization,
3118
+ project: config.project,
3119
+ name: config.name,
3120
+ headers: config.headers,
3121
+ fetch: options?.proxyUrl ? this.createProxyFetch(options.proxyUrl) : void 0
3122
+ });
3123
+ }
3124
+ providerName = "openai";
3125
+ client;
3126
+ createModel(modelId) {
3127
+ return this.client(modelId);
3128
+ }
3129
+ getProviderTools(toolNames, options) {
3130
+ return buildOpenAITools(this.client, toolNames, options);
3131
+ }
3132
+ getReasoningOptions(budget) {
3133
+ const effort = this.budgetToEffort(budget);
3134
+ return {
3135
+ openai: { reasoningEffort: effort }
3136
+ };
3137
+ }
3138
+ budgetToEffort(budget) {
3139
+ if (typeof budget === "number") {
3140
+ if (budget <= 2048) return "low";
3141
+ if (budget <= 5e3) return "medium";
3142
+ return "high";
3143
+ }
3144
+ if (budget === "minimal") return "low";
3145
+ return budget;
3146
+ }
3147
+ normalizeError(error) {
3148
+ return normalizeOpenAIError(error);
3149
+ }
3150
+ isRetryable(error) {
3151
+ return isOpenAIRetryable(error);
3152
+ }
3153
+ };
3154
+ function normalizeVertexError(error) {
3155
+ if (error instanceof APICallError) {
3156
+ return {
3157
+ name: error.name,
3158
+ message: error.message,
3159
+ statusCode: error.statusCode,
3160
+ isRetryable: isVertexRetryable(error),
3161
+ provider: "google-vertex",
3162
+ originalError: error
3163
+ };
3164
+ }
3165
+ if (error instanceof Error) {
3166
+ return {
3167
+ name: error.name,
3168
+ message: error.message,
3169
+ isRetryable: isVertexRetryable(error),
3170
+ provider: "google-vertex",
3171
+ originalError: error
3172
+ };
3173
+ }
3174
+ return {
3175
+ name: "UnknownError",
3176
+ message: String(error),
3177
+ isRetryable: false,
3178
+ provider: "google-vertex",
3179
+ originalError: error
3180
+ };
3181
+ }
3182
+ function isVertexRetryable(error) {
3183
+ if (error instanceof APICallError) {
3184
+ if (error.isRetryable) return true;
3185
+ const statusCode = error.statusCode;
3186
+ if (statusCode === 429) return true;
3187
+ if (statusCode === 500) return true;
3188
+ if (statusCode === 502) return true;
3189
+ if (statusCode === 503) return true;
3190
+ if (statusCode === 504) return true;
3191
+ }
3192
+ if (error instanceof Error) {
3193
+ const message = error.message.toLowerCase();
3194
+ if (message.includes("rate limit")) return true;
3195
+ if (message.includes("quota exceeded")) return true;
3196
+ if (message.includes("timeout")) return true;
3197
+ if (message.includes("service unavailable")) return true;
3198
+ }
3199
+ return false;
3200
+ }
3201
+
3202
+ // ../../packages/providers/vertex/src/tools.ts
3203
+ function buildVertexTools(client, toolNames, options) {
3204
+ const tools = {};
3205
+ for (const name of toolNames) {
3206
+ switch (name) {
3207
+ case "googleSearch": {
3208
+ const googleSearchTool = client.tools.googleSearch({});
3209
+ tools["google_search"] = googleSearchTool;
3210
+ break;
3211
+ }
3212
+ case "codeExecution": {
3213
+ const codeExecutionTool = client.tools.codeExecution({});
3214
+ tools["code_execution"] = codeExecutionTool;
3215
+ break;
3216
+ }
3217
+ case "urlContext": {
3218
+ const urlContextTool = client.tools.urlContext({});
3219
+ tools["url_context"] = urlContextTool;
3220
+ break;
3221
+ }
3222
+ case "enterpriseWebSearch": {
3223
+ const enterpriseWebSearchTool = client.tools.enterpriseWebSearch({});
3224
+ tools["enterprise_web_search"] = enterpriseWebSearchTool;
3225
+ break;
3226
+ }
3227
+ case "googleMaps": {
3228
+ const googleMapsTool = client.tools.googleMaps(options?.googleMaps?.retrievalConfig ?? {});
3229
+ tools["google_maps"] = googleMapsTool;
3230
+ break;
3231
+ }
3232
+ }
3233
+ }
3234
+ return tools;
3235
+ }
3236
+
3237
+ // ../../packages/providers/vertex/src/adapter.ts
3238
+ var VertexProviderAdapter = class extends BaseProviderAdapter {
3239
+ constructor(config, options) {
3240
+ super(options);
3241
+ this.config = config;
3242
+ this.client = createVertex({
3243
+ project: config.project,
3244
+ location: config.location,
3245
+ baseURL: config.baseUrl,
3246
+ headers: config.headers,
3247
+ fetch: options?.proxyUrl ? this.createProxyFetch(options.proxyUrl) : void 0
3248
+ });
3249
+ }
3250
+ providerName = "google-vertex";
3251
+ client;
3252
+ createModel(modelId) {
3253
+ return this.client(modelId);
3254
+ }
3255
+ getProviderTools(toolNames, options) {
3256
+ return buildVertexTools(this.client, toolNames, options);
3257
+ }
3258
+ getProviderOptions(config) {
3259
+ if (!config?.safetySettings || config.safetySettings.length === 0) {
3260
+ return void 0;
3261
+ }
3262
+ return {
3263
+ vertex: {
3264
+ safetySettings: config.safetySettings
3265
+ }
3266
+ };
3267
+ }
3268
+ getReasoningOptions(budget) {
3269
+ if (budget === "none" || budget === 0) {
3270
+ return void 0;
3271
+ }
3272
+ const budgetTokens = this.budgetToTokens(budget);
3273
+ return {
3274
+ vertex: {
3275
+ thinkingConfig: {
3276
+ thinkingBudget: budgetTokens,
3277
+ includeThoughts: true
3278
+ }
3279
+ }
3280
+ };
3281
+ }
3282
+ budgetToTokens(budget) {
3283
+ if (typeof budget === "number") return budget;
3284
+ const map = {
3285
+ minimal: 1024,
3286
+ low: 2048,
3287
+ medium: 5e3,
3288
+ high: 1e4
3289
+ };
3290
+ return map[budget] ?? 5e3;
3291
+ }
3292
+ normalizeError(error) {
3293
+ return normalizeVertexError(error);
3294
+ }
3295
+ isRetryable(error) {
3296
+ return isVertexRetryable(error);
3297
+ }
3298
+ };
2279
3299
 
2280
3300
  // src/helpers/register-providers.ts
2281
- registerProviderAdapter("anthropic", async () => {
2282
- const { AnthropicProviderAdapter } = await import('@perstack/anthropic-provider');
2283
- return AnthropicProviderAdapter;
2284
- });
2285
- registerProviderAdapter("openai", async () => {
2286
- const { OpenAIProviderAdapter } = await import('@perstack/openai-provider');
2287
- return OpenAIProviderAdapter;
2288
- });
2289
- registerProviderAdapter("google", async () => {
2290
- const { GoogleProviderAdapter } = await import('@perstack/google-provider');
2291
- return GoogleProviderAdapter;
2292
- });
2293
- registerProviderAdapter("ollama", async () => {
2294
- const { OllamaProviderAdapter } = await import('@perstack/ollama-provider');
2295
- return OllamaProviderAdapter;
2296
- });
2297
- registerProviderAdapter("azure-openai", async () => {
2298
- const { AzureOpenAIProviderAdapter } = await import('@perstack/azure-openai-provider');
2299
- return AzureOpenAIProviderAdapter;
2300
- });
2301
- registerProviderAdapter("amazon-bedrock", async () => {
2302
- const { BedrockProviderAdapter } = await import('@perstack/bedrock-provider');
2303
- return BedrockProviderAdapter;
2304
- });
2305
- registerProviderAdapter("google-vertex", async () => {
2306
- const { VertexProviderAdapter } = await import('@perstack/vertex-provider');
2307
- return VertexProviderAdapter;
2308
- });
2309
- registerProviderAdapter("deepseek", async () => {
2310
- const { DeepseekProviderAdapter } = await import('@perstack/deepseek-provider');
2311
- return DeepseekProviderAdapter;
2312
- });
3301
+ registerProviderAdapter(
3302
+ "anthropic",
3303
+ async () => AnthropicProviderAdapter
3304
+ );
3305
+ registerProviderAdapter(
3306
+ "openai",
3307
+ async () => OpenAIProviderAdapter
3308
+ );
3309
+ registerProviderAdapter(
3310
+ "google",
3311
+ async () => GoogleProviderAdapter
3312
+ );
3313
+ registerProviderAdapter(
3314
+ "ollama",
3315
+ async () => OllamaProviderAdapter
3316
+ );
3317
+ registerProviderAdapter(
3318
+ "azure-openai",
3319
+ async () => AzureOpenAIProviderAdapter
3320
+ );
3321
+ registerProviderAdapter(
3322
+ "amazon-bedrock",
3323
+ async () => BedrockProviderAdapter
3324
+ );
3325
+ registerProviderAdapter(
3326
+ "google-vertex",
3327
+ async () => VertexProviderAdapter
3328
+ );
3329
+ registerProviderAdapter(
3330
+ "deepseek",
3331
+ async () => DeepseekProviderAdapter
3332
+ );
2313
3333
  var shouldEnableReasoning = (budget) => budget !== void 0 && budget !== "none" && budget !== 0;
2314
3334
  var LLMExecutor = class {
2315
3335
  constructor(adapter, model) {
@@ -2636,5 +3656,5 @@ async function run(runInput, options) {
2636
3656
  }
2637
3657
 
2638
3658
  export { findLockfile, getLockfileExpertToolDefinitions, getModel, loadLockfile, package_default, run, runtimeStateMachine };
2639
- //# sourceMappingURL=chunk-LDJKVMQK.js.map
2640
- //# sourceMappingURL=chunk-LDJKVMQK.js.map
3659
+ //# sourceMappingURL=chunk-BXJGGA3Q.js.map
3660
+ //# sourceMappingURL=chunk-BXJGGA3Q.js.map