@inkeep/agents-run-api 0.0.0-dev-20250916015245 → 0.0.0-dev-20250916190005

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.
Files changed (3) hide show
  1. package/dist/index.cjs +103 -114
  2. package/dist/index.js +103 -114
  3. package/package.json +3 -2
package/dist/index.cjs CHANGED
@@ -30,6 +30,7 @@ var destr = require('destr');
30
30
  var traverse = require('traverse');
31
31
  var ai = require('ai');
32
32
  var anthropic = require('@ai-sdk/anthropic');
33
+ var google = require('@ai-sdk/google');
33
34
  var openai = require('@ai-sdk/openai');
34
35
  var jmespath = require('jmespath');
35
36
  var mcp_js = require('@modelcontextprotocol/sdk/server/mcp.js');
@@ -1410,6 +1411,38 @@ __publicField(_ArtifactReferenceSchema, "ARTIFACT_PROPS_SCHEMA", {
1410
1411
  var ArtifactReferenceSchema = _ArtifactReferenceSchema;
1411
1412
  var logger5 = agentsCore.getLogger("ModelFactory");
1412
1413
  var _ModelFactory = class _ModelFactory {
1414
+ /**
1415
+ * Create a provider instance with custom configuration
1416
+ */
1417
+ static createProvider(provider, config2) {
1418
+ switch (provider) {
1419
+ case "anthropic":
1420
+ return anthropic.createAnthropic(config2);
1421
+ case "openai":
1422
+ return openai.createOpenAI(config2);
1423
+ case "google":
1424
+ return google.createGoogleGenerativeAI(config2);
1425
+ default:
1426
+ throw new Error(`Unsupported provider: ${provider}`);
1427
+ }
1428
+ }
1429
+ /**
1430
+ * Extract provider configuration from providerOptions
1431
+ * Only includes settings that go to the provider constructor (baseURL, apiKey, etc.)
1432
+ */
1433
+ static extractProviderConfig(providerOptions) {
1434
+ if (!providerOptions) {
1435
+ return {};
1436
+ }
1437
+ const providerConfig = {};
1438
+ if (providerOptions.baseUrl || providerOptions.baseURL) {
1439
+ providerConfig.baseURL = providerOptions.baseUrl || providerOptions.baseURL;
1440
+ }
1441
+ if (providerOptions.gateway) {
1442
+ Object.assign(providerConfig, providerOptions.gateway);
1443
+ }
1444
+ return providerConfig;
1445
+ }
1413
1446
  /**
1414
1447
  * Create a language model instance from configuration
1415
1448
  * Throws error if no config provided - models must be configured at project level
@@ -1432,49 +1465,40 @@ var _ModelFactory = class _ModelFactory {
1432
1465
  },
1433
1466
  "Creating language model from config"
1434
1467
  );
1435
- try {
1436
- switch (provider) {
1437
- case "anthropic":
1438
- return _ModelFactory.createAnthropicModel(modelName, modelSettings.providerOptions);
1439
- case "openai":
1440
- return _ModelFactory.createOpenAIModel(modelName, modelSettings.providerOptions);
1441
- default:
1442
- throw new Error(
1443
- `Unsupported provider: ${provider}. Supported providers are: ${_ModelFactory.SUPPORTED_PROVIDERS.join(", ")}`
1444
- );
1445
- }
1446
- } catch (error) {
1447
- logger5.error(
1448
- {
1449
- provider,
1450
- model: modelName,
1451
- error: error instanceof Error ? error.message : "Unknown error"
1452
- },
1453
- "Failed to create model"
1454
- );
1455
- throw new Error(
1456
- `Failed to create model ${modelString}: ${error instanceof Error ? error.message : "Unknown error"}`
1457
- );
1468
+ const providerConfig = _ModelFactory.extractProviderConfig(modelSettings.providerOptions);
1469
+ if (Object.keys(providerConfig).length > 0) {
1470
+ logger5.info({ config: providerConfig }, `Applying custom ${provider} provider configuration`);
1471
+ const customProvider = _ModelFactory.createProvider(provider, providerConfig);
1472
+ return customProvider.languageModel(modelName);
1473
+ }
1474
+ switch (provider) {
1475
+ case "anthropic":
1476
+ return anthropic.anthropic(modelName);
1477
+ case "openai":
1478
+ return openai.openai(modelName);
1479
+ case "google":
1480
+ return google.google(modelName);
1481
+ default:
1482
+ throw new Error(`Unsupported provider: ${provider}`);
1458
1483
  }
1459
1484
  }
1460
1485
  /**
1461
1486
  * Parse model string to extract provider and model name
1462
- * Examples: "anthropic/claude-4-sonnet" -> { provider: "anthropic", modelName: "claude-4-sonnet" }
1463
- * "claude-4-sonnet" -> { provider: "anthropic", modelName: "claude-4-sonnet" } (default to anthropic)
1487
+ * Examples: "anthropic/claude-sonnet-4" -> { provider: "anthropic", modelName: "claude-sonnet-4" }
1488
+ * "claude-sonnet-4" -> { provider: "anthropic", modelName: "claude-sonnet-4" } (default to anthropic)
1464
1489
  */
1465
1490
  static parseModelString(modelString) {
1466
1491
  if (modelString.includes("/")) {
1467
1492
  const [provider, ...modelParts] = modelString.split("/");
1468
1493
  const normalizedProvider = provider.toLowerCase();
1469
1494
  if (!_ModelFactory.SUPPORTED_PROVIDERS.includes(normalizedProvider)) {
1470
- logger5.warn(
1495
+ logger5.error(
1471
1496
  { provider: normalizedProvider, modelName: modelParts.join("/") },
1472
1497
  "Unsupported provider detected, falling back to anthropic"
1473
1498
  );
1474
- return {
1475
- provider: "anthropic",
1476
- modelName: modelParts.join("/")
1477
- };
1499
+ throw new Error(
1500
+ `Unsupported provider: ${normalizedProvider}. Please provide a model in the format of provider/model-name.`
1501
+ );
1478
1502
  }
1479
1503
  return {
1480
1504
  provider: normalizedProvider,
@@ -1482,51 +1506,9 @@ var _ModelFactory = class _ModelFactory {
1482
1506
  // In case model name has slashes
1483
1507
  };
1484
1508
  }
1485
- return {
1486
- provider: "anthropic",
1487
- modelName: modelString
1488
- };
1489
- }
1490
- /**
1491
- * Create an Anthropic model instance
1492
- */
1493
- static createAnthropicModel(modelName, providerOptions) {
1494
- const anthropicConfig = {};
1495
- if (providerOptions?.baseUrl || providerOptions?.baseURL) {
1496
- anthropicConfig.baseURL = providerOptions.baseUrl || providerOptions.baseURL;
1497
- }
1498
- if (providerOptions?.gateway) {
1499
- logger5.info(
1500
- { gateway: providerOptions.gateway },
1501
- "Setting up AI Gateway for Anthropic model"
1502
- );
1503
- Object.assign(anthropicConfig, providerOptions.gateway);
1504
- }
1505
- if (Object.keys(anthropicConfig).length > 0) {
1506
- logger5.info({ config: anthropicConfig }, "Applying custom Anthropic provider configuration");
1507
- const provider = anthropic.createAnthropic(anthropicConfig);
1508
- return provider(modelName);
1509
- }
1510
- return anthropic.anthropic(modelName);
1511
- }
1512
- /**
1513
- * Create an OpenAI model instance
1514
- */
1515
- static createOpenAIModel(modelName, providerOptions) {
1516
- const openaiConfig = {};
1517
- if (providerOptions?.baseUrl || providerOptions?.baseURL) {
1518
- openaiConfig.baseURL = providerOptions.baseUrl || providerOptions.baseURL;
1519
- }
1520
- if (providerOptions?.gateway) {
1521
- logger5.info({ gateway: providerOptions.gateway }, "Setting up AI Gateway for OpenAI model");
1522
- Object.assign(openaiConfig, providerOptions.gateway);
1523
- }
1524
- if (Object.keys(openaiConfig).length > 0) {
1525
- logger5.info({ config: openaiConfig }, "Applying custom OpenAI provider configuration");
1526
- const provider = openai.createOpenAI(openaiConfig);
1527
- return provider(modelName);
1528
- }
1529
- return openai.openai(modelName);
1509
+ throw new Error(
1510
+ `Invalid model provided: ${modelString}. Please provide a model in the format of provider/model-name.`
1511
+ );
1530
1512
  }
1531
1513
  /**
1532
1514
  * Get generation parameters from provider options
@@ -1551,7 +1533,7 @@ var _ModelFactory = class _ModelFactory {
1551
1533
  * Includes maxDuration if specified in provider options (in seconds, following Vercel standard)
1552
1534
  */
1553
1535
  static prepareGenerationConfig(modelSettings) {
1554
- const modelString = modelSettings?.model?.trim() || "anthropic/claude-4-sonnet-20250514";
1536
+ const modelString = modelSettings?.model?.trim();
1555
1537
  const model = _ModelFactory.createModel({
1556
1538
  model: modelString,
1557
1539
  providerOptions: modelSettings?.providerOptions
@@ -1592,7 +1574,7 @@ var _ModelFactory = class _ModelFactory {
1592
1574
  /**
1593
1575
  * Supported providers for security validation
1594
1576
  */
1595
- __publicField(_ModelFactory, "SUPPORTED_PROVIDERS", ["anthropic", "openai"]);
1577
+ __publicField(_ModelFactory, "SUPPORTED_PROVIDERS", ["anthropic", "openai", "google"]);
1596
1578
  var ModelFactory = _ModelFactory;
1597
1579
 
1598
1580
  // src/utils/graph-session.ts
@@ -3665,7 +3647,7 @@ function createPropSelectorsSchema(artifactComponents) {
3665
3647
  Object.entries(summaryProps.properties).forEach(([propName, propDef]) => {
3666
3648
  const propDescription = propDef?.description || propDef?.title || `${propName} property`;
3667
3649
  propSchema[propName] = z5__default.default.string().describe(
3668
- `JMESPath selector for ${propName} (${propDescription}) - summary version, relative to base selector`
3650
+ `JMESPath selector for ${propName} (${propDescription}) - summary version, MUST be relative to your baseSelector target level. Access fields WITHIN the items your baseSelector returns.`
3669
3651
  );
3670
3652
  });
3671
3653
  }
@@ -3677,7 +3659,7 @@ function createPropSelectorsSchema(artifactComponents) {
3677
3659
  if (!propSchema[propName]) {
3678
3660
  const propDescription = propDef?.description || propDef?.title || `${propName} property`;
3679
3661
  propSchema[propName] = z5__default.default.string().describe(
3680
- `JMESPath selector for ${propName} (${propDescription}) - full version, relative to base selector`
3662
+ `JMESPath selector for ${propName} (${propDescription}) - MUST be relative to your baseSelector target level. If baseSelector stops at a document, this accesses fields WITHIN that document. Examples: "title", "content.body", "metadata.author"`
3681
3663
  );
3682
3664
  }
3683
3665
  });
@@ -3691,7 +3673,26 @@ function createPropSelectorsSchema(artifactComponents) {
3691
3673
  return z5__default.default.union(propSelectorSchemas);
3692
3674
  }
3693
3675
  return z5__default.default.record(z5__default.default.string(), z5__default.default.string()).describe(
3694
- "Prop selectors mapping schema properties to JMESPath expressions relative to base selector"
3676
+ `Prop selectors mapping schema properties to JMESPath expressions relative to base selector. Each path is relative to the item(s) your baseSelector returns.
3677
+
3678
+ \u{1F3AF} CRITICAL: PropSelectors work ONLY on the data your baseSelector returns!
3679
+ If baseSelector = "result.docs[0]" \u2192 propSelectors access fields INSIDE that doc
3680
+ If baseSelector = "result.docs[0].content[0]" \u2192 propSelectors access fields INSIDE that content item
3681
+
3682
+ \u2705 CORRECT EXAMPLES (paths relative to baseSelector target):
3683
+ \u2022 baseSelector: "result.documents[?type=='article']" \u2192 propSelectors: {"title": "title", "url": "url"}
3684
+ \u2022 baseSelector: "result.content[0].text" \u2192 propSelectors: {"content": "content[0].text", "source": "content[0].source"}
3685
+ \u2022 baseSelector: "result.items" \u2192 propSelectors: {"name": "profile.name", "email": "contact.email"}
3686
+
3687
+ \u274C WRONG EXAMPLES (accessing data not at baseSelector level):
3688
+ \u2022 baseSelector: "result.docs[0].content[0]" \u2192 propSelectors: {"title": "title"} \u2190 title is at doc level, not content level!
3689
+ \u2022 baseSelector: "result.source.content" \u2192 propSelectors: {"title": "content[4].text"} \u2190 baseSelector ends at array, can't index into it!
3690
+ \u2022 baseSelector: "result.items" \u2192 propSelectors: {"title": "documents[0].title"} \u2190 going deeper when baseSelector should handle depth
3691
+
3692
+ \u274C NEVER USE LITERAL VALUES:
3693
+ {"title": "Robert Tran", "url": "https://linkedin.com/..."}
3694
+
3695
+ \u{1F4A1} TIP: Match your baseSelector depth to where the properties you need actually exist!`
3695
3696
  );
3696
3697
  }
3697
3698
  function createInputSchema(artifactComponents) {
@@ -3700,7 +3701,18 @@ function createInputSchema(artifactComponents) {
3700
3701
  "EXACT toolCallId from a previous tool execution - copy it exactly from the tool call result. NEVER invent or make up tool call IDs."
3701
3702
  ),
3702
3703
  baseSelector: z5__default.default.string().describe(
3703
- `JMESPath selector to get to the main data array/object. ALWAYS start with "result." Example: "result.content[?type=='text']"`
3704
+ `JMESPath selector to get to the main data array/object. ALWAYS start with "result." That is a mandatory prefix.
3705
+
3706
+ Data structures are COMPLEX and NESTED. Examples:
3707
+ \u2022 "result.content[0].text.content[2]" - parsed JSON in text field
3708
+ \u2022 "result.structuredContent.content[1]" - direct structured data
3709
+ \u2022 "result.data.items[?type=='doc']" - filtered array
3710
+
3711
+ \u{1F6A8} CRITICAL: If you need data from array[4], your baseSelector must END at array[4], NOT at the array itself!
3712
+ \u2705 CORRECT: "result.source.content[4]" \u2192 propSelectors can access fields in that item
3713
+ \u274C WRONG: "result.source.content" \u2192 propSelectors can't use content[4] because baseSelector already selected the array
3714
+
3715
+ \u{1F525} IF YOUR PATH FAILS: READ THE ERROR MESSAGE! It tells you the correct path! \u{1F525}`
3704
3716
  ),
3705
3717
  propSelectors: createPropSelectorsSchema(artifactComponents)
3706
3718
  });
@@ -3719,6 +3731,9 @@ function createSaveToolResultTool(sessionId, streamRequestId, agentId, artifactC
3719
3731
  return ai.tool({
3720
3732
  description: `Save tool results as structured artifacts. Each artifact should represent ONE SPECIFIC, IMPORTANT, and UNIQUE document or data item.
3721
3733
 
3734
+ \u26A1 CRITICAL: JSON-like text content in tool results is AUTOMATICALLY PARSED into proper JSON objects - treat all data as structured, not text strings.
3735
+ \u{1F6A8} CRITICAL: Data structures are deeply nested. When your path fails, READ THE ERROR MESSAGE - it shows the correct path!
3736
+
3722
3737
  AVAILABLE ARTIFACT TYPES:
3723
3738
  ${availableTypesWithDescriptions}
3724
3739
 
@@ -3730,26 +3745,6 @@ Each artifact you save becomes a SEPARATE DATA COMPONENT in the structured respo
3730
3745
  \u2705 UNIQUE with distinct value from other artifacts
3731
3746
  \u2705 RENDERED AS INDIVIDUAL DATA COMPONENT in the UI
3732
3747
 
3733
- \u274C DO NOT save multiple different items in one artifact unless they are EXTREMELY SIMILAR
3734
- \u274C DO NOT batch unrelated items together - each item becomes its own data component
3735
- \u274C DO NOT save generic collections - break them into individual data components
3736
-
3737
- \u{1F3AF} STRUCTURED DATA COMPONENT PRINCIPLE:
3738
- Each artifact save creates ONE data component that will be rendered separately in the UI. If you have 5 important items, save them as 5 separate artifacts to create 5 separate data components for better user experience.
3739
-
3740
- THINK: "What is the ONE most important piece of information here that deserves its own data component?"
3741
-
3742
- EXAMPLES OF GOOD INDIVIDUAL ARTIFACTS (SEPARATE DATA COMPONENTS):
3743
- - Nick Gomez's founder profile (specific person) \u2192 Individual data component
3744
- - The /users/create API endpoint documentation (specific endpoint) \u2192 Individual data component
3745
- - Error message for authentication failure (specific error type) \u2192 Individual data component
3746
- - Configuration for Redis caching (specific config topic) \u2192 Individual data component
3747
-
3748
- EXAMPLES OF BAD BATCHING:
3749
- \u274C "All team members" \u2192 Should be separate artifacts for each important member (separate data components)
3750
- \u274C "All API endpoints" \u2192 Should be separate artifacts for each distinct endpoint (separate data components)
3751
- \u274C "All error types" \u2192 Should be separate artifacts for each error category (separate data components)
3752
-
3753
3748
  USAGE PATTERN:
3754
3749
  1. baseSelector: Navigate through nested structures to target ONE SPECIFIC item
3755
3750
  - Navigate through all necessary levels: "result.data.items.nested[?condition]"
@@ -3759,9 +3754,11 @@ USAGE PATTERN:
3759
3754
  - NOT: "result.items[*]" (too broad, gets everything)
3760
3755
 
3761
3756
  2. propSelectors: Extract properties relative to your selected item
3762
- - Always relative to the single item that baseSelector returns
3763
- - Simple paths from that item: { prop1: "field_x", prop2: "nested.field_y", prop3: "deep.nested.field_z" }
3764
- - The tool handles array iteration - your selectors work on individual items
3757
+ - \u{1F3AF} CRITICAL: Always relative to the single item that baseSelector returns
3758
+ - If baseSelector ends at a document \u2192 propSelectors access document fields
3759
+ - If baseSelector ends at content[0] \u2192 propSelectors access content[0] fields
3760
+ - Simple paths from that exact level: { prop1: "field_x", prop2: "nested.field_y" }
3761
+ - \u274C DON'T try to go back up or deeper - adjust your baseSelector instead!
3765
3762
 
3766
3763
  3. Result: ONE artifact representing ONE important, unique item \u2192 ONE data component
3767
3764
 
@@ -3770,15 +3767,7 @@ USAGE PATTERN:
3770
3767
  - Focus on getting to the right level with baseSelector, then keep propSelectors simple
3771
3768
  - Test your baseSelector: Does it return exactly the items you want?
3772
3769
 
3773
- \u26A0\uFE0F STRICT SELECTIVITY RULES FOR DATA COMPONENTS:
3774
- - ALWAYS ask: "Is this ONE specific, important thing that deserves its own data component?"
3775
- - If the answer is no, don't save it or find a more specific selector
3776
- - Multiple similar items = Multiple separate artifact saves (use the tool multiple times) \u2192 Multiple data components
3777
- - Each artifact should be independently valuable and uniquely identifiable \u2192 Each data component stands alone
3778
- - BETTER to save 3 individual, specific artifacts (3 data components) than 1 generic collection (1 data component)
3779
-
3780
- \u{1F504} MULTIPLE ARTIFACTS = MULTIPLE DATA COMPONENTS:
3781
- Remember: Each time you call this tool, you create a separate data component. Call it multiple times for multiple items to create a rich, structured response with individual data components for each important piece of information.`,
3770
+ Please use Error Messages to Debug when there is an error in the tool call.`,
3782
3771
  inputSchema,
3783
3772
  execute: async ({ toolCallId, baseSelector, propSelectors, ...rest }, _context) => {
3784
3773
  const artifactType = "artifactType" in rest ? rest.artifactType : void 0;
@@ -6308,7 +6297,7 @@ ${output}`;
6308
6297
  { role: "user", content: userMessage },
6309
6298
  ...reasoningFlow,
6310
6299
  {
6311
- role: "system",
6300
+ role: "user",
6312
6301
  content: await this.buildPhase2SystemPrompt()
6313
6302
  }
6314
6303
  ],
package/dist/index.js CHANGED
@@ -24,6 +24,7 @@ import destr from 'destr';
24
24
  import traverse from 'traverse';
25
25
  import { createUIMessageStream, JsonToSseTransformStream, parsePartialJson, generateText, generateObject, tool, streamText } from 'ai';
26
26
  import { createAnthropic, anthropic } from '@ai-sdk/anthropic';
27
+ import { createGoogleGenerativeAI, google } from '@ai-sdk/google';
27
28
  import { createOpenAI, openai } from '@ai-sdk/openai';
28
29
  import jmespath from 'jmespath';
29
30
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
@@ -1101,6 +1102,38 @@ __publicField(_ArtifactReferenceSchema, "ARTIFACT_PROPS_SCHEMA", {
1101
1102
  var ArtifactReferenceSchema = _ArtifactReferenceSchema;
1102
1103
  var logger5 = getLogger("ModelFactory");
1103
1104
  var _ModelFactory = class _ModelFactory {
1105
+ /**
1106
+ * Create a provider instance with custom configuration
1107
+ */
1108
+ static createProvider(provider, config) {
1109
+ switch (provider) {
1110
+ case "anthropic":
1111
+ return createAnthropic(config);
1112
+ case "openai":
1113
+ return createOpenAI(config);
1114
+ case "google":
1115
+ return createGoogleGenerativeAI(config);
1116
+ default:
1117
+ throw new Error(`Unsupported provider: ${provider}`);
1118
+ }
1119
+ }
1120
+ /**
1121
+ * Extract provider configuration from providerOptions
1122
+ * Only includes settings that go to the provider constructor (baseURL, apiKey, etc.)
1123
+ */
1124
+ static extractProviderConfig(providerOptions) {
1125
+ if (!providerOptions) {
1126
+ return {};
1127
+ }
1128
+ const providerConfig = {};
1129
+ if (providerOptions.baseUrl || providerOptions.baseURL) {
1130
+ providerConfig.baseURL = providerOptions.baseUrl || providerOptions.baseURL;
1131
+ }
1132
+ if (providerOptions.gateway) {
1133
+ Object.assign(providerConfig, providerOptions.gateway);
1134
+ }
1135
+ return providerConfig;
1136
+ }
1104
1137
  /**
1105
1138
  * Create a language model instance from configuration
1106
1139
  * Throws error if no config provided - models must be configured at project level
@@ -1123,49 +1156,40 @@ var _ModelFactory = class _ModelFactory {
1123
1156
  },
1124
1157
  "Creating language model from config"
1125
1158
  );
1126
- try {
1127
- switch (provider) {
1128
- case "anthropic":
1129
- return _ModelFactory.createAnthropicModel(modelName, modelSettings.providerOptions);
1130
- case "openai":
1131
- return _ModelFactory.createOpenAIModel(modelName, modelSettings.providerOptions);
1132
- default:
1133
- throw new Error(
1134
- `Unsupported provider: ${provider}. Supported providers are: ${_ModelFactory.SUPPORTED_PROVIDERS.join(", ")}`
1135
- );
1136
- }
1137
- } catch (error) {
1138
- logger5.error(
1139
- {
1140
- provider,
1141
- model: modelName,
1142
- error: error instanceof Error ? error.message : "Unknown error"
1143
- },
1144
- "Failed to create model"
1145
- );
1146
- throw new Error(
1147
- `Failed to create model ${modelString}: ${error instanceof Error ? error.message : "Unknown error"}`
1148
- );
1159
+ const providerConfig = _ModelFactory.extractProviderConfig(modelSettings.providerOptions);
1160
+ if (Object.keys(providerConfig).length > 0) {
1161
+ logger5.info({ config: providerConfig }, `Applying custom ${provider} provider configuration`);
1162
+ const customProvider = _ModelFactory.createProvider(provider, providerConfig);
1163
+ return customProvider.languageModel(modelName);
1164
+ }
1165
+ switch (provider) {
1166
+ case "anthropic":
1167
+ return anthropic(modelName);
1168
+ case "openai":
1169
+ return openai(modelName);
1170
+ case "google":
1171
+ return google(modelName);
1172
+ default:
1173
+ throw new Error(`Unsupported provider: ${provider}`);
1149
1174
  }
1150
1175
  }
1151
1176
  /**
1152
1177
  * Parse model string to extract provider and model name
1153
- * Examples: "anthropic/claude-4-sonnet" -> { provider: "anthropic", modelName: "claude-4-sonnet" }
1154
- * "claude-4-sonnet" -> { provider: "anthropic", modelName: "claude-4-sonnet" } (default to anthropic)
1178
+ * Examples: "anthropic/claude-sonnet-4" -> { provider: "anthropic", modelName: "claude-sonnet-4" }
1179
+ * "claude-sonnet-4" -> { provider: "anthropic", modelName: "claude-sonnet-4" } (default to anthropic)
1155
1180
  */
1156
1181
  static parseModelString(modelString) {
1157
1182
  if (modelString.includes("/")) {
1158
1183
  const [provider, ...modelParts] = modelString.split("/");
1159
1184
  const normalizedProvider = provider.toLowerCase();
1160
1185
  if (!_ModelFactory.SUPPORTED_PROVIDERS.includes(normalizedProvider)) {
1161
- logger5.warn(
1186
+ logger5.error(
1162
1187
  { provider: normalizedProvider, modelName: modelParts.join("/") },
1163
1188
  "Unsupported provider detected, falling back to anthropic"
1164
1189
  );
1165
- return {
1166
- provider: "anthropic",
1167
- modelName: modelParts.join("/")
1168
- };
1190
+ throw new Error(
1191
+ `Unsupported provider: ${normalizedProvider}. Please provide a model in the format of provider/model-name.`
1192
+ );
1169
1193
  }
1170
1194
  return {
1171
1195
  provider: normalizedProvider,
@@ -1173,51 +1197,9 @@ var _ModelFactory = class _ModelFactory {
1173
1197
  // In case model name has slashes
1174
1198
  };
1175
1199
  }
1176
- return {
1177
- provider: "anthropic",
1178
- modelName: modelString
1179
- };
1180
- }
1181
- /**
1182
- * Create an Anthropic model instance
1183
- */
1184
- static createAnthropicModel(modelName, providerOptions) {
1185
- const anthropicConfig = {};
1186
- if (providerOptions?.baseUrl || providerOptions?.baseURL) {
1187
- anthropicConfig.baseURL = providerOptions.baseUrl || providerOptions.baseURL;
1188
- }
1189
- if (providerOptions?.gateway) {
1190
- logger5.info(
1191
- { gateway: providerOptions.gateway },
1192
- "Setting up AI Gateway for Anthropic model"
1193
- );
1194
- Object.assign(anthropicConfig, providerOptions.gateway);
1195
- }
1196
- if (Object.keys(anthropicConfig).length > 0) {
1197
- logger5.info({ config: anthropicConfig }, "Applying custom Anthropic provider configuration");
1198
- const provider = createAnthropic(anthropicConfig);
1199
- return provider(modelName);
1200
- }
1201
- return anthropic(modelName);
1202
- }
1203
- /**
1204
- * Create an OpenAI model instance
1205
- */
1206
- static createOpenAIModel(modelName, providerOptions) {
1207
- const openaiConfig = {};
1208
- if (providerOptions?.baseUrl || providerOptions?.baseURL) {
1209
- openaiConfig.baseURL = providerOptions.baseUrl || providerOptions.baseURL;
1210
- }
1211
- if (providerOptions?.gateway) {
1212
- logger5.info({ gateway: providerOptions.gateway }, "Setting up AI Gateway for OpenAI model");
1213
- Object.assign(openaiConfig, providerOptions.gateway);
1214
- }
1215
- if (Object.keys(openaiConfig).length > 0) {
1216
- logger5.info({ config: openaiConfig }, "Applying custom OpenAI provider configuration");
1217
- const provider = createOpenAI(openaiConfig);
1218
- return provider(modelName);
1219
- }
1220
- return openai(modelName);
1200
+ throw new Error(
1201
+ `Invalid model provided: ${modelString}. Please provide a model in the format of provider/model-name.`
1202
+ );
1221
1203
  }
1222
1204
  /**
1223
1205
  * Get generation parameters from provider options
@@ -1242,7 +1224,7 @@ var _ModelFactory = class _ModelFactory {
1242
1224
  * Includes maxDuration if specified in provider options (in seconds, following Vercel standard)
1243
1225
  */
1244
1226
  static prepareGenerationConfig(modelSettings) {
1245
- const modelString = modelSettings?.model?.trim() || "anthropic/claude-4-sonnet-20250514";
1227
+ const modelString = modelSettings?.model?.trim();
1246
1228
  const model = _ModelFactory.createModel({
1247
1229
  model: modelString,
1248
1230
  providerOptions: modelSettings?.providerOptions
@@ -1283,7 +1265,7 @@ var _ModelFactory = class _ModelFactory {
1283
1265
  /**
1284
1266
  * Supported providers for security validation
1285
1267
  */
1286
- __publicField(_ModelFactory, "SUPPORTED_PROVIDERS", ["anthropic", "openai"]);
1268
+ __publicField(_ModelFactory, "SUPPORTED_PROVIDERS", ["anthropic", "openai", "google"]);
1287
1269
  var ModelFactory = _ModelFactory;
1288
1270
  var tracer = getTracer("agents-run-api");
1289
1271
 
@@ -3349,7 +3331,7 @@ function createPropSelectorsSchema(artifactComponents) {
3349
3331
  Object.entries(summaryProps.properties).forEach(([propName, propDef]) => {
3350
3332
  const propDescription = propDef?.description || propDef?.title || `${propName} property`;
3351
3333
  propSchema[propName] = z4.string().describe(
3352
- `JMESPath selector for ${propName} (${propDescription}) - summary version, relative to base selector`
3334
+ `JMESPath selector for ${propName} (${propDescription}) - summary version, MUST be relative to your baseSelector target level. Access fields WITHIN the items your baseSelector returns.`
3353
3335
  );
3354
3336
  });
3355
3337
  }
@@ -3361,7 +3343,7 @@ function createPropSelectorsSchema(artifactComponents) {
3361
3343
  if (!propSchema[propName]) {
3362
3344
  const propDescription = propDef?.description || propDef?.title || `${propName} property`;
3363
3345
  propSchema[propName] = z4.string().describe(
3364
- `JMESPath selector for ${propName} (${propDescription}) - full version, relative to base selector`
3346
+ `JMESPath selector for ${propName} (${propDescription}) - MUST be relative to your baseSelector target level. If baseSelector stops at a document, this accesses fields WITHIN that document. Examples: "title", "content.body", "metadata.author"`
3365
3347
  );
3366
3348
  }
3367
3349
  });
@@ -3375,7 +3357,26 @@ function createPropSelectorsSchema(artifactComponents) {
3375
3357
  return z4.union(propSelectorSchemas);
3376
3358
  }
3377
3359
  return z4.record(z4.string(), z4.string()).describe(
3378
- "Prop selectors mapping schema properties to JMESPath expressions relative to base selector"
3360
+ `Prop selectors mapping schema properties to JMESPath expressions relative to base selector. Each path is relative to the item(s) your baseSelector returns.
3361
+
3362
+ \u{1F3AF} CRITICAL: PropSelectors work ONLY on the data your baseSelector returns!
3363
+ If baseSelector = "result.docs[0]" \u2192 propSelectors access fields INSIDE that doc
3364
+ If baseSelector = "result.docs[0].content[0]" \u2192 propSelectors access fields INSIDE that content item
3365
+
3366
+ \u2705 CORRECT EXAMPLES (paths relative to baseSelector target):
3367
+ \u2022 baseSelector: "result.documents[?type=='article']" \u2192 propSelectors: {"title": "title", "url": "url"}
3368
+ \u2022 baseSelector: "result.content[0].text" \u2192 propSelectors: {"content": "content[0].text", "source": "content[0].source"}
3369
+ \u2022 baseSelector: "result.items" \u2192 propSelectors: {"name": "profile.name", "email": "contact.email"}
3370
+
3371
+ \u274C WRONG EXAMPLES (accessing data not at baseSelector level):
3372
+ \u2022 baseSelector: "result.docs[0].content[0]" \u2192 propSelectors: {"title": "title"} \u2190 title is at doc level, not content level!
3373
+ \u2022 baseSelector: "result.source.content" \u2192 propSelectors: {"title": "content[4].text"} \u2190 baseSelector ends at array, can't index into it!
3374
+ \u2022 baseSelector: "result.items" \u2192 propSelectors: {"title": "documents[0].title"} \u2190 going deeper when baseSelector should handle depth
3375
+
3376
+ \u274C NEVER USE LITERAL VALUES:
3377
+ {"title": "Robert Tran", "url": "https://linkedin.com/..."}
3378
+
3379
+ \u{1F4A1} TIP: Match your baseSelector depth to where the properties you need actually exist!`
3379
3380
  );
3380
3381
  }
3381
3382
  function createInputSchema(artifactComponents) {
@@ -3384,7 +3385,18 @@ function createInputSchema(artifactComponents) {
3384
3385
  "EXACT toolCallId from a previous tool execution - copy it exactly from the tool call result. NEVER invent or make up tool call IDs."
3385
3386
  ),
3386
3387
  baseSelector: z4.string().describe(
3387
- `JMESPath selector to get to the main data array/object. ALWAYS start with "result." Example: "result.content[?type=='text']"`
3388
+ `JMESPath selector to get to the main data array/object. ALWAYS start with "result." That is a mandatory prefix.
3389
+
3390
+ Data structures are COMPLEX and NESTED. Examples:
3391
+ \u2022 "result.content[0].text.content[2]" - parsed JSON in text field
3392
+ \u2022 "result.structuredContent.content[1]" - direct structured data
3393
+ \u2022 "result.data.items[?type=='doc']" - filtered array
3394
+
3395
+ \u{1F6A8} CRITICAL: If you need data from array[4], your baseSelector must END at array[4], NOT at the array itself!
3396
+ \u2705 CORRECT: "result.source.content[4]" \u2192 propSelectors can access fields in that item
3397
+ \u274C WRONG: "result.source.content" \u2192 propSelectors can't use content[4] because baseSelector already selected the array
3398
+
3399
+ \u{1F525} IF YOUR PATH FAILS: READ THE ERROR MESSAGE! It tells you the correct path! \u{1F525}`
3388
3400
  ),
3389
3401
  propSelectors: createPropSelectorsSchema(artifactComponents)
3390
3402
  });
@@ -3403,6 +3415,9 @@ function createSaveToolResultTool(sessionId, streamRequestId, agentId, artifactC
3403
3415
  return tool({
3404
3416
  description: `Save tool results as structured artifacts. Each artifact should represent ONE SPECIFIC, IMPORTANT, and UNIQUE document or data item.
3405
3417
 
3418
+ \u26A1 CRITICAL: JSON-like text content in tool results is AUTOMATICALLY PARSED into proper JSON objects - treat all data as structured, not text strings.
3419
+ \u{1F6A8} CRITICAL: Data structures are deeply nested. When your path fails, READ THE ERROR MESSAGE - it shows the correct path!
3420
+
3406
3421
  AVAILABLE ARTIFACT TYPES:
3407
3422
  ${availableTypesWithDescriptions}
3408
3423
 
@@ -3414,26 +3429,6 @@ Each artifact you save becomes a SEPARATE DATA COMPONENT in the structured respo
3414
3429
  \u2705 UNIQUE with distinct value from other artifacts
3415
3430
  \u2705 RENDERED AS INDIVIDUAL DATA COMPONENT in the UI
3416
3431
 
3417
- \u274C DO NOT save multiple different items in one artifact unless they are EXTREMELY SIMILAR
3418
- \u274C DO NOT batch unrelated items together - each item becomes its own data component
3419
- \u274C DO NOT save generic collections - break them into individual data components
3420
-
3421
- \u{1F3AF} STRUCTURED DATA COMPONENT PRINCIPLE:
3422
- Each artifact save creates ONE data component that will be rendered separately in the UI. If you have 5 important items, save them as 5 separate artifacts to create 5 separate data components for better user experience.
3423
-
3424
- THINK: "What is the ONE most important piece of information here that deserves its own data component?"
3425
-
3426
- EXAMPLES OF GOOD INDIVIDUAL ARTIFACTS (SEPARATE DATA COMPONENTS):
3427
- - Nick Gomez's founder profile (specific person) \u2192 Individual data component
3428
- - The /users/create API endpoint documentation (specific endpoint) \u2192 Individual data component
3429
- - Error message for authentication failure (specific error type) \u2192 Individual data component
3430
- - Configuration for Redis caching (specific config topic) \u2192 Individual data component
3431
-
3432
- EXAMPLES OF BAD BATCHING:
3433
- \u274C "All team members" \u2192 Should be separate artifacts for each important member (separate data components)
3434
- \u274C "All API endpoints" \u2192 Should be separate artifacts for each distinct endpoint (separate data components)
3435
- \u274C "All error types" \u2192 Should be separate artifacts for each error category (separate data components)
3436
-
3437
3432
  USAGE PATTERN:
3438
3433
  1. baseSelector: Navigate through nested structures to target ONE SPECIFIC item
3439
3434
  - Navigate through all necessary levels: "result.data.items.nested[?condition]"
@@ -3443,9 +3438,11 @@ USAGE PATTERN:
3443
3438
  - NOT: "result.items[*]" (too broad, gets everything)
3444
3439
 
3445
3440
  2. propSelectors: Extract properties relative to your selected item
3446
- - Always relative to the single item that baseSelector returns
3447
- - Simple paths from that item: { prop1: "field_x", prop2: "nested.field_y", prop3: "deep.nested.field_z" }
3448
- - The tool handles array iteration - your selectors work on individual items
3441
+ - \u{1F3AF} CRITICAL: Always relative to the single item that baseSelector returns
3442
+ - If baseSelector ends at a document \u2192 propSelectors access document fields
3443
+ - If baseSelector ends at content[0] \u2192 propSelectors access content[0] fields
3444
+ - Simple paths from that exact level: { prop1: "field_x", prop2: "nested.field_y" }
3445
+ - \u274C DON'T try to go back up or deeper - adjust your baseSelector instead!
3449
3446
 
3450
3447
  3. Result: ONE artifact representing ONE important, unique item \u2192 ONE data component
3451
3448
 
@@ -3454,15 +3451,7 @@ USAGE PATTERN:
3454
3451
  - Focus on getting to the right level with baseSelector, then keep propSelectors simple
3455
3452
  - Test your baseSelector: Does it return exactly the items you want?
3456
3453
 
3457
- \u26A0\uFE0F STRICT SELECTIVITY RULES FOR DATA COMPONENTS:
3458
- - ALWAYS ask: "Is this ONE specific, important thing that deserves its own data component?"
3459
- - If the answer is no, don't save it or find a more specific selector
3460
- - Multiple similar items = Multiple separate artifact saves (use the tool multiple times) \u2192 Multiple data components
3461
- - Each artifact should be independently valuable and uniquely identifiable \u2192 Each data component stands alone
3462
- - BETTER to save 3 individual, specific artifacts (3 data components) than 1 generic collection (1 data component)
3463
-
3464
- \u{1F504} MULTIPLE ARTIFACTS = MULTIPLE DATA COMPONENTS:
3465
- Remember: Each time you call this tool, you create a separate data component. Call it multiple times for multiple items to create a rich, structured response with individual data components for each important piece of information.`,
3454
+ Please use Error Messages to Debug when there is an error in the tool call.`,
3466
3455
  inputSchema,
3467
3456
  execute: async ({ toolCallId, baseSelector, propSelectors, ...rest }, _context) => {
3468
3457
  const artifactType = "artifactType" in rest ? rest.artifactType : void 0;
@@ -5990,7 +5979,7 @@ ${output}`;
5990
5979
  { role: "user", content: userMessage },
5991
5980
  ...reasoningFlow,
5992
5981
  {
5993
- role: "system",
5982
+ role: "user",
5994
5983
  content: await this.buildPhase2SystemPrompt()
5995
5984
  }
5996
5985
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@inkeep/agents-run-api",
3
- "version": "0.0.0-dev-20250916015245",
3
+ "version": "0.0.0-dev-20250916190005",
4
4
  "description": "Agents Run API for Inkeep Agent Framework - handles chat, agent execution, and streaming",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,6 +11,7 @@
11
11
  "license": "SEE LICENSE IN LICENSE.md",
12
12
  "dependencies": {
13
13
  "@ai-sdk/anthropic": "2.0.2",
14
+ "@ai-sdk/google": "^2.0.14",
14
15
  "@ai-sdk/openai": "2.0.11",
15
16
  "@ai-sdk/react": "2.0.11",
16
17
  "@hono/node-server": "^1.14.3",
@@ -44,7 +45,7 @@
44
45
  "traverse": "^0.6.11",
45
46
  "ts-pattern": "^5.7.1",
46
47
  "zod": "^4.1.5",
47
- "@inkeep/agents-core": "^0.0.0-dev-20250916015245"
48
+ "@inkeep/agents-core": "^0.0.0-dev-20250916190005"
48
49
  },
49
50
  "devDependencies": {
50
51
  "@hono/vite-dev-server": "^0.20.1",