@squadbase/vite-server 0.1.17-dev.a9ddcfa → 0.1.17-dev.d4fff69

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 (80) hide show
  1. package/dist/cli/index.js +4299 -821
  2. package/dist/connectors/airtable-oauth.js +48 -8
  3. package/dist/connectors/airtable.js +44 -8
  4. package/dist/connectors/amplitude.js +8 -8
  5. package/dist/connectors/anthropic.js +2 -2
  6. package/dist/connectors/asana.js +37 -10
  7. package/dist/connectors/attio.js +30 -13
  8. package/dist/connectors/aws-billing.js +8 -8
  9. package/dist/connectors/azure-sql.js +47 -10
  10. package/dist/connectors/backlog-api-key.js +40 -15
  11. package/dist/connectors/clickup.js +50 -10
  12. package/dist/connectors/cosmosdb.js +12 -12
  13. package/dist/connectors/customerio.js +8 -8
  14. package/dist/connectors/dbt.js +686 -25
  15. package/dist/connectors/freshdesk.js +82 -8
  16. package/dist/connectors/freshsales.js +8 -8
  17. package/dist/connectors/freshservice.js +8 -8
  18. package/dist/connectors/gamma.js +15 -15
  19. package/dist/connectors/gemini.js +2 -2
  20. package/dist/connectors/github.js +12 -12
  21. package/dist/connectors/gmail-oauth.js +10 -10
  22. package/dist/connectors/gmail.js +4 -4
  23. package/dist/connectors/google-ads.js +8 -8
  24. package/dist/connectors/google-analytics-oauth.js +152 -25
  25. package/dist/connectors/google-analytics.js +490 -96
  26. package/dist/connectors/google-audit-log.js +4 -4
  27. package/dist/connectors/google-calendar-oauth.js +61 -15
  28. package/dist/connectors/google-calendar.js +61 -11
  29. package/dist/connectors/google-docs.js +10 -10
  30. package/dist/connectors/google-drive.js +32 -10
  31. package/dist/connectors/google-search-console-oauth.js +126 -17
  32. package/dist/connectors/google-sheets.js +6 -6
  33. package/dist/connectors/google-slides.js +10 -10
  34. package/dist/connectors/grafana.js +45 -10
  35. package/dist/connectors/hackernews.d.ts +5 -0
  36. package/dist/connectors/hackernews.js +890 -0
  37. package/dist/connectors/hubspot-oauth.js +41 -9
  38. package/dist/connectors/hubspot.js +25 -9
  39. package/dist/connectors/influxdb.js +8 -8
  40. package/dist/connectors/intercom-oauth.js +72 -12
  41. package/dist/connectors/intercom.js +12 -12
  42. package/dist/connectors/jdbc.js +37 -10
  43. package/dist/connectors/jira-api-key.js +68 -11
  44. package/dist/connectors/kintone-api-token.js +66 -18
  45. package/dist/connectors/kintone.js +54 -11
  46. package/dist/connectors/linear.js +54 -12
  47. package/dist/connectors/linkedin-ads.js +41 -14
  48. package/dist/connectors/mailchimp-oauth.js +6 -6
  49. package/dist/connectors/mailchimp.js +6 -6
  50. package/dist/connectors/meta-ads-oauth.js +33 -14
  51. package/dist/connectors/meta-ads.js +35 -14
  52. package/dist/connectors/mixpanel.js +8 -8
  53. package/dist/connectors/monday.js +9 -9
  54. package/dist/connectors/mongodb.js +8 -8
  55. package/dist/connectors/notion-oauth.js +60 -11
  56. package/dist/connectors/notion.js +60 -11
  57. package/dist/connectors/openai.js +2 -2
  58. package/dist/connectors/oracle.js +39 -11
  59. package/dist/connectors/outlook-oauth.js +21 -21
  60. package/dist/connectors/powerbi-oauth.js +13 -13
  61. package/dist/connectors/salesforce.js +42 -9
  62. package/dist/connectors/semrush.js +6 -6
  63. package/dist/connectors/sentry.js +36 -10
  64. package/dist/connectors/shopify-oauth.js +43 -10
  65. package/dist/connectors/shopify.js +8 -8
  66. package/dist/connectors/sqlserver.js +47 -10
  67. package/dist/connectors/stripe-api-key.js +66 -15
  68. package/dist/connectors/stripe-oauth.js +70 -19
  69. package/dist/connectors/supabase.js +31 -6
  70. package/dist/connectors/tableau.js +15 -15
  71. package/dist/connectors/tiktok-ads.js +37 -16
  72. package/dist/connectors/wix-store.js +8 -8
  73. package/dist/connectors/x.d.ts +5 -0
  74. package/dist/connectors/x.js +927 -0
  75. package/dist/connectors/zendesk-oauth.js +55 -12
  76. package/dist/connectors/zendesk.js +12 -12
  77. package/dist/index.js +4317 -819
  78. package/dist/main.js +4317 -819
  79. package/dist/vite-plugin.js +4297 -819
  80. package/package.json +9 -1
@@ -114,7 +114,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
114
114
  /**
115
115
  * Create tools for connections that belong to this connector.
116
116
  * Filters connections by connectorKey internally.
117
- * Returns tools keyed as `${connectorKey}_${toolName}`.
117
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
118
118
  */
