@squadbase/vite-server 0.1.17-dev.a107052 → 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 +4284 -820
  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 +475 -95
  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 +4302 -818
  78. package/dist/main.js +4302 -818
  79. package/dist/vite-plugin.js +4282 -818
  80. package/package.json +9 -1
@@ -194,7 +194,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
194
194
  /**
195
195
  * Create tools for connections that belong to this connector.
196
196
  * Filters connections by connectorKey internally.
197
- * Returns tools keyed as `${connectorKey}_${toolName}`.
197
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
198
198
  */
199
199
  createTools(connections, config, opts) {
200
200
  const myConnections = connections.filter(
@@ -204,7 +204,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
204
204
  for (const t of Object.values(this.tools)) {
205
205
  const tool = t.createTool(myConnections, config);
206
206
  const originalToModelOutput = tool.toModelOutput;
207
- result[`${this.connectorKey}_${t.name}`] = {
207
+ result[`connector_${this.connectorKey}_${t.name}`] = {
208
208
  ...tool,
209
209
  toModelOutput: async (options) => {
210
210
  if (!originalToModelOutput) {
@@ -489,16 +489,16 @@ var ENTITY_LABELS = {
489
489
  }
490
490
  };
491
491
  var ENTITY_PATHS = {
492
- customers: "/v1/customers?limit=1",
493
- charges: "/v1/charges?limit=1",
494
- invoices: "/v1/invoices?limit=1",
495
- subscriptions: "/v1/subscriptions?limit=1",
496
- products: "/v1/products?limit=1",
497
- prices: "/v1/prices?limit=1",
498
- payouts: "/v1/payouts?limit=1",
499
- refunds: "/v1/refunds?limit=1",
500
- disputes: "/v1/disputes?limit=1",
501
- paymentIntents: "/v1/payment_intents?limit=1"
492
+ customers: "/v1/customers?limit=3",
493
+ charges: "/v1/charges?limit=3",
494
+ invoices: "/v1/invoices?limit=3",
495
+ subscriptions: "/v1/subscriptions?limit=3",
496
+ products: "/v1/products?limit=3",
497
+ prices: "/v1/prices?limit=3",
498
+ payouts: "/v1/payouts?limit=3",
499
+ refunds: "/v1/refunds?limit=3",
500
+ disputes: "/v1/disputes?limit=3",
501
+ paymentIntents: "/v1/payment_intents?limit=3"
502
502
  };
503
503
  var ENTITY_VALUES = Object.keys(ENTITY_PATHS);
504
504
  async function defaultFetchEntity(params, path2) {
@@ -534,6 +534,7 @@ function createStripeSetupFlow(fetchEntity = defaultFetchEntity, labelPrefix = "
534
534
  const sections = [`## ${labelPrefix}`, ""];
535
535
  for (const entity of selected) {
536
536
  let count = "available";
537
+ let sampleRows = [];
537
538
  const res = await fetchEntity(rt.params, ENTITY_PATHS[entity]);
538
539
  if (res.ok) {
539
540
  const data = await res.json();
@@ -542,13 +543,63 @@ function createStripeSetupFlow(fetchEntity = defaultFetchEntity, labelPrefix = "
542
543
  } else if (data.has_more === false) {
543
544
  count = String(data.data?.length ?? 1);
544
545
  } else if (Array.isArray(data.data)) {
545
- count = "1+ (paginated)";
546
+ count = "many (paginated)";
546
547
  }
548
+ sampleRows = (data.data ?? []).slice(0, 3);
547
549
  } else {
548
550
  count = "unavailable";
549
551
  }
550
552
  sections.push(`### ${ENTITY_LABELS[entity].en}`, "");
551
553
  sections.push(`Status: ${count}`, "");
554
+ if ((entity === "charges" || entity === "paymentIntents") && sampleRows.length > 0) {
555
+ sections.push("**Recent sample:**", "");
556
+ sections.push("| ID | Amount | Currency | Status | Created |");
557
+ sections.push("|----|--------|----------|--------|---------|");
558
+ for (const row of sampleRows) {
559
+ const id = String(row["id"] ?? "-").replace(/\|/g, "\\|");
560
+ const amount = typeof row["amount"] === "number" ? (row["amount"] / 100).toFixed(2) : "-";
561
+ const currency = String(row["currency"] ?? "-");
562
+ const status = String(row["status"] ?? "-");
563
+ const created = typeof row["created"] === "number" ? new Date(row["created"] * 1e3).toISOString().slice(0, 10) : "-";
564
+ sections.push(
565
+ `| ${id} | ${amount} | ${currency} | ${status} | ${created} |`
566
+ );
567
+ }
568
+ sections.push("");
569
+ }
570
+ if (entity === "invoices" && sampleRows.length > 0) {
571
+ sections.push("**Recent sample:**", "");
572
+ sections.push("| ID | Total | Currency | Status | Created |");
573
+ sections.push("|----|-------|----------|--------|---------|");
574
+ for (const row of sampleRows) {
575
+ const id = String(row["id"] ?? "-").replace(/\|/g, "\\|");
576
+ const total = typeof row["total"] === "number" ? (row["total"] / 100).toFixed(2) : "-";
577
+ const currency = String(row["currency"] ?? "-");
578
+ const status = String(row["status"] ?? "-");
579
+ const created = typeof row["created"] === "number" ? new Date(row["created"] * 1e3).toISOString().slice(0, 10) : "-";
580
+ sections.push(
581
+ `| ${id} | ${total} | ${currency} | ${status} | ${created} |`
582
+ );
583
+ }
584
+ sections.push("");
585
+ }
586
+ if (entity === "subscriptions" && sampleRows.length > 0) {
587
+ sections.push("**Recent sample:**", "");
588
+ sections.push("| ID | Status | Currency | Interval | Created |");
589
+ sections.push("|----|--------|----------|----------|---------|");
590
+ for (const row of sampleRows) {
591
+ const id = String(row["id"] ?? "-").replace(/\|/g, "\\|");
592
+ const status = String(row["status"] ?? "-");
593
+ const currency = String(row["currency"] ?? "-");
594
+ const items = row["items"];
595
+ const interval = items?.data?.[0]?.plan?.interval ?? "-";
596
+ const created = typeof row["created"] === "number" ? new Date(row["created"] * 1e3).toISOString().slice(0, 10) : "-";
597
+ sections.push(
598
+ `| ${id} | ${status} | ${currency} | ${interval} | ${created} |`
599
+ );
600
+ }
601
+ sections.push("");
602
+ }
552
603
  }
553
604
  return sections.join("\n");
554
605
  }
@@ -571,7 +622,7 @@ var stripeApiKeyConnector = new ConnectorPlugin({
571
622
  systemPrompt: {
572
623
  en: `### Tools
573
624
 
574
- - \`stripe-api-key_request\`: The only way to call the Stripe API. Use it to query charges, customers, invoices, subscriptions, products, prices, payment intents, balances, and more. Authentication is configured automatically using the API Key (Bearer token). Stripe uses cursor-based pagination with \`starting_after\` and \`has_more\`.
625
+ - \`connector_stripe-api-key_request\`: The only way to call the Stripe API. Use it to query charges, customers, invoices, subscriptions, products, prices, payment intents, balances, and more. Authentication is configured automatically using the API Key (Bearer token). Stripe uses cursor-based pagination with \`starting_after\` and \`has_more\`.
575
626
 
576
627
  ### Stripe API Reference
577
628
 
@@ -622,7 +673,7 @@ const data = await res.json();
622
673
  \`\`\``,
623
674
  ja: `### \u30C4\u30FC\u30EB
624
675
 
625
- - \`stripe-api-key_request\`: Stripe API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u8ACB\u6C42\u3001\u9867\u5BA2\u3001\u8ACB\u6C42\u66F8\u3001\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3001\u5546\u54C1\u3001\u4FA1\u683C\u3001\u652F\u6255\u3044\u30A4\u30F3\u30C6\u30F3\u30C8\u3001\u6B8B\u9AD8\u306A\u3069\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002API\u30AD\u30FC\uFF08Bearer\u30C8\u30FC\u30AF\u30F3\uFF09\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002Stripe\u306F \`starting_after\` \u3068 \`has_more\` \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
676
+ - \`connector_stripe-api-key_request\`: Stripe API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u8ACB\u6C42\u3001\u9867\u5BA2\u3001\u8ACB\u6C42\u66F8\u3001\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3001\u5546\u54C1\u3001\u4FA1\u683C\u3001\u652F\u6255\u3044\u30A4\u30F3\u30C6\u30F3\u30C8\u3001\u6B8B\u9AD8\u306A\u3069\u306E\u30AF\u30A8\u30EA\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002API\u30AD\u30FC\uFF08Bearer\u30C8\u30FC\u30AF\u30F3\uFF09\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002Stripe\u306F \`starting_after\` \u3068 \`has_more\` \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
626
677
 
627
678
  ### Stripe API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
628
679
 
@@ -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) {
@@ -387,11 +387,11 @@ var stripeOnboarding = new ConnectorOnboarding({
387
387
  - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
388
388
  },
389
389
  dataOverviewInstructions: {
390
- en: `1. Call stripe-oauth_request with GET /v1/customers?limit=5 to explore customers structure
391
- 2. Call stripe-oauth_request with GET /v1/charges?limit=5 to explore charges structure
390
+ en: `1. Call connector_stripe-oauth_request with GET /v1/customers?limit=5 to explore customers structure
391
+ 2. Call connector_stripe-oauth_request with GET /v1/charges?limit=5 to explore charges structure
392
392
  3. Explore other endpoints (invoices, subscriptions, products) as needed`,
393
- ja: `1. stripe-oauth_request \u3067 GET /v1/customers?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u9867\u5BA2\u306E\u69CB\u9020\u3092\u78BA\u8A8D
394
- 2. stripe-oauth_request \u3067 GET /v1/charges?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u8AB2\u91D1\u306E\u69CB\u9020\u3092\u78BA\u8A8D
393
+ ja: `1. connector_stripe-oauth_request \u3067 GET /v1/customers?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u9867\u5BA2\u306E\u69CB\u9020\u3092\u78BA\u8A8D
394
+ 2. connector_stripe-oauth_request \u3067 GET /v1/charges?limit=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u8AB2\u91D1\u306E\u69CB\u9020\u3092\u78BA\u8A8D
395
395
  3. \u5FC5\u8981\u306B\u5FDC\u3058\u3066\u4ED6\u306E\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\uFF08\u8ACB\u6C42\u66F8\u3001\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3001\u5546\u54C1\uFF09\u3092\u63A2\u7D22`
396
396
  }
397
397
  });
@@ -421,16 +421,16 @@ var ENTITY_LABELS = {
421
421
  }
422
422
  };
423
423
  var ENTITY_PATHS = {
424
- customers: "/v1/customers?limit=1",
425
- charges: "/v1/charges?limit=1",
426
- invoices: "/v1/invoices?limit=1",
427
- subscriptions: "/v1/subscriptions?limit=1",
428
- products: "/v1/products?limit=1",
429
- prices: "/v1/prices?limit=1",
430
- payouts: "/v1/payouts?limit=1",
431
- refunds: "/v1/refunds?limit=1",
432
- disputes: "/v1/disputes?limit=1",
433
- paymentIntents: "/v1/payment_intents?limit=1"
424
+ customers: "/v1/customers?limit=3",
425
+ charges: "/v1/charges?limit=3",
426
+ invoices: "/v1/invoices?limit=3",
427
+ subscriptions: "/v1/subscriptions?limit=3",
428
+ products: "/v1/products?limit=3",
429
+ prices: "/v1/prices?limit=3",
430
+ payouts: "/v1/payouts?limit=3",
431
+ refunds: "/v1/refunds?limit=3",
432
+ disputes: "/v1/disputes?limit=3",
433
+ paymentIntents: "/v1/payment_intents?limit=3"
434
434
  };
435
435
  var ENTITY_VALUES = Object.keys(ENTITY_PATHS);
436
436
  var stripeOauthSetupFlow = {
@@ -462,6 +462,7 @@ var stripeOauthSetupFlow = {
462
462
  const sections = ["## Stripe", ""];
463
463
  for (const entity of selected) {
464
464
  let count = "available";
465
+ let sampleRows = [];
465
466
  const res = await rt.config.proxyFetch(
466
467
  `${BASE_URL3}${ENTITY_PATHS[entity]}`,
467
468
  { method: "GET" }
@@ -473,13 +474,63 @@ var stripeOauthSetupFlow = {
473
474
  } else if (data.has_more === false) {
474
475
  count = String(data.data?.length ?? 1);
475
476
  } else if (Array.isArray(data.data)) {
476
- count = "1+ (paginated)";
477
+ count = "many (paginated)";
477
478
  }
479
+ sampleRows = (data.data ?? []).slice(0, 3);
478
480
  } else {
479
481
  count = "unavailable";
480
482
  }
481
483
  sections.push(`### ${ENTITY_LABELS[entity].en}`, "");
482
484
  sections.push(`Status: ${count}`, "");
485
+ if ((entity === "charges" || entity === "paymentIntents") && sampleRows.length > 0) {
486
+ sections.push("**Recent sample:**", "");
487
+ sections.push("| ID | Amount | Currency | Status | Created |");
488
+ sections.push("|----|--------|----------|--------|---------|");
489
+ for (const row of sampleRows) {
490
+ const id = String(row["id"] ?? "-").replace(/\|/g, "\\|");
491
+ const amount = typeof row["amount"] === "number" ? (row["amount"] / 100).toFixed(2) : "-";
492
+ const currency = String(row["currency"] ?? "-");
493
+ const status = String(row["status"] ?? "-");
494
+ const created = typeof row["created"] === "number" ? new Date(row["created"] * 1e3).toISOString().slice(0, 10) : "-";
495
+ sections.push(
496
+ `| ${id} | ${amount} | ${currency} | ${status} | ${created} |`
497
+ );
498
+ }
499
+ sections.push("");
500
+ }
501
+ if (entity === "invoices" && sampleRows.length > 0) {
502
+ sections.push("**Recent sample:**", "");
503
+ sections.push("| ID | Total | Currency | Status | Created |");
504
+ sections.push("|----|-------|----------|--------|---------|");
505
+ for (const row of sampleRows) {
506
+ const id = String(row["id"] ?? "-").replace(/\|/g, "\\|");
507
+ const total = typeof row["total"] === "number" ? (row["total"] / 100).toFixed(2) : "-";
508
+ const currency = String(row["currency"] ?? "-");
509
+ const status = String(row["status"] ?? "-");
510
+ const created = typeof row["created"] === "number" ? new Date(row["created"] * 1e3).toISOString().slice(0, 10) : "-";
511
+ sections.push(
512
+ `| ${id} | ${total} | ${currency} | ${status} | ${created} |`
513
+ );
514
+ }
515
+ sections.push("");
516
+ }
517
+ if (entity === "subscriptions" && sampleRows.length > 0) {
518
+ sections.push("**Recent sample:**", "");
519
+ sections.push("| ID | Status | Currency | Interval | Created |");
520
+ sections.push("|----|--------|----------|----------|---------|");
521
+ for (const row of sampleRows) {
522
+ const id = String(row["id"] ?? "-").replace(/\|/g, "\\|");
523
+ const status = String(row["status"] ?? "-");
524
+ const currency = String(row["currency"] ?? "-");
525
+ const items = row["items"];
526
+ const interval = items?.data?.[0]?.plan?.interval ?? "-";
527
+ const created = typeof row["created"] === "number" ? new Date(row["created"] * 1e3).toISOString().slice(0, 10) : "-";
528
+ sections.push(
529
+ `| ${id} | ${status} | ${currency} | ${interval} | ${created} |`
530
+ );
531
+ }
532
+ sections.push("");
533
+ }
483
534
  }
484
535
  return sections.join("\n");
485
536
  }
@@ -509,7 +560,7 @@ var stripeOauthConnector = new ConnectorPlugin({
509
560
  systemPrompt: {
510
561
  en: `### Tools
511
562
 
512
- - \`stripe-oauth_request\`: The only way to call the Stripe API. Use it to query charges, customers, invoices, subscriptions, products, prices, payment intents, balances, and more. Authentication is configured automatically via OAuth. Stripe uses cursor-based pagination with \`starting_after\` and \`has_more\`.
563
+ - \`connector_stripe-oauth_request\`: The only way to call the Stripe API. Use it to query charges, customers, invoices, subscriptions, products, prices, payment intents, balances, and more. Authentication is configured automatically via OAuth. Stripe uses cursor-based pagination with \`starting_after\` and \`has_more\`.
513
564
 
514
565
  ### Stripe API Reference
515
566
 
@@ -558,7 +609,7 @@ const data = await res.json();
558
609
  \`\`\``,
559
610
  ja: `### \u30C4\u30FC\u30EB
560
611
 
561
- - \`stripe-oauth_request\`: Stripe API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u8ACB\u6C42\u3001\u9867\u5BA2\u3001\u8ACB\u6C42\u66F8\u3001\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3001\u5546\u54C1\u3001\u4FA1\u683C\u3001\u652F\u6255\u3044\u30A4\u30F3\u30C6\u30F3\u30C8\u3001\u6B8B\u9AD8\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\u3002Stripe\u306F \`starting_after\` \u3068 \`has_more\` \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
612
+ - \`connector_stripe-oauth_request\`: Stripe API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u8ACB\u6C42\u3001\u9867\u5BA2\u3001\u8ACB\u6C42\u66F8\u3001\u30B5\u30D6\u30B9\u30AF\u30EA\u30D7\u30B7\u30E7\u30F3\u3001\u5546\u54C1\u3001\u4FA1\u683C\u3001\u652F\u6255\u3044\u30A4\u30F3\u30C6\u30F3\u30C8\u3001\u6B8B\u9AD8\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\u3002Stripe\u306F \`starting_after\` \u3068 \`has_more\` \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
562
613
 
563
614
  ### Stripe API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
564
615
 
@@ -208,7 +208,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
208
208
  /**
209
209
  * Create tools for connections that belong to this connector.
210
210
  * Filters connections by connectorKey internally.
211
- * Returns tools keyed as `${connectorKey}_${toolName}`.
211
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
212
212
  */
213
213
  createTools(connections, config, opts) {
214
214
  const myConnections = connections.filter(
@@ -218,7 +218,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
218
218
  for (const t of Object.values(this.tools)) {
219
219
  const tool = t.createTool(myConnections, config);
220
220
  const originalToModelOutput = tool.toModelOutput;
221
- result[`${this.connectorKey}_${t.name}`] = {
221
+ result[`connector_${this.connectorKey}_${t.name}`] = {
222
222
  ...tool,
223
223
  toModelOutput: async (options) => {
224
224
  if (!originalToModelOutput) {
@@ -469,6 +469,21 @@ var supabaseSetupFlow = {
469
469
  fetchAll: () => fetchTableNames(rt.params, schema),
470
470
  limit: SUPABASE_SETUP_MAX_TABLES
471
471
  });
472
+ let rowCounts = /* @__PURE__ */ new Map();
473
+ try {
474
+ const countRows = await runQuery(
475
+ rt.params,
476
+ `SELECT relname, n_live_tup FROM pg_stat_user_tables WHERE schemaname = $1`,
477
+ [schema]
478
+ );
479
+ rowCounts = new Map(
480
+ countRows.map((r) => [
481
+ String(r["relname"] ?? ""),
482
+ Number(r["n_live_tup"] ?? 0)
483
+ ])
484
+ );
485
+ } catch {
486
+ }
472
487
  const sections = [
473
488
  "## Supabase",
474
489
  "",
@@ -484,7 +499,9 @@ var supabaseSetupFlow = {
484
499
  ORDER BY ordinal_position`,
485
500
  [schema, table]
486
501
  );
487
- sections.push(`#### Table: ${table}`, "");
502
+ const rowCount = rowCounts.get(table);
503
+ const heading = typeof rowCount === "number" ? `#### Table: ${table} (~${rowCount.toLocaleString()} rows)` : `#### Table: ${table}`;
504
+ sections.push(heading, "");
488
505
  sections.push("| Column | Type | Nullable | Default |");
489
506
  sections.push("|--------|------|----------|---------|");
490
507
  for (const c of cols) {
@@ -520,6 +537,9 @@ var outputSchema = z.discriminatedUnion("success", [
520
537
  z.object({
521
538
  success: z.literal(true),
522
539
  rowCount: z.number(),
540
+ rowsAffected: z.number().optional().describe(
541
+ "Affected rows for INSERT/UPDATE/DELETE; undefined for SELECT"
542
+ ),
523
543
  truncated: z.boolean(),
524
544
  rows: z.array(z.record(z.string(), z.unknown()))
525
545
  }),
@@ -533,7 +553,8 @@ var executeQueryTool = new ConnectorTool({
533
553
  description: `Execute SQL against a Supabase Postgres database. Returns up to ${MAX_ROWS} rows.
534
554
  Use for: schema exploration (information_schema), data sampling, and analytical queries against Supabase tables.
535
555
  User tables live in the \`public\` schema by default; Supabase-managed metadata lives in \`auth\` and \`storage\`.
536
- Avoid loading large amounts of data; always include LIMIT in queries.`,
556
+ Avoid loading large amounts of data; always include LIMIT in queries.
557
+ 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. Use RETURNING to get written rows back in \`rows\`.`,
537
558
  inputSchema,
538
559
  outputSchema,
539
560
  async execute({ connectionId, sql }, connections) {
@@ -561,9 +582,13 @@ Avoid loading large amounts of data; always include LIMIT in queries.`,
561
582
  const result = await pool.query(sql);
562
583
  const rows = result.rows;
563
584
  const truncated = rows.length > MAX_ROWS;
585
+ const isDml = ["INSERT", "UPDATE", "DELETE", "MERGE"].includes(
586
+ result.command
587
+ );
564
588
  return {
565
589
  success: true,
566
590
  rowCount: Math.min(rows.length, MAX_ROWS),
591
+ rowsAffected: isDml ? result.rowCount ?? 0 : void 0,
567
592
  truncated,
568
593
  rows: rows.slice(0, MAX_ROWS)
569
594
  };
@@ -595,7 +620,7 @@ var supabaseConnector = new ConnectorPlugin({
595
620
  systemPrompt: {
596
621
  en: `### Tools
597
622
 
598
- - \`supabase_executeQuery\`: Executes a PostgreSQL query against the Supabase project's database and returns rows. Use this for schema exploration via \`information_schema.tables\`/\`columns\` and for sampling data. See the SQL Reference below for syntax notes and Supabase-specific schemas.
623
+ - \`connector_supabase_executeQuery\`: Executes a PostgreSQL query against the Supabase project's database and returns rows. Use this for schema exploration via \`information_schema.tables\`/\`columns\` and for sampling data. See the SQL Reference below for syntax notes and Supabase-specific schemas.
599
624
 
600
625
  ### Business Logic
601
626
 
@@ -612,7 +637,7 @@ The business logic type for this connector is "sql".
612
637
  - Always include LIMIT in queries`,
613
638
  ja: `### \u30C4\u30FC\u30EB
614
639
 
615
- - \`supabase_executeQuery\`: Supabase\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E Postgres \u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u5BFE\u3057\u3066\u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u3057\u3001\u884C\u30C7\u30FC\u30BF\u3092\u8FD4\u3057\u307E\u3059\u3002\`information_schema.tables\`/\`columns\` \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\u69CB\u6587\u306E\u6CE8\u610F\u70B9\u3068 Supabase \u56FA\u6709\u306E\u30B9\u30AD\u30FC\u30DE\u306F\u4E0B\u90E8\u306E\u300CSQL \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
640
+ - \`connector_supabase_executeQuery\`: Supabase\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u306E Postgres \u30C7\u30FC\u30BF\u30D9\u30FC\u30B9\u306B\u5BFE\u3057\u3066\u30AF\u30A8\u30EA\u3092\u5B9F\u884C\u3057\u3001\u884C\u30C7\u30FC\u30BF\u3092\u8FD4\u3057\u307E\u3059\u3002\`information_schema.tables\`/\`columns\` \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\u69CB\u6587\u306E\u6CE8\u610F\u70B9\u3068 Supabase \u56FA\u6709\u306E\u30B9\u30AD\u30FC\u30DE\u306F\u4E0B\u90E8\u306E\u300CSQL \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
616
641
 
617
642
  ### Business Logic
618
643
 
@@ -305,7 +305,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
305
305
  /**
306
306
  * Create tools for connections that belong to this connector.
307
307
  * Filters connections by connectorKey internally.
308
- * Returns tools keyed as `${connectorKey}_${toolName}`.
308
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
309
309
  */
310
310
  createTools(connections, config, opts) {
311
311
  const myConnections = connections.filter(
@@ -315,7 +315,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
315
315
  for (const t of Object.values(this.tools)) {
316
316
  const tool = t.createTool(myConnections, config);
317
317
  const originalToModelOutput = tool.toModelOutput;
318
- result[`${this.connectorKey}_${t.name}`] = {
318
+ result[`connector_${this.connectorKey}_${t.name}`] = {
319
319
  ...tool,
320
320
  toModelOutput: async (options) => {
321
321
  if (!originalToModelOutput) {
@@ -447,7 +447,7 @@ var tableauOnboarding = new ConnectorOnboarding({
447
447
  connectionSetupInstructions: {
448
448
  en: `Follow these steps to verify the Tableau PAT connection.
449
449
 
450
- 1. Call \`tableau_request\` with \`method: "GET"\` and \`path: "/sites/{siteId}/projects?pageSize=5"\` to list a few projects on the signed-in site
450
+ 1. Call \`connector_tableau_request\` with \`method: "GET"\` and \`path: "/sites/{siteId}/projects?pageSize=5"\` to list a few projects on the signed-in site
451
451
  2. If the call fails with HTTP 401, ask the user to confirm the PAT name/secret and that the Site Content URL matches the site where the PAT was issued (Tableau Cloud sites are case-sensitive)
452
452
 
453
453
  #### Constraints
@@ -455,7 +455,7 @@ var tableauOnboarding = new ConnectorOnboarding({
455
455
  - The literal placeholder \`{siteId}\` in the path is automatically replaced with the session's site ID \u2014 do NOT hardcode the ID`,
456
456
  ja: `Tableau PAT \u30B3\u30CD\u30AF\u30B7\u30E7\u30F3\u306E\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u306F\u4EE5\u4E0B\u306E\u624B\u9806\u3067\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002
457
457
 
458
- 1. \`tableau_request\` \u3092 \`method: "GET"\`\u3001\`path: "/sites/{siteId}/projects?pageSize=5"\` \u3067\u547C\u3073\u51FA\u3057\u3001\u30B5\u30A4\u30F3\u30A4\u30F3\u5148\u30B5\u30A4\u30C8\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u3044\u304F\u3064\u304B\u53D6\u5F97\u3059\u308B
458
+ 1. \`connector_tableau_request\` \u3092 \`method: "GET"\`\u3001\`path: "/sites/{siteId}/projects?pageSize=5"\` \u3067\u547C\u3073\u51FA\u3057\u3001\u30B5\u30A4\u30F3\u30A4\u30F3\u5148\u30B5\u30A4\u30C8\u306E\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3092\u3044\u304F\u3064\u304B\u53D6\u5F97\u3059\u308B
459
459
  2. HTTP 401 \u3067\u5931\u6557\u3057\u305F\u5834\u5408\u306F\u3001PAT \u540D/\u30B7\u30FC\u30AF\u30EC\u30C3\u30C8\u304A\u3088\u3073 Site Content URL \u304C PAT \u767A\u884C\u30B5\u30A4\u30C8\u3068\u4E00\u81F4\u3057\u3066\u3044\u308B\u304B\u3092\u30E6\u30FC\u30B6\u30FC\u306B\u78BA\u8A8D\u3059\u308B\u3088\u3046\u4F1D\u3048\u308B\uFF08Tableau Cloud \u306E\u30B5\u30A4\u30C8\u540D\u306F\u5927\u6587\u5B57\u5C0F\u6587\u5B57\u3092\u533A\u5225\uFF09
460
460
 
461
461
  #### \u5236\u7D04
@@ -463,14 +463,14 @@ var tableauOnboarding = new ConnectorOnboarding({
463
463
  - \u30D1\u30B9\u5185\u306E\u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC \`{siteId}\` \u306F\u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u30B5\u30A4\u30C8 ID \u3067\u81EA\u52D5\u7F6E\u63DB\u3055\u308C\u307E\u3059 \u2014 ID \u3092\u30CF\u30FC\u30C9\u30B3\u30FC\u30C9\u3057\u306A\u3044\u3053\u3068`
464
464
  },
465
465
  dataOverviewInstructions: {
466
- en: `1. Call tableau_request with GET /sites/{siteId}/projects to list projects
467
- 2. Call tableau_request with GET /sites/{siteId}/workbooks?pageSize=20 to list workbooks
468
- 3. For a target workbook, call tableau_request with GET /sites/{siteId}/workbooks/{workbookId}/views to list its views
469
- 4. Call tableau_request with GET /sites/{siteId}/datasources?pageSize=20 to list published data sources`,
470
- ja: `1. tableau_request \u3067 GET /sites/{siteId}/projects \u3092\u547C\u3073\u51FA\u3057\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
471
- 2. tableau_request \u3067 GET /sites/{siteId}/workbooks?pageSize=20 \u3092\u547C\u3073\u51FA\u3057\u3001\u30EF\u30FC\u30AF\u30D6\u30C3\u30AF\u4E00\u89A7\u3092\u53D6\u5F97
472
- 3. \u5BFE\u8C61\u30EF\u30FC\u30AF\u30D6\u30C3\u30AF\u306B\u3064\u3044\u3066 tableau_request \u3067 GET /sites/{siteId}/workbooks/{workbookId}/views \u3092\u547C\u3073\u51FA\u3057\u3001\u30D3\u30E5\u30FC\u4E00\u89A7\u3092\u53D6\u5F97
473
- 4. tableau_request \u3067 GET /sites/{siteId}/datasources?pageSize=20 \u3092\u547C\u3073\u51FA\u3057\u3001\u516C\u958B\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97`
466
+ en: `1. Call connector_tableau_request with GET /sites/{siteId}/projects to list projects
467
+ 2. Call connector_tableau_request with GET /sites/{siteId}/workbooks?pageSize=20 to list workbooks
468
+ 3. For a target workbook, call connector_tableau_request with GET /sites/{siteId}/workbooks/{workbookId}/views to list its views
469
+ 4. Call connector_tableau_request with GET /sites/{siteId}/datasources?pageSize=20 to list published data sources`,
470
+ ja: `1. connector_tableau_request \u3067 GET /sites/{siteId}/projects \u3092\u547C\u3073\u51FA\u3057\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
471
+ 2. connector_tableau_request \u3067 GET /sites/{siteId}/workbooks?pageSize=20 \u3092\u547C\u3073\u51FA\u3057\u3001\u30EF\u30FC\u30AF\u30D6\u30C3\u30AF\u4E00\u89A7\u3092\u53D6\u5F97
472
+ 3. \u5BFE\u8C61\u30EF\u30FC\u30AF\u30D6\u30C3\u30AF\u306B\u3064\u3044\u3066 connector_tableau_request \u3067 GET /sites/{siteId}/workbooks/{workbookId}/views \u3092\u547C\u3073\u51FA\u3057\u3001\u30D3\u30E5\u30FC\u4E00\u89A7\u3092\u53D6\u5F97
473
+ 4. connector_tableau_request \u3067 GET /sites/{siteId}/datasources?pageSize=20 \u3092\u547C\u3073\u51FA\u3057\u3001\u516C\u958B\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97`
474
474
  }
475
475
  });
476
476
 
@@ -917,13 +917,13 @@ var tableauConnector = new ConnectorPlugin({
917
917
  description: "Connect to Tableau Cloud or Tableau Server via a Personal Access Token (PAT). Use it to enumerate projects, workbooks, views, and data sources, and to pull view data.",
918
918
  iconUrl: "https://images.ctfassets.net/9ncizv60xc5y/3ejrZvfw7zCDa3FPbUNQx9/d810e117b3a86c45dd96205453bf67a0/tableau-icon.svg",
919
919
  parameters,
920
- releaseFlag: { dev1: true, dev2: false, prod: false },
920
+ releaseFlag: { dev1: true, dev2: true, prod: true },
921
921
  categories: ["bi"],
922
922
  onboarding: tableauOnboarding,
923
923
  systemPrompt: {
924
924
  en: `### Tools
925
925
 
926
- - \`tableau_request\`: The only way to call the Tableau REST API. Use it for projects, workbooks, views, data sources, users, and permissions. The \`X-Tableau-Auth\` token is issued and managed centrally by the Squadbase backend so concurrent processes (chat & deployed app) share a single PAT sign-in. Use the literal \`{siteId}\` placeholder in the path \u2014 it is replaced with the session's site ID automatically.
926
+ - \`connector_tableau_request\`: The only way to call the Tableau REST API. Use it for projects, workbooks, views, data sources, users, and permissions. The \`X-Tableau-Auth\` token is issued and managed centrally by the Squadbase backend so concurrent processes (chat & deployed app) share a single PAT sign-in. Use the literal \`{siteId}\` placeholder in the path \u2014 it is replaced with the session's site ID automatically.
927
927
 
928
928
  ### Business Logic
929
929
 
@@ -980,7 +980,7 @@ export default async function handler(c: Context) {
980
980
  - Combine: \`filter=ownerName:eq:alice,tags:in:[finance]\``,
981
981
  ja: `### \u30C4\u30FC\u30EB
982
982
 
983
- - \`tableau_request\`: Tableau REST API \u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3001\u30EF\u30FC\u30AF\u30D6\u30C3\u30AF\u3001\u30D3\u30E5\u30FC\u3001\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u3001\u30E6\u30FC\u30B6\u30FC\u3001\u6A29\u9650\u306A\u3069\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\`X-Tableau-Auth\` \u30C8\u30FC\u30AF\u30F3\u306F Squadbase \u30D0\u30C3\u30AF\u30A8\u30F3\u30C9\u3067\u4E00\u5143\u7BA1\u7406\u3055\u308C\u3001\u8907\u6570\u30D7\u30ED\u30BB\u30B9 (\u30C1\u30E3\u30C3\u30C8\u30FB\u30C7\u30D7\u30ED\u30A4\u6E08\u307F\u30A2\u30D7\u30EA) \u3067\u540C\u3058 PAT \u30B5\u30A4\u30F3\u30A4\u30F3\u3092\u5171\u6709\u3057\u307E\u3059\u3002\u30D1\u30B9\u5185\u306B\u306F \`{siteId}\` \u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044 \u2014 \u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u30B5\u30A4\u30C8 ID \u3067\u81EA\u52D5\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002
983
+ - \`connector_tableau_request\`: Tableau REST API \u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3001\u30EF\u30FC\u30AF\u30D6\u30C3\u30AF\u3001\u30D3\u30E5\u30FC\u3001\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u3001\u30E6\u30FC\u30B6\u30FC\u3001\u6A29\u9650\u306A\u3069\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\`X-Tableau-Auth\` \u30C8\u30FC\u30AF\u30F3\u306F Squadbase \u30D0\u30C3\u30AF\u30A8\u30F3\u30C9\u3067\u4E00\u5143\u7BA1\u7406\u3055\u308C\u3001\u8907\u6570\u30D7\u30ED\u30BB\u30B9 (\u30C1\u30E3\u30C3\u30C8\u30FB\u30C7\u30D7\u30ED\u30A4\u6E08\u307F\u30A2\u30D7\u30EA) \u3067\u540C\u3058 PAT \u30B5\u30A4\u30F3\u30A4\u30F3\u3092\u5171\u6709\u3057\u307E\u3059\u3002\u30D1\u30B9\u5185\u306B\u306F \`{siteId}\` \u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044 \u2014 \u30BB\u30C3\u30B7\u30E7\u30F3\u306E\u30B5\u30A4\u30C8 ID \u3067\u81EA\u52D5\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002
984
984
 
985
985
  ### Business Logic
986
986
 
@@ -171,7 +171,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
171
171
  /**
172
172
  * Create tools for connections that belong to this connector.
173
173
  * Filters connections by connectorKey internally.
174
- * Returns tools keyed as `${connectorKey}_${toolName}`.
174
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
175
175
  */
176
176
  createTools(connections, config, opts) {
177
177
  const myConnections = connections.filter(
@@ -181,7 +181,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
181
181
  for (const t of Object.values(this.tools)) {
182
182
  const tool = t.createTool(myConnections, config);
183
183
  const originalToModelOutput = tool.toModelOutput;
184
- result[`${this.connectorKey}_${t.name}`] = {
184
+ result[`connector_${this.connectorKey}_${t.name}`] = {
185
185
  ...tool,
186
186
  toModelOutput: async (options) => {
187
187
  if (!originalToModelOutput) {
@@ -468,12 +468,12 @@ var tiktokAdsOnboarding = new ConnectorOnboarding({
468
468
  - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
469
469
  },
470
470
  dataOverviewInstructions: {
471
- en: `1. Call tiktok-ads_request with GET campaign/get/ to explore campaign data
472
- 2. Call tiktok-ads_request with GET adgroup/get/ to explore ad group data
473
- 3. Call tiktok-ads_request with GET report/integrated/get/ with metrics=["spend","impressions","clicks","ctr","cpm","cpc"]&dimensions=["campaign_id"]&data_level=AUCTION_CAMPAIGN&start_date=YYYY-MM-DD&end_date=YYYY-MM-DD to check recent performance`,
474
- ja: `1. tiktok-ads_request \u3067 GET campaign/get/ \u3092\u547C\u3073\u51FA\u3057\u3066\u30AD\u30E3\u30F3\u30DA\u30FC\u30F3\u30C7\u30FC\u30BF\u3092\u63A2\u7D22
475
- 2. tiktok-ads_request \u3067 GET adgroup/get/ \u3092\u547C\u3073\u51FA\u3057\u3066\u5E83\u544A\u30B0\u30EB\u30FC\u30D7\u30C7\u30FC\u30BF\u3092\u63A2\u7D22
476
- 3. tiktok-ads_request \u3067 GET report/integrated/get/ \u306B metrics=["spend","impressions","clicks","ctr","cpm","cpc"]&dimensions=["campaign_id"]&data_level=AUCTION_CAMPAIGN&start_date=YYYY-MM-DD&end_date=YYYY-MM-DD \u3092\u6307\u5B9A\u3057\u3066\u76F4\u8FD1\u306E\u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u3092\u78BA\u8A8D`
471
+ en: `1. Call connector_tiktok-ads_request with GET campaign/get/ to explore campaign data
472
+ 2. Call connector_tiktok-ads_request with GET adgroup/get/ to explore ad group data
473
+ 3. Call connector_tiktok-ads_request with GET report/integrated/get/ with metrics=["spend","impressions","clicks","ctr","cpm","cpc"]&dimensions=["campaign_id"]&data_level=AUCTION_CAMPAIGN&start_date=YYYY-MM-DD&end_date=YYYY-MM-DD to check recent performance`,
474
+ ja: `1. connector_tiktok-ads_request \u3067 GET campaign/get/ \u3092\u547C\u3073\u51FA\u3057\u3066\u30AD\u30E3\u30F3\u30DA\u30FC\u30F3\u30C7\u30FC\u30BF\u3092\u63A2\u7D22
475
+ 2. connector_tiktok-ads_request \u3067 GET adgroup/get/ \u3092\u547C\u3073\u51FA\u3057\u3066\u5E83\u544A\u30B0\u30EB\u30FC\u30D7\u30C7\u30FC\u30BF\u3092\u63A2\u7D22
476
+ 3. connector_tiktok-ads_request \u3067 GET report/integrated/get/ \u306B metrics=["spend","impressions","clicks","ctr","cpm","cpc"]&dimensions=["campaign_id"]&data_level=AUCTION_CAMPAIGN&start_date=YYYY-MM-DD&end_date=YYYY-MM-DD \u3092\u6307\u5B9A\u3057\u3066\u76F4\u8FD1\u306E\u30D1\u30D5\u30A9\u30FC\u30DE\u30F3\u30B9\u3092\u78BA\u8A8D`
477
477
  }
478
478
  });
479
479
 
@@ -513,6 +513,19 @@ async function listAdvertisers(proxyFetch) {
513
513
  }
514
514
  return data.data?.list ?? [];
515
515
  }
516
+ async function fetchCampaignCount(proxyFetch, advertiserId) {
517
+ try {
518
+ const url = `${BASE_URL3}/campaign/get/?advertiser_id=${encodeURIComponent(advertiserId)}&page_size=1`;
519
+ const res = await proxyFetch(url, { method: "GET" });
520
+ if (!res.ok) return null;
521
+ const data = await res.json();
522
+ if (data.code !== void 0 && data.code !== 0) return null;
523
+ const total = data.data?.page_info?.total_number;
524
+ return typeof total === "number" ? total : null;
525
+ } catch {
526
+ return null;
527
+ }
528
+ }
516
529
  async function fetchAdvertiserInfo(proxyFetch, advertiserId) {
517
530
  const advertiserIdsParam = encodeURIComponent(
518
531
  JSON.stringify([advertiserId])
@@ -577,16 +590,24 @@ var tiktokAdsSetupFlow = {
577
590
  sections.push("_No advertisers selected._", "");
578
591
  return sections.join("\n");
579
592
  }
580
- sections.push("| Advertiser ID | Name | Currency | Status | Time Zone |");
581
- sections.push("|---------------|------|----------|--------|-----------|");
593
+ sections.push(
594
+ "| Advertiser ID | Name | Currency | Status | Time Zone | Campaigns |"
595
+ );
596
+ sections.push(
597
+ "|---------------|------|----------|--------|-----------|-----------|"
598
+ );
582
599
  for (const id of targetIds) {
583
- const info = await fetchAdvertiserInfo(rt.config.proxyFetch, id);
600
+ const [info, campaignCount] = await Promise.all([
601
+ fetchAdvertiserInfo(rt.config.proxyFetch, id),
602
+ fetchCampaignCount(rt.config.proxyFetch, id)
603
+ ]);
584
604
  const name = (info.name ?? "-").replace(/\|/g, "\\|");
585
605
  const currency = info.currency ?? "-";
586
606
  const status = info.status ?? "-";
587
607
  const timeZone = info.display_timezone ?? "-";
608
+ const campaigns = campaignCount == null ? "-" : String(campaignCount);
588
609
  sections.push(
589
- `| ${id} | ${name} | ${currency} | ${status} | ${timeZone} |`
610
+ `| ${id} | ${name} | ${currency} | ${status} | ${timeZone} | ${campaigns} |`
590
611
  );
591
612
  }
592
613
  sections.push("");
@@ -759,8 +780,8 @@ var tiktokAdsConnector = new ConnectorPlugin({
759
780
  systemPrompt: {
760
781
  en: `### Tools
761
782
 
762
- - \`tiktok-ads_request\`: Send authenticated requests to the TikTok Marketing API v1.3. Authentication is handled automatically via OAuth proxy. The advertiser_id is automatically injected if configured.
763
- - \`tiktok-ads_listAdvertisers\`: List accessible TikTok Ads advertiser accounts. Use this during setup to discover available accounts.
783
+ - \`connector_tiktok-ads_request\`: Send authenticated requests to the TikTok Marketing API v1.3. Authentication is handled automatically via OAuth proxy. The advertiser_id is automatically injected if configured.
784
+ - \`connector_tiktok-ads_listAdvertisers\`: List accessible TikTok Ads advertiser accounts. Use this during setup to discover available accounts.
764
785
 
765
786
  ### TikTok Marketing API Reference
766
787
 
@@ -825,8 +846,8 @@ const data = await res.json();
825
846
  \`\`\``,
826
847
  ja: `### \u30C4\u30FC\u30EB
827
848
 
828
- - \`tiktok-ads_request\`: TikTok Marketing API v1.3\u3078\u8A8D\u8A3C\u6E08\u307F\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u9001\u4FE1\u3057\u307E\u3059\u3002\u8A8D\u8A3C\u306FOAuth\u30D7\u30ED\u30AD\u30B7\u7D4C\u7531\u3067\u81EA\u52D5\u7684\u306B\u51E6\u7406\u3055\u308C\u307E\u3059\u3002advertiser_id\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u306F\u81EA\u52D5\u7684\u306B\u6CE8\u5165\u3055\u308C\u307E\u3059\u3002
829
- - \`tiktok-ads_listAdvertisers\`: \u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306ATikTok Ads\u5E83\u544A\u4E3B\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u4E00\u89A7\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306B\u5229\u7528\u53EF\u80FD\u306A\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u78BA\u8A8D\u3059\u308B\u305F\u3081\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002
849
+ - \`connector_tiktok-ads_request\`: TikTok Marketing API v1.3\u3078\u8A8D\u8A3C\u6E08\u307F\u30EA\u30AF\u30A8\u30B9\u30C8\u3092\u9001\u4FE1\u3057\u307E\u3059\u3002\u8A8D\u8A3C\u306FOAuth\u30D7\u30ED\u30AD\u30B7\u7D4C\u7531\u3067\u81EA\u52D5\u7684\u306B\u51E6\u7406\u3055\u308C\u307E\u3059\u3002advertiser_id\u304C\u8A2D\u5B9A\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u306F\u81EA\u52D5\u7684\u306B\u6CE8\u5165\u3055\u308C\u307E\u3059\u3002
850
+ - \`connector_tiktok-ads_listAdvertisers\`: \u30A2\u30AF\u30BB\u30B9\u53EF\u80FD\u306ATikTok Ads\u5E83\u544A\u4E3B\u30A2\u30AB\u30A6\u30F3\u30C8\u306E\u4E00\u89A7\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306B\u5229\u7528\u53EF\u80FD\u306A\u30A2\u30AB\u30A6\u30F3\u30C8\u3092\u78BA\u8A8D\u3059\u308B\u305F\u3081\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002
830
851
 
831
852
  ### TikTok Marketing API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
832
853