119
119
  createTools(connections, config, opts) {
120
120
  const myConnections = connections.filter(
@@ -124,7 +124,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
124
124
  for (const t of Object.values(this.tools)) {
125
125
  const tool = t.createTool(myConnections, config);
126
126
  const originalToModelOutput = tool.toModelOutput;
127
- result[`${this.connectorKey}_${t.name}`] = {
127
+ result[`connector_${this.connectorKey}_${t.name}`] = {
128
128
  ...tool,
129
129
  toModelOutput: async (options) => {
130
130
  if (!originalToModelOutput) {
@@ -392,11 +392,11 @@ var hubspotOnboarding = new ConnectorOnboarding({
392
392
  - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
393
393
  },
394
394
  dataOverviewInstructions: {
395
- en: `1. Call hubspot-oauth_request with GET /crm/v3/objects/contacts?limit=5 to explore contacts structure
396
- 2. Call hubspot-oauth_request with GET /crm/v3/objects/deals?limit=5 to explore deals structure
395
+ en: `1. Call connector_hubspot-oauth_request with GET /crm/v3/objects/contacts?limit=5 to explore contacts structure
396
+ 2. Call connector_hubspot-oauth_request with GET /crm/v3/objects/deals?limit=5 to explore deals structure
397
397
  3. Explore other object types (companies, etc.) as needed to understand available data`,
398
- ja: `1. hubspot-oauth_request \u3067 GET /crm/v3/objects/contacts?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u69CB\u9020\u3092\u78BA\u8A8D
399
- 2. hubspot-oauth_request \u3067 GET /crm/v3/objects/deals?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u53D6\u5F15\u306E\u69CB\u9020\u3092\u78BA\u8A8D
398
+ ja: `1. connector_hubspot-oauth_request \u3067 GET /crm/v3/objects/contacts?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u69CB\u9020\u3092\u78BA\u8A8D
399
+ 2. connector_hubspot-oauth_request \u3067 GET /crm/v3/objects/deals?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u53D6\u5F15\u306E\u69CB\u9020\u3092\u78BA\u8A8D
400
400
  3. \u5FC5\u8981\u306B\u5FDC\u3058\u3066\u4ED6\u306E\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u30BF\u30A4\u30D7\uFF08\u4F01\u696D\u306A\u3069\uFF09\u3092\u63A2\u7D22\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30C7\u30FC\u30BF\u3092\u628A\u63E1`
401
401
  }
402
402
  });
@@ -434,6 +434,19 @@ async function listProperties(proxyFetch, objectType) {
434
434
  const data = await res.json();
435
435
  return data.results ?? [];
436
436
  }
437
+ async function fetchObjectCount(proxyFetch, objectType) {
438
+ try {
439
+ const res = await apiFetch(
440
+ proxyFetch,
441
+ `/crm/v3/objects/${objectType}?limit=1`
442
+ );
443
+ if (!res.ok) return null;
444
+ const data = await res.json();
445
+ return typeof data.total === "number" ? data.total : null;
446
+ } catch {
447
+ return null;
448
+ }
449
+ }
437
450
  var hubspotOauthSetupFlow = {
438
451
  initialState: () => ({}),
439
452
  steps: [
@@ -464,8 +477,27 @@ var hubspotOauthSetupFlow = {
464
477
  limit: HUBSPOT_SETUP_MAX_OBJECT_TYPES
465
478
  });
466
479
  const sections = ["## HubSpot", ""];
480
+ const countByType = /* @__PURE__ */ new Map();
481
+ for (const objectType of targetObjectTypes) {
482
+ countByType.set(
483
+ objectType,
484
+ await fetchObjectCount(rt.config.proxyFetch, objectType)
485
+ );
486
+ }
487
+ sections.push("### Record counts", "");
488
+ sections.push("| Object type | Record count |");
489
+ sections.push("|-------------|-------------|");
490
+ for (const objectType of targetObjectTypes) {
491
+ const count = countByType.get(objectType);
492
+ sections.push(
493
+ `| ${objectType} | ${count == null ? "-" : count.toLocaleString()} |`
494
+ );
495
+ }
496
+ sections.push("");
467
497
  for (const objectType of targetObjectTypes) {
468
- sections.push(`### Object: ${objectType}`, "");
498
+ const count = countByType.get(objectType);
499
+ const countLabel = count == null ? "" : ` (${count.toLocaleString()} records)`;
500
+ sections.push(`### Object: ${objectType}${countLabel}`, "");
469
501
  const props = await listProperties(rt.config.proxyFetch, objectType);
470
502
  const limited = props.slice(0, HUBSPOT_SETUP_MAX_PROPERTIES);
471
503
  sections.push("| Property | Type | Label |");
@@ -515,7 +547,7 @@ var hubspotOauthConnector = new ConnectorPlugin({
515
547
  systemPrompt: {
516
548
  en: `### Tools
517
549
 
518
- - \`hubspot-oauth_request\`: The only way to call the HubSpot API. Use it to query contacts, deals, companies, and other CRM objects. Authentication is configured automatically via OAuth. HubSpot uses cursor-based pagination with the \`after\` parameter from \`paging.next.after\` in the response.
550
+ - \`connector_hubspot-oauth_request\`: The only way to call the HubSpot API. Use it to query contacts, deals, companies, and other CRM objects. Authentication is configured automatically via OAuth. HubSpot uses cursor-based pagination with the \`after\` parameter from \`paging.next.after\` in the response.
519
551
 
520
552
  ### HubSpot API Reference
521
553
 
@@ -560,7 +592,7 @@ const data = await res.json();
560
592
  \`\`\``,
561
593
  ja: `### \u30C4\u30FC\u30EB
562
594
 
563
- - \`hubspot-oauth_request\`: HubSpot API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30B3\u30F3\u30BF\u30AF\u30C8\u3001\u53D6\u5F15\u3001\u4F1A\u793E\u3001\u305D\u306E\u4ED6\u306ECRM\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002HubSpot\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E \`paging.next.after\` \u304B\u3089\u306E \`after\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
595
+ - \`connector_hubspot-oauth_request\`: HubSpot API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30B3\u30F3\u30BF\u30AF\u30C8\u3001\u53D6\u5F15\u3001\u4F1A\u793E\u3001\u305D\u306E\u4ED6\u306ECRM\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002HubSpot\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E \`paging.next.after\` \u304B\u3089\u306E \`after\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
564
596
 
565
597
  ### HubSpot API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
566
598
 
@@ -257,7 +257,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
257
257
  /**
258
258
  * Create tools for connections that belong to this connector.
259
259
  * Filters connections by connectorKey internally.
260
- * Returns tools keyed as `${connectorKey}_${toolName}`.
260
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
261
261
  */
262
262
  createTools(connections, config, opts) {
263
263
  const myConnections = connections.filter(
@@ -267,7 +267,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
267
267
  for (const t of Object.values(this.tools)) {
268
268
  const tool = t.createTool(myConnections, config);
269
269
  const originalToModelOutput = tool.toModelOutput;
270
- result[`${this.connectorKey}_${t.name}`] = {
270
+ result[`connector_${this.connectorKey}_${t.name}`] = {
271
271
  ...tool,
272
272
  toModelOutput: async (options) => {
273
273
  if (!originalToModelOutput) {
@@ -397,11 +397,11 @@ var AUTH_TYPES = {
397
397
  // ../connectors/src/connectors/hubspot/setup.ts
398
398
  var hubspotOnboarding = new ConnectorOnboarding({
399
399
  dataOverviewInstructions: {
400
- en: `1. Call hubspot_request with GET /crm/v3/objects/contacts?limit=5 to explore contacts structure
401
- 2. Call hubspot_request with GET /crm/v3/objects/deals?limit=5 to explore deals structure
400
+ en: `1. Call connector_hubspot_request with GET /crm/v3/objects/contacts?limit=5 to explore contacts structure
401
+ 2. Call connector_hubspot_request with GET /crm/v3/objects/deals?limit=5 to explore deals structure
402
402
  3. Explore other object types (companies, tickets, etc.) as needed to understand available data`,
403
- ja: `1. hubspot_request \u3067 GET /crm/v3/objects/contacts?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u69CB\u9020\u3092\u78BA\u8A8D
404
- 2. hubspot_request \u3067 GET /crm/v3/objects/deals?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u53D6\u5F15\u306E\u69CB\u9020\u3092\u78BA\u8A8D
403
+ ja: `1. connector_hubspot_request \u3067 GET /crm/v3/objects/contacts?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u69CB\u9020\u3092\u78BA\u8A8D
404
+ 2. connector_hubspot_request \u3067 GET /crm/v3/objects/deals?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u53D6\u5F15\u306E\u69CB\u9020\u3092\u78BA\u8A8D
405
405
  3. \u5FC5\u8981\u306B\u5FDC\u3058\u3066\u4ED6\u306E\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u30BF\u30A4\u30D7\uFF08\u4F01\u696D\u3001\u30C1\u30B1\u30C3\u30C8\u306A\u3069\uFF09\u3092\u63A2\u7D22\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30C7\u30FC\u30BF\u3092\u628A\u63E1`
406
406
  }
407
407
  });
@@ -435,6 +435,20 @@ var HUBSPOT_OBJECT_TYPES = [
435
435
  { value: "meetings", label: "Meetings" },
436
436
  { value: "tasks", label: "Tasks" }
437
437
  ];
438
+ async function countObjects(params, objectType) {
439
+ try {
440
+ const res = await apiFetch(params, `/crm/v3/objects/${objectType}/search`, {
441
+ method: "POST",
442
+ headers: { "Content-Type": "application/json" },
443
+ body: JSON.stringify({ limit: 1 })
444
+ });
445
+ if (!res.ok) return null;
446
+ const data = await res.json();
447
+ return typeof data.total === "number" ? data.total : null;
448
+ } catch {
449
+ return null;
450
+ }
451
+ }
438
452
  async function listProperties(params, objectType) {
439
453
  const res = await apiFetch(params, `/crm/v3/properties/${objectType}`);
440
454
  if (!res.ok) {
@@ -479,7 +493,9 @@ var hubspotSetupFlow = {
479
493
  });
480
494
  const sections = ["## HubSpot", ""];
481
495
  for (const objectType of targetObjectTypes) {
482
- sections.push(`### Object: ${objectType}`, "");
496
+ const count = await countObjects(rt.params, objectType);
497
+ const heading = count != null ? `### Object: ${objectType} (${count.toLocaleString()} records)` : `### Object: ${objectType}`;
498
+ sections.push(heading, "");
483
499
  const props = await listProperties(rt.params, objectType);
484
500
  const limited = props.slice(0, HUBSPOT_SETUP_MAX_PROPERTIES);
485
501
  sections.push("| Property | Type | Label |");
@@ -595,7 +611,7 @@ var hubspotConnector = new ConnectorPlugin({
595
611
  systemPrompt: {
596
612
  en: `### Tools
597
613
 
598
- - \`hubspot_request\`: The only way to call the HubSpot API. Use it to query contacts, deals, companies, tickets, and other CRM objects. Authentication (Bearer token) is configured automatically. HubSpot uses cursor-based pagination with the \`after\` parameter from \`paging.next.after\` in the response. Use the search endpoint for complex queries with filters.
614
+ - \`connector_hubspot_request\`: The only way to call the HubSpot API. Use it to query contacts, deals, companies, tickets, and other CRM objects. Authentication (Bearer token) is configured automatically. HubSpot uses cursor-based pagination with the \`after\` parameter from \`paging.next.after\` in the response. Use the search endpoint for complex queries with filters.
599
615
 
600
616
  ### Business Logic
601
617
 
@@ -661,7 +677,7 @@ export default async function handler(c: Context) {
661
677
  - \`after\` \u2014 Pagination offset`,
662
678
  ja: `### \u30C4\u30FC\u30EB
663
679
 
664
- - \`hubspot_request\`: HubSpot API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30B3\u30F3\u30BF\u30AF\u30C8\u3001\u53D6\u5F15\u3001\u4F1A\u793E\u3001\u30C1\u30B1\u30C3\u30C8\u3001\u305D\u306E\u4ED6\u306ECRM\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Bearer\u30C8\u30FC\u30AF\u30F3\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002HubSpot\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E \`paging.next.after\` \u304B\u3089\u306E \`after\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002\u8907\u96D1\u306A\u30AF\u30A8\u30EA\u306B\u306F\u30D5\u30A3\u30EB\u30BF\u4ED8\u304D\u306Esearch\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
680
+ - \`connector_hubspot_request\`: HubSpot API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30B3\u30F3\u30BF\u30AF\u30C8\u3001\u53D6\u5F15\u3001\u4F1A\u793E\u3001\u30C1\u30B1\u30C3\u30C8\u3001\u305D\u306E\u4ED6\u306ECRM\u30AA\u30D6\u30B8\u30A7\u30AF\u30C8\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Bearer\u30C8\u30FC\u30AF\u30F3\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002HubSpot\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E \`paging.next.after\` \u304B\u3089\u306E \`after\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002\u8907\u96D1\u306A\u30AF\u30A8\u30EA\u306B\u306F\u30D5\u30A3\u30EB\u30BF\u4ED8\u304D\u306Esearch\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
665
681
 
666
682
  ### Business Logic
667
683
 
@@ -316,7 +316,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
316
316
  /**
317
317
  * Create tools for connections that belong to this connector.
318
318
  * Filters connections by connectorKey internally.
319
- * Returns tools keyed as `${connectorKey}_${toolName}`.
319
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
320
320
  */
321
321
  createTools(connections, config, opts) {
322
322
  const myConnections = connections.filter(
@@ -326,7 +326,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
326
326
  for (const t of Object.values(this.tools)) {
327
327
  const tool = t.createTool(myConnections, config);
328
328
  const originalToModelOutput = tool.toModelOutput;
329
- result[`${this.connectorKey}_${t.name}`] = {
329
+ result[`connector_${this.connectorKey}_${t.name}`] = {
330
330
  ...tool,
331
331
  toModelOutput: async (options) => {
332
332
  if (!originalToModelOutput) {
@@ -486,7 +486,7 @@ var influxdbOnboarding = new ConnectorOnboarding({
486
486
  dataOverviewInstructions: {
487
487
  en: `The instance may be either InfluxDB 3 (supports SQL) or InfluxDB 2 (Flux only; includes InfluxDB Cloud on '*.cloud2.influxdata.com'). Detect the variant first, then pick the matching endpoints.
488
488
 
489
- 1. Probe for InfluxDB 3: call influxdb_request with POST /api/v3/query_sql, body { "db": "<database>", "q": "SELECT 1" }
489
+ 1. Probe for InfluxDB 3: call connector_influxdb_request with POST /api/v3/query_sql, body { "db": "<database>", "q": "SELECT 1" }
490
490
  - 200 with JSON rows \u2192 InfluxDB 3. Continue with SQL.
491
491
  - 405 Method Not Allowed, or an HTML body like "<html>...405 Not Allowed..." \u2192 InfluxDB 2. Fall back to Flux (step 3).
492
492
  2. InfluxDB 3 data overview:
@@ -498,7 +498,7 @@ var influxdbOnboarding = new ConnectorOnboarding({
498
498
  - If the Organization parameter was not provided but v3 probing failed, ask the user to set it using updateConnectionParameters before continuing.`,
499
499
  ja: `\u63A5\u7D9A\u5148\u306F InfluxDB 3\uFF08SQL \u5BFE\u5FDC\uFF09\u3068 InfluxDB 2\uFF08Flux \u306E\u307F\u3002\`*.cloud2.influxdata.com\` \u306E InfluxDB Cloud \u3092\u542B\u3080\uFF09\u306E\u3069\u3061\u3089\u306E\u53EF\u80FD\u6027\u3082\u3042\u308A\u307E\u3059\u3002\u307E\u305A\u30D0\u30EA\u30A2\u30F3\u30C8\u3092\u5224\u5225\u3057\u3001\u305D\u308C\u306B\u5408\u3046\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002
500
500
 
501
- 1. InfluxDB 3 \u306E\u5224\u5225: influxdb_request \u3067 POST /api/v3/query_sql\u3001body { "db": "<database>", "q": "SELECT 1" } \u3092\u5B9F\u884C
501
+ 1. InfluxDB 3 \u306E\u5224\u5225: connector_influxdb_request \u3067 POST /api/v3/query_sql\u3001body { "db": "<database>", "q": "SELECT 1" } \u3092\u5B9F\u884C
502
502
  - 200 + JSON \u884C\u304C\u8FD4\u308B \u2192 InfluxDB 3\u3002\u305D\u306E\u307E\u307E SQL \u3067\u7D9A\u884C\u3002
503
503
  - 405 Method Not Allowed\u3001\u307E\u305F\u306F "<html>...405 Not Allowed..." \u306E\u3088\u3046\u306A HTML \u672C\u6587\u304C\u8FD4\u308B \u2192 InfluxDB 2\u3002Flux \u306B\u30D5\u30A9\u30FC\u30EB\u30D0\u30C3\u30AF\uFF08\u624B\u9806 3\uFF09\u3002
504
504
  2. InfluxDB 3 \u306E\u5834\u5408\u306E\u30C7\u30FC\u30BF\u6982\u8981:
@@ -875,13 +875,13 @@ var influxdbConnector = new ConnectorPlugin({
875
875
 
876
876
  The configured instance may be **InfluxDB 3** (supports SQL via \`/api/v3/query_sql\`) or **InfluxDB 2** (Flux only; includes InfluxDB Cloud on \`*.cloud2.influxdata.com\`). Always probe first, then use the matching endpoints:
877
877
 
878
- 1. Call \`influxdb_request\` POST \`/api/v3/query_sql\` with body \`{ "db": "<database>", "q": "SELECT 1" }\`
878
+ 1. Call \`connector_influxdb_request\` POST \`/api/v3/query_sql\` with body \`{ "db": "<database>", "q": "SELECT 1" }\`
879
879
  2. 200 + JSON rows \u2192 InfluxDB 3. Use SQL endpoints.
880
880
  3. 405 Method Not Allowed or HTML body (e.g. \`<html>...405 Not Allowed...</html>\`) \u2192 InfluxDB 2. Use Flux via \`/api/v2/query?org={org}\`. Require the \`org\` parameter; if missing, ask the user via \`updateConnectionParameters\`.
881
881
 
882
882
  ### Tools
883
883
 
884
- - \`influxdb_request\`: The only way to call the InfluxDB HTTP API. Use it to run SQL / InfluxQL / Flux queries, write line protocol, and inspect buckets / databases. Authentication (\`Authorization: Token {token}\`) and the instance URL are configured automatically. On InfluxDB 3 prefer SQL (\`POST /api/v3/query_sql\`) \u2014 it returns JSON rows that are directly usable. On InfluxDB 2 use Flux (\`POST /api/v2/query?org={org}\`) \u2014 the response is annotated CSV. Writes use \`POST /api/v3/write_lp?db={db}\` (v3) or \`POST /api/v2/write?org={org}&bucket={bucket}\` (v2) with a line-protocol body and \`contentType\` set to \`text/plain; charset=utf-8\`.
884
+ - \`connector_influxdb_request\`: The only way to call the InfluxDB HTTP API. Use it to run SQL / InfluxQL / Flux queries, write line protocol, and inspect buckets / databases. Authentication (\`Authorization: Token {token}\`) and the instance URL are configured automatically. On InfluxDB 3 prefer SQL (\`POST /api/v3/query_sql\`) \u2014 it returns JSON rows that are directly usable. On InfluxDB 2 use Flux (\`POST /api/v2/query?org={org}\`) \u2014 the response is annotated CSV. Writes use \`POST /api/v3/write_lp?db={db}\` (v3) or \`POST /api/v2/write?org={org}&bucket={bucket}\` (v2) with a line-protocol body and \`contentType\` set to \`text/plain; charset=utf-8\`.
885
885
 
886
886
  ### Business Logic
887
887
 
@@ -946,13 +946,13 @@ export default async function handler(c: Context) {
946
946
 
947
947
  \u63A5\u7D9A\u5148\u306F **InfluxDB 3**\uFF08\`/api/v3/query_sql\` \u306E SQL \u5BFE\u5FDC\uFF09\u3068 **InfluxDB 2**\uFF08Flux \u306E\u307F\u3002\`*.cloud2.influxdata.com\` \u306E InfluxDB Cloud \u3092\u542B\u3080\uFF09\u306E\u3069\u3061\u3089\u306E\u53EF\u80FD\u6027\u3082\u3042\u308A\u307E\u3059\u3002\u5FC5\u305A\u6700\u521D\u306B\u30D7\u30ED\u30FC\u30D6\u3057\u3066\u304B\u3089\u3001\u5BFE\u5FDC\u3059\u308B\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044:
948
948
 
949
- 1. \`influxdb_request\` \u3067 POST \`/api/v3/query_sql\`\u3001body \`{ "db": "<database>", "q": "SELECT 1" }\` \u3092\u547C\u3073\u51FA\u3059
949
+ 1. \`connector_influxdb_request\` \u3067 POST \`/api/v3/query_sql\`\u3001body \`{ "db": "<database>", "q": "SELECT 1" }\` \u3092\u547C\u3073\u51FA\u3059
950
950
  2. 200 + JSON \u884C \u2192 InfluxDB 3\u3002SQL \u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3092\u4F7F\u7528\u3002
951
951
  3. 405 Method Not Allowed\u3001\u307E\u305F\u306F HTML \u672C\u6587\uFF08\u4F8B: \`<html>...405 Not Allowed...</html>\`\uFF09\u2192 InfluxDB 2\u3002\`/api/v2/query?org={org}\` \u304B\u3089 Flux \u3092\u4F7F\u7528\u3002\`org\` \u30D1\u30E9\u30E1\u30FC\u30BF\u5FC5\u9808\u3002\u672A\u8A2D\u5B9A\u306A\u3089 \`updateConnectionParameters\` \u3067\u30E6\u30FC\u30B6\u30FC\u306B\u8A2D\u5B9A\u3092\u4F9D\u983C\u3059\u308B\u3002
952
952
 
953
953
  ### \u30C4\u30FC\u30EB
954
954
 
955
- - \`influxdb_request\`: InfluxDB HTTP API \u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002SQL / InfluxQL / Flux \u30AF\u30A8\u30EA\u306E\u5B9F\u884C\u3001line protocol \u66F8\u304D\u8FBC\u307F\u3001bucket / database \u306E\u78BA\u8A8D\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08\`Authorization: Token {token}\`\uFF09\u3068 instance URL \u306F\u81EA\u52D5\u3067\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002InfluxDB 3 \u3067\u306F SQL (\`POST /api/v3/query_sql\`) \u304C JSON \u884C\u3092\u8FD4\u3059\u305F\u3081\u6700\u3082\u6271\u3044\u3084\u3059\u3044\u3067\u3059\u3002InfluxDB 2 \u3067\u306F Flux (\`POST /api/v2/query?org={org}\`) \u3092\u4F7F\u7528\u3057\u3001\u30EC\u30B9\u30DD\u30F3\u30B9\u306F\u6CE8\u91C8\u4ED8\u304D CSV \u3067\u3059\u3002\u66F8\u304D\u8FBC\u307F\u306F \`POST /api/v3/write_lp?db={db}\` (v3) \u307E\u305F\u306F \`POST /api/v2/write?org={org}&bucket={bucket}\` (v2) \u306B line protocol \u3092\u9001\u308A\u307E\u3059\uFF08\`contentType\` \u306F \`text/plain; charset=utf-8\`\uFF09\u3002
955
+ - \`connector_influxdb_request\`: InfluxDB HTTP API \u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002SQL / InfluxQL / Flux \u30AF\u30A8\u30EA\u306E\u5B9F\u884C\u3001line protocol \u66F8\u304D\u8FBC\u307F\u3001bucket / database \u306E\u78BA\u8A8D\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08\`Authorization: Token {token}\`\uFF09\u3068 instance URL \u306F\u81EA\u52D5\u3067\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002InfluxDB 3 \u3067\u306F SQL (\`POST /api/v3/query_sql\`) \u304C JSON \u884C\u3092\u8FD4\u3059\u305F\u3081\u6700\u3082\u6271\u3044\u3084\u3059\u3044\u3067\u3059\u3002InfluxDB 2 \u3067\u306F Flux (\`POST /api/v2/query?org={org}\`) \u3092\u4F7F\u7528\u3057\u3001\u30EC\u30B9\u30DD\u30F3\u30B9\u306F\u6CE8\u91C8\u4ED8\u304D CSV \u3067\u3059\u3002\u66F8\u304D\u8FBC\u307F\u306F \`POST /api/v3/write_lp?db={db}\` (v3) \u307E\u305F\u306F \`POST /api/v2/write?org={org}&bucket={bucket}\` (v2) \u306B line protocol \u3092\u9001\u308A\u307E\u3059\uFF08\`contentType\` \u306F \`text/plain; charset=utf-8\`\uFF09\u3002
956
956
 
957
957
  ### Business Logic
958
958
 
@@ -114,7 +114,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
114
114
  /**
115
115
  * Create tools for connections that belong to this connector.
116
116
  * Filters connections by connectorKey internally.
117
- * Returns tools keyed as `${connectorKey}_${toolName}`.
117
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
118
118
  */
119
119
  createTools(connections, config, opts) {
120
120
  const myConnections = connections.filter(
@@ -124,7 +124,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
124
124
  for (const t of Object.values(this.tools)) {
125
125
  const tool = t.createTool(myConnections, config);
126
126
  const originalToModelOutput = tool.toModelOutput;
127
- result[`${this.connectorKey}_${t.name}`] = {
127
+ result[`connector_${this.connectorKey}_${t.name}`] = {
128
128
  ...tool,
129
129
  toModelOutput: async (options) => {
130
130
  if (!originalToModelOutput) {
@@ -397,14 +397,14 @@ var intercomOauthOnboarding = new ConnectorOnboarding({
397
397
  - \u30C4\u30FC\u30EB\u9593\u306F1\u6587\u3060\u3051\u66F8\u3044\u3066\u5373\u6B21\u306E\u30C4\u30FC\u30EB\u547C\u3073\u51FA\u3057\u3002\u4E0D\u8981\u306A\u8AAC\u660E\u306F\u7701\u7565\u3057\u3001\u52B9\u7387\u7684\u306B\u9032\u3081\u308B`
398
398
  },
399
399
  dataOverviewInstructions: {
400
- en: `1. Call intercom-oauth_request with GET /contacts?per_page=5 to explore contacts structure
401
- 2. Call intercom-oauth_request with GET /conversations?per_page=5 to explore conversations structure
402
- 3. Call intercom-oauth_request with GET /data_attributes?model=contact to list contact data attributes
403
- 4. Call intercom-oauth_request with GET /companies?per_page=5 to explore company structure`,
404
- ja: `1. intercom-oauth_request \u3067 GET /contacts?per_page=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u69CB\u9020\u3092\u78BA\u8A8D
405
- 2. intercom-oauth_request \u3067 GET /conversations?per_page=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u4F1A\u8A71\u306E\u69CB\u9020\u3092\u78BA\u8A8D
406
- 3. intercom-oauth_request \u3067 GET /data_attributes?model=contact \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u30C7\u30FC\u30BF\u5C5E\u6027\u3092\u78BA\u8A8D
407
- 4. intercom-oauth_request \u3067 GET /companies?per_page=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u4F01\u696D\u306E\u69CB\u9020\u3092\u78BA\u8A8D`
400
+ en: `1. Call connector_intercom-oauth_request with GET /contacts?per_page=5 to explore contacts structure
401
+ 2. Call connector_intercom-oauth_request with GET /conversations?per_page=5 to explore conversations structure
402
+ 3. Call connector_intercom-oauth_request with GET /data_attributes?model=contact to list contact data attributes
403
+ 4. Call connector_intercom-oauth_request with GET /companies?per_page=5 to explore company structure`,
404
+ ja: `1. connector_intercom-oauth_request \u3067 GET /contacts?per_page=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u69CB\u9020\u3092\u78BA\u8A8D
405
+ 2. connector_intercom-oauth_request \u3067 GET /conversations?per_page=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u4F1A\u8A71\u306E\u69CB\u9020\u3092\u78BA\u8A8D
406
+ 3. connector_intercom-oauth_request \u3067 GET /data_attributes?model=contact \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u30C7\u30FC\u30BF\u5C5E\u6027\u3092\u78BA\u8A8D
407
+ 4. connector_intercom-oauth_request \u3067 GET /companies?per_page=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u4F01\u696D\u306E\u69CB\u9020\u3092\u78BA\u8A8D`
408
408
  }
409
409
  });
410
410
 
@@ -493,6 +493,66 @@ var intercomOauthSetupFlow = {
493
493
  );
494
494
  }
495
495
  sections.push("");
496
+ if (targetScopes.includes("conversations")) {
497
+ try {
498
+ const convRes = await apiFetch(
499
+ rt.config.proxyFetch,
500
+ "/conversations?per_page=5&order=desc&sort=updated_at"
501
+ );
502
+ if (convRes.ok) {
503
+ const convData = await convRes.json();
504
+ const conversations = convData.conversations ?? [];
505
+ if (conversations.length > 0) {
506
+ sections.push("### Recent conversations (sample)", "");
507
+ sections.push("| ID | State | Subject | Created |");
508
+ sections.push("|----|-------|---------|---------|");
509
+ for (const c of conversations.slice(0, 5)) {
510
+ const id = c.id ?? "-";
511
+ const state2 = c.state ?? (c.open ? "open" : "closed");
512
+ const subject = (c.source?.subject ?? "-").replace(/\|/g, "\\|").slice(0, 50);
513
+ const created = typeof c.created_at === "number" ? new Date(c.created_at * 1e3).toISOString().slice(0, 10) : "-";
514
+ sections.push(
515
+ `| ${id} | ${state2} | ${subject} | ${created} |`
516
+ );
517
+ }
518
+ sections.push("");
519
+ }
520
+ }
521
+ } catch {
522
+ }
523
+ }
524
+ if (targetScopes.includes("contacts")) {
525
+ try {
526
+ const contactRes = await apiFetch(
527
+ rt.config.proxyFetch,
528
+ "/contacts?per_page=50"
529
+ );
530
+ if (contactRes.ok) {
531
+ const contactData = await contactRes.json();
532
+ const contacts = contactData.data ?? [];
533
+ if (contacts.length > 0) {
534
+ const roleCounts = {};
535
+ for (const c of contacts) {
536
+ const role = c.role ?? "unknown";
537
+ roleCounts[role] = (roleCounts[role] ?? 0) + 1;
538
+ }
539
+ sections.push(
540
+ "### Contact type breakdown (from recent contacts)",
541
+ ""
542
+ );
543
+ sections.push("| Role | Count |");
544
+ sections.push("|------|-------|");
545
+ for (const [role, cnt] of Object.entries(roleCounts).sort(
546
+ (a, b) => b[1] - a[1]
547
+ )) {
548
+ sections.push(`| ${role} | ${cnt} |`);
549
+ }
550
+ sections.push("");
551
+ }
552
+ }
553
+ } catch {
554
+ }
555
+ }
496
556
  return sections.join("\n");
497
557
  }
498
558
  };
@@ -524,7 +584,7 @@ var intercomOauthConnector = new ConnectorPlugin({
524
584
  systemPrompt: {
525
585
  en: `### Tools
526
586
 
527
- - \`intercom-oauth_request\`: The only way to call the Intercom API. Use it to query contacts, conversations, companies, articles, tags, segments, and more. Authentication is configured automatically via OAuth. The Intercom-Version header is set automatically. Intercom uses cursor-based pagination with the \`starting_after\` parameter from \`pages.next.starting_after\` in the response.
587
+ - \`connector_intercom-oauth_request\`: The only way to call the Intercom API. Use it to query contacts, conversations, companies, articles, tags, segments, and more. Authentication is configured automatically via OAuth. The Intercom-Version header is set automatically. Intercom uses cursor-based pagination with the \`starting_after\` parameter from \`pages.next.starting_after\` in the response.
528
588
 
529
589
  ### Intercom API Reference
530
590
 
@@ -582,7 +642,7 @@ const data = await res.json();
582
642
  \`\`\``,
583
643
  ja: `### \u30C4\u30FC\u30EB
584
644
 
585
- - \`intercom-oauth_request\`: Intercom API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30B3\u30F3\u30BF\u30AF\u30C8\u3001\u4F1A\u8A71\u3001\u4F01\u696D\u3001\u8A18\u4E8B\u3001\u30BF\u30B0\u3001\u30BB\u30B0\u30E1\u30F3\u30C8\u306A\u3069\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002Intercom-Version\u30D8\u30C3\u30C0\u30FC\u3082\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002Intercom\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E \`pages.next.starting_after\` \u304B\u3089\u306E \`starting_after\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
645
+ - \`connector_intercom-oauth_request\`: Intercom API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30B3\u30F3\u30BF\u30AF\u30C8\u3001\u4F1A\u8A71\u3001\u4F01\u696D\u3001\u8A18\u4E8B\u3001\u30BF\u30B0\u3001\u30BB\u30B0\u30E1\u30F3\u30C8\u306A\u3069\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002Intercom-Version\u30D8\u30C3\u30C0\u30FC\u3082\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002Intercom\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E \`pages.next.starting_after\` \u304B\u3089\u306E \`starting_after\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
586
646
 
587
647
  ### Intercom API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
588
648
 
@@ -275,7 +275,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
275
275
  /**
276
276
  * Create tools for connections that belong to this connector.
277
277
  * Filters connections by connectorKey internally.
278
- * Returns tools keyed as `${connectorKey}_${toolName}`.
278
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
279
279
  */
280
280
  createTools(connections, config, opts) {
281
281
  const myConnections = connections.filter(
@@ -285,7 +285,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
285
285
  for (const t of Object.values(this.tools)) {
286
286
  const tool = t.createTool(myConnections, config);
287
287
  const originalToModelOutput = tool.toModelOutput;
288
- result[`${this.connectorKey}_${t.name}`] = {
288
+ result[`connector_${this.connectorKey}_${t.name}`] = {
289
289
  ...tool,
290
290
  toModelOutput: async (options) => {
291
291
  if (!originalToModelOutput) {
@@ -415,14 +415,14 @@ var AUTH_TYPES = {
415
415
  // ../connectors/src/connectors/intercom/setup.ts
416
416
  var intercomOnboarding = new ConnectorOnboarding({
417
417
  dataOverviewInstructions: {
418
- en: `1. Call intercom_request with GET /contacts?per_page=5 to explore contacts structure
419
- 2. Call intercom_request with GET /conversations?per_page=5 to explore conversations structure
420
- 3. Call intercom_request with GET /data_attributes?model=contact to list contact data attributes
421
- 4. Call intercom_request with GET /companies?per_page=5 to explore company structure`,
422
- ja: `1. intercom_request \u3067 GET /contacts?per_page=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u69CB\u9020\u3092\u78BA\u8A8D
423
- 2. intercom_request \u3067 GET /conversations?per_page=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u4F1A\u8A71\u306E\u69CB\u9020\u3092\u78BA\u8A8D
424
- 3. intercom_request \u3067 GET /data_attributes?model=contact \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u30C7\u30FC\u30BF\u5C5E\u6027\u3092\u78BA\u8A8D
425
- 4. intercom_request \u3067 GET /companies?per_page=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u4F01\u696D\u306E\u69CB\u9020\u3092\u78BA\u8A8D`
418
+ en: `1. Call connector_intercom_request with GET /contacts?per_page=5 to explore contacts structure
419
+ 2. Call connector_intercom_request with GET /conversations?per_page=5 to explore conversations structure
420
+ 3. Call connector_intercom_request with GET /data_attributes?model=contact to list contact data attributes
421
+ 4. Call connector_intercom_request with GET /companies?per_page=5 to explore company structure`,
422
+ ja: `1. connector_intercom_request \u3067 GET /contacts?per_page=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u69CB\u9020\u3092\u78BA\u8A8D
423
+ 2. connector_intercom_request \u3067 GET /conversations?per_page=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u4F1A\u8A71\u306E\u69CB\u9020\u3092\u78BA\u8A8D
424
+ 3. connector_intercom_request \u3067 GET /data_attributes?model=contact \u3092\u547C\u3073\u51FA\u3057\u3001\u30B3\u30F3\u30BF\u30AF\u30C8\u306E\u30C7\u30FC\u30BF\u5C5E\u6027\u3092\u78BA\u8A8D
425
+ 4. connector_intercom_request \u3067 GET /companies?per_page=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u4F01\u696D\u306E\u69CB\u9020\u3092\u78BA\u8A8D`
426
426
  }
427
427
  });
428
428
 
@@ -619,7 +619,7 @@ var intercomConnector = new ConnectorPlugin({
619
619
  systemPrompt: {
620
620
  en: `### Tools
621
621
 
622
- - \`intercom_request\`: The only way to call the Intercom API. Use it to query contacts, conversations, companies, articles, tags, segments, and more. Authentication (Bearer token) and API version header (Intercom-Version: 2.11) are configured automatically. Intercom uses cursor-based pagination with the \`starting_after\` parameter from \`pages.next.starting_after\` in the response. Use search endpoints (POST) for complex queries with filters.
622
+ - \`connector_intercom_request\`: The only way to call the Intercom API. Use it to query contacts, conversations, companies, articles, tags, segments, and more. Authentication (Bearer token) and API version header (Intercom-Version: 2.11) are configured automatically. Intercom uses cursor-based pagination with the \`starting_after\` parameter from \`pages.next.starting_after\` in the response. Use search endpoints (POST) for complex queries with filters.
623
623
 
624
624
  ### Business Logic
625
625
 
@@ -715,7 +715,7 @@ export default async function handler(c: Context) {
715
715
  - Date fields use Unix timestamps`,
716
716
  ja: `### \u30C4\u30FC\u30EB
717
717
 
718
- - \`intercom_request\`: Intercom API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30B3\u30F3\u30BF\u30AF\u30C8\u3001\u4F1A\u8A71\u3001\u4F01\u696D\u3001\u8A18\u4E8B\u3001\u30BF\u30B0\u3001\u30BB\u30B0\u30E1\u30F3\u30C8\u306A\u3069\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Bearer\u30C8\u30FC\u30AF\u30F3\uFF09\u3068API\u30D0\u30FC\u30B8\u30E7\u30F3\u30D8\u30C3\u30C0\u30FC\uFF08Intercom-Version: 2.11\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002Intercom\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E \`pages.next.starting_after\` \u304B\u3089\u306E \`starting_after\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002\u8907\u96D1\u306A\u30AF\u30A8\u30EA\u306B\u306Fsearch\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\uFF08POST\uFF09\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
718
+ - \`connector_intercom_request\`: Intercom API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30B3\u30F3\u30BF\u30AF\u30C8\u3001\u4F1A\u8A71\u3001\u4F01\u696D\u3001\u8A18\u4E8B\u3001\u30BF\u30B0\u3001\u30BB\u30B0\u30E1\u30F3\u30C8\u306A\u3069\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08Bearer\u30C8\u30FC\u30AF\u30F3\uFF09\u3068API\u30D0\u30FC\u30B8\u30E7\u30F3\u30D8\u30C3\u30C0\u30FC\uFF08Intercom-Version: 2.11\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002Intercom\u306F\u30EC\u30B9\u30DD\u30F3\u30B9\u306E \`pages.next.starting_after\` \u304B\u3089\u306E \`starting_after\` \u30D1\u30E9\u30E1\u30FC\u30BF\u306B\u3088\u308B\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u306E\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002\u8907\u96D1\u306A\u30AF\u30A8\u30EA\u306B\u306Fsearch\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\uFF08POST\uFF09\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002
719
719
 
720
720
  ### Business Logic
721
721
 
@@ -341,7 +341,7 @@ async function runMssqlQuery(parsed, sql, options = {}) {
341
341
  try {
342
342
  const result = await pool.request().query(sql);
343
343
  const recordset = result.recordset ?? [];
344
- return { rows: recordset };
344
+ return { rows: recordset, rowsAffected: result.rowsAffected ?? [] };
345
345
  } finally {
346
346
  await pool.close();
347
347
  }
@@ -526,10 +526,16 @@ async function runOracleQuery(parsed, sql, options = {}) {
526
526
  outFormat: oracledb.OUT_FORMAT_OBJECT,
527
527
  // Bound by the connector's own row cap, but keep the driver from
528
528
  // streaming arbitrarily large result sets.
529
- maxRows: 5e3
529
+ maxRows: 5e3,
530
+ // oracledb defaults to autoCommit=false, which silently rolls back
531
+ // DML when the connection closes.
532
+ autoCommit: true
530
533
  }
531
534
  );
532
- return { rows: result.rows ?? [] };
535
+ return {
536
+ rows: result.rows ?? [],
537
+ rowsAffected: result.rowsAffected
538
+ };
533
539
  } finally {
534
540
  try {
535
541
  await connection2.close();
@@ -1023,7 +1029,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
1023
1029
  /**
1024
1030
  * Create tools for connections that belong to this connector.
1025
1031
  * Filters connections by connectorKey internally.
1026
- * Returns tools keyed as `${connectorKey}_${toolName}`.
1032
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
1027
1033
  */
1028
1034
  createTools(connections, config, opts) {
1029
1035
  const myConnections = connections.filter(
@@ -1033,7 +1039,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
1033
1039
  for (const t of Object.values(this.tools)) {
1034
1040
  const tool = t.createTool(myConnections, config);
1035
1041
  const originalToModelOutput = tool.toModelOutput;
1036
- result[`${this.connectorKey}_${t.name}`] = {
1042
+ result[`connector_${this.connectorKey}_${t.name}`] = {
1037
1043
  ...tool,
1038
1044
  toModelOutput: async (options) => {
1039
1045
  if (!originalToModelOutput) {
@@ -1160,6 +1166,12 @@ var AUTH_TYPES = {
1160
1166
  USER_PASSWORD: "user-password"
1161
1167
  };
1162
1168
 
1169
+ // ../connectors/src/lib/sql-dml.ts
1170
+ function isDmlStatement(sql) {
1171
+ const stripped = sql.replace(/^(\s*(--[^\n]*\n|\/\*[\s\S]*?\*\/))+/, "").trimStart();
1172
+ return /^(insert|update|delete|merge)\b/i.test(stripped);
1173
+ }
1174
+
1163
1175
  // ../connectors/src/connectors/jdbc/index.ts
1164
1176
  init_pg_pool();
1165
1177
  init_ssh_tunnel();
@@ -1171,13 +1183,13 @@ init_utils2();
1171
1183
  // ../connectors/src/connectors/jdbc/setup.ts
1172
1184
  var jdbcOnboarding = new ConnectorOnboarding({
1173
1185
  dataOverviewInstructions: {
1174
- en: `1. Use \`jdbc_executeQuery\` to detect the database flavor: \`SELECT version()\` (works on PostgreSQL/MySQL/MariaDB)
1186
+ en: `1. Use \`connector_jdbc_executeQuery\` to detect the database flavor: \`SELECT version()\` (works on PostgreSQL/MySQL/MariaDB)
1175
1187
  2. List tables:
1176
1188
  - PostgreSQL: \`SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'\`
1177
1189
  - MySQL/MariaDB: \`SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()\`
1178
1190
  3. For key tables, fetch column info from \`information_schema.columns\`
1179
1191
  4. Sample up to 3 tables with \`SELECT * FROM <table_name> LIMIT 5\` if column info alone is insufficient`,
1180
- ja: `1. \`jdbc_executeQuery\` \u3067DB\u30D5\u30EC\u30FC\u30D0\u30FC\u3092\u5224\u5B9A: \`SELECT version()\` (PostgreSQL/MySQL/MariaDB \u3067\u52D5\u4F5C)
1192
+ ja: `1. \`connector_jdbc_executeQuery\` \u3067DB\u30D5\u30EC\u30FC\u30D0\u30FC\u3092\u5224\u5B9A: \`SELECT version()\` (PostgreSQL/MySQL/MariaDB \u3067\u52D5\u4F5C)
1181
1193
  2. \u30C6\u30FC\u30D6\u30EB\u4E00\u89A7\u3092\u53D6\u5F97:
1182
1194
  - PostgreSQL: \`SELECT table_name FROM information_schema.tables WHERE table_schema = 'public'\`
1183
1195
  - MySQL/MariaDB: \`SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_SCHEMA = DATABASE()\`
@@ -1522,6 +1534,9 @@ var outputSchema = z.discriminatedUnion("success", [
1522
1534
  z.object({
1523
1535
  success: z.literal(true),
1524
1536
  rowCount: z.number(),
1537
+ rowsAffected: z.number().optional().describe(
1538
+ "Affected rows for INSERT/UPDATE/DELETE; undefined for SELECT"
1539
+ ),
1525
1540
  truncated: z.boolean(),
1526
1541
  rows: z.array(z.record(z.string(), z.unknown()))
1527
1542
  }),
@@ -1536,7 +1551,8 @@ var executeQueryTool = new ConnectorTool({
1536
1551
  Use for: schema exploration via \`information_schema\` (or USER_TABLES on Oracle), data sampling, analytical queries.
1537
1552
  The connector dispatches by JDBC URL prefix to the matching driver
1538
1553
  (PostgreSQL / Redshift / MySQL / MariaDB / SQL Server / Oracle), so use the dialect that matches the connection.
1539
- Always bound results: LIMIT for PG/MySQL/Redshift, TOP for SQL Server, FETCH FIRST for Oracle.`,
1554
+ Always bound results: LIMIT for PG/MySQL/Redshift, TOP for SQL Server, FETCH FIRST for Oracle.
1555
+ For INSERT/UPDATE/DELETE, \`rowCount\` is 0 and \`rows\` is empty (rowCount counts returned rows, not affected rows) \u2014 this is normal, not a failure; check \`rowsAffected\` for the number of affected rows.`,
1540
1556
  inputSchema,
1541
1557
  outputSchema,
1542
1558
  async execute({ connectionId, sql }, connections) {
@@ -1574,6 +1590,9 @@ Always bound results: LIMIT for PG/MySQL/Redshift, TOP for SQL Server, FETCH FIR
1574
1590
  return {
1575
1591
  success: true,
1576
1592
  rowCount: Math.min(rows.length, MAX_ROWS),
1593
+ // tedious counts SELECT result rows in rowsAffected too, so only
1594
+ // report it for DML. Multi-statement batches are summed.
1595
+ rowsAffected: isDmlStatement(sql) ? result.rowsAffected.reduce((sum, n) => sum + n, 0) : void 0,
1577
1596
  truncated: rows.length > MAX_ROWS,
1578
1597
  rows: rows.slice(0, MAX_ROWS)
1579
1598
  };
@@ -1591,6 +1610,8 @@ Always bound results: LIMIT for PG/MySQL/Redshift, TOP for SQL Server, FETCH FIR
1591
1610
  return {
1592
1611
  success: true,
1593
1612
  rowCount: Math.min(rows.length, MAX_ROWS),
1613
+ // oracledb sets rowsAffected only for DML; undefined for SELECT.
1614
+ rowsAffected: result.rowsAffected,
1594
1615
  truncated: rows.length > MAX_ROWS,
1595
1616
  rows: rows.slice(0, MAX_ROWS)
1596
1617
  };
@@ -1617,9 +1638,13 @@ Always bound results: LIMIT for PG/MySQL/Redshift, TOP for SQL Server, FETCH FIR
1617
1638
  );
1618
1639
  const rows = result.rows;
1619
1640
  const truncated = rows.length > MAX_ROWS;
1641
+ const isDml = ["INSERT", "UPDATE", "DELETE", "MERGE"].includes(
1642
+ result.command
1643
+ );
1620
1644
  return {
1621
1645
  success: true,
1622
1646
  rowCount: Math.min(rows.length, MAX_ROWS),
1647
+ rowsAffected: isDml ? result.rowCount ?? 0 : void 0,
1623
1648
  truncated,
1624
1649
  rows: rows.slice(0, MAX_ROWS)
1625
1650
  };
@@ -1643,9 +1668,11 @@ Always bound results: LIMIT for PG/MySQL/Redshift, TOP for SQL Server, FETCH FIR
1643
1668
  const [rows] = await Promise.race([queryPromise, timeoutPromise]);
1644
1669
  const resultRows = Array.isArray(rows) ? rows : [];
1645
1670
  const truncated = resultRows.length > MAX_ROWS;
1671
+ const rowsAffected = !Array.isArray(rows) && rows !== null && typeof rows === "object" && "affectedRows" in rows && typeof rows.affectedRows === "number" ? rows.affectedRows : void 0;
1646
1672
  return {
1647
1673
  success: true,
1648
1674
  rowCount: Math.min(resultRows.length, MAX_ROWS),
1675
+ rowsAffected,
1649
1676
  truncated,
1650
1677
  rows: resultRows.slice(0, MAX_ROWS)
1651
1678
  };
@@ -1697,7 +1724,7 @@ var jdbcConnector = new ConnectorPlugin({
1697
1724
  systemPrompt: {
1698
1725
  en: `### Tools
1699
1726
 
1700
- - \`jdbc_executeQuery\`: Executes a SQL query through a JDBC URL and returns rows. The connector dispatches by URL prefix to the matching native driver, so use the dialect that matches the connection. Use this for schema exploration via \`information_schema\` (or vendor equivalent) and for sampling data. See the SQL Reference below.
1727
+ - \`connector_jdbc_executeQuery\`: Executes a SQL query through a JDBC URL and returns rows. The connector dispatches by URL prefix to the matching native driver, so use the dialect that matches the connection. Use this for schema exploration via \`information_schema\` (or vendor equivalent) and for sampling data. See the SQL Reference below.
1701
1728
 
1702
1729
  ### Business Logic
1703
1730
 
@@ -1729,7 +1756,7 @@ Explicitly **not** supported via this connector \u2014 use the dedicated connect
1729
1756
  The platform's server-logic schema inference may wrap your query as \`SELECT * FROM (<inner>) AS _sq LIMIT N\` (PostgreSQL/MySQL syntax). For PostgreSQL / Redshift / MySQL routes this executes natively. For \`jdbc:sqlserver://\` and \`jdbc:oracle:thin:\` routes, the connector detects this exact wrapper at \`query()\` time, executes \`<inner>\` directly via the dialect-specific driver, and slices the first N rows in JS. You do not need to handle this \u2014 but in queries **you author**, do not use \`LIMIT\` for the SQL Server / Oracle routes; use \`TOP\` / \`FETCH FIRST\` as listed above.`,
1730
1757
  ja: `### \u30C4\u30FC\u30EB
1731
1758
 
1732
- - \`jdbc_executeQuery\`: JDBC URL \u7D4C\u7531\u3067 SQL \u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u3057\u3001\u884C\u30C7\u30FC\u30BF\u3092\u8FD4\u3057\u307E\u3059\u3002\u30B3\u30CD\u30AF\u30BF\u306F URL \u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9\u304B\u3089\u5BFE\u5FDC\u3059\u308B\u30CD\u30A4\u30C6\u30A3\u30D6\u30C9\u30E9\u30A4\u30D0\u3078\u632F\u308A\u5206\u3051\u308B\u305F\u3081\u3001\u63A5\u7D9A\u5148\u306B\u5408\u3063\u305F\u65B9\u8A00\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\`information_schema\`\uFF08\u307E\u305F\u306F\u5404 DB \u306E\u540C\u7B49\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u30D3\u30E5\u30FC\uFF09\u3092\u4F7F\u3063\u305F\u30B9\u30AD\u30FC\u30DE\u63A2\u7D22\u3084\u30C7\u30FC\u30BF\u306E\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u306B\u4F7F\u3044\u307E\u3059\u3002\u4E0B\u90E8\u306E\u300CSQL \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
1759
+ - \`connector_jdbc_executeQuery\`: JDBC URL \u7D4C\u7531\u3067 SQL \u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u3057\u3001\u884C\u30C7\u30FC\u30BF\u3092\u8FD4\u3057\u307E\u3059\u3002\u30B3\u30CD\u30AF\u30BF\u306F URL \u30D7\u30EC\u30D5\u30A3\u30C3\u30AF\u30B9\u304B\u3089\u5BFE\u5FDC\u3059\u308B\u30CD\u30A4\u30C6\u30A3\u30D6\u30C9\u30E9\u30A4\u30D0\u3078\u632F\u308A\u5206\u3051\u308B\u305F\u3081\u3001\u63A5\u7D9A\u5148\u306B\u5408\u3063\u305F\u65B9\u8A00\u3092\u4F7F\u7528\u3057\u3066\u304F\u3060\u3055\u3044\u3002\`information_schema\`\uFF08\u307E\u305F\u306F\u5404 DB \u306E\u540C\u7B49\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u30D3\u30E5\u30FC\uFF09\u3092\u4F7F\u3063\u305F\u30B9\u30AD\u30FC\u30DE\u63A2\u7D22\u3084\u30C7\u30FC\u30BF\u306E\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0\u306B\u4F7F\u3044\u307E\u3059\u3002\u4E0B\u90E8\u306E\u300CSQL \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
1733
1760
 
1734
1761
  ### Business Logic
1735
1762