@squadbase/vite-server 0.1.17-dev.24af54e → 0.1.17-dev.423ee34

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 (77) hide show
  1. package/dist/cli/index.js +4873 -1073
  2. package/dist/connectors/airtable-oauth.js +78 -11
  3. package/dist/connectors/airtable.js +74 -11
  4. package/dist/connectors/amplitude.js +38 -11
  5. package/dist/connectors/anthropic.js +4 -2
  6. package/dist/connectors/asana.js +67 -13
  7. package/dist/connectors/attio.js +60 -16
  8. package/dist/connectors/aws-billing.js +38 -11
  9. package/dist/connectors/azure-sql.js +64 -13
  10. package/dist/connectors/backlog-api-key.js +70 -18
  11. package/dist/connectors/clickup.js +80 -13
  12. package/dist/connectors/cosmosdb.js +42 -15
  13. package/dist/connectors/customerio.js +39 -12
  14. package/dist/connectors/dbt.js +716 -28
  15. package/dist/connectors/freshdesk.js +112 -11
  16. package/dist/connectors/freshsales.js +38 -11
  17. package/dist/connectors/freshservice.js +38 -11
  18. package/dist/connectors/gamma.js +47 -20
  19. package/dist/connectors/gemini.js +4 -2
  20. package/dist/connectors/github.js +42 -15
  21. package/dist/connectors/gmail-oauth.js +38 -13
  22. package/dist/connectors/gmail.js +34 -7
  23. package/dist/connectors/google-ads.js +38 -11
  24. package/dist/connectors/google-analytics-oauth.js +182 -28
  25. package/dist/connectors/google-analytics.js +653 -104
  26. package/dist/connectors/google-audit-log.js +34 -7
  27. package/dist/connectors/google-calendar-oauth.js +91 -18
  28. package/dist/connectors/google-calendar.js +91 -14
  29. package/dist/connectors/google-docs.js +38 -13
  30. package/dist/connectors/google-drive.js +60 -13
  31. package/dist/connectors/google-search-console-oauth.js +156 -20
  32. package/dist/connectors/google-sheets.js +36 -9
  33. package/dist/connectors/google-slides.js +38 -13
  34. package/dist/connectors/grafana.js +75 -13
  35. package/dist/connectors/hubspot-oauth.js +69 -12
  36. package/dist/connectors/hubspot.js +55 -12
  37. package/dist/connectors/influxdb.js +38 -11
  38. package/dist/connectors/intercom-oauth.js +100 -15
  39. package/dist/connectors/intercom.js +42 -15
  40. package/dist/connectors/jdbc.js +36 -9
  41. package/dist/connectors/jira-api-key.js +98 -14
  42. package/dist/connectors/kintone-api-token.js +96 -21
  43. package/dist/connectors/kintone.js +84 -14
  44. package/dist/connectors/linear.js +84 -15
  45. package/dist/connectors/linkedin-ads.js +71 -17
  46. package/dist/connectors/mailchimp-oauth.js +36 -9
  47. package/dist/connectors/mailchimp.js +36 -9
  48. package/dist/connectors/meta-ads-oauth.js +63 -17
  49. package/dist/connectors/meta-ads.js +65 -17
  50. package/dist/connectors/mixpanel.js +38 -11
  51. package/dist/connectors/monday.js +39 -12
  52. package/dist/connectors/mongodb.js +38 -11
  53. package/dist/connectors/notion-oauth.js +88 -14
  54. package/dist/connectors/notion.js +90 -14
  55. package/dist/connectors/openai.js +4 -2
  56. package/dist/connectors/oracle.js +78 -20
  57. package/dist/connectors/outlook-oauth.js +48 -23
  58. package/dist/connectors/powerbi-oauth.js +321 -49
  59. package/dist/connectors/salesforce.js +72 -12
  60. package/dist/connectors/semrush.js +374 -52
  61. package/dist/connectors/sentry.js +66 -13
  62. package/dist/connectors/shopify-oauth.js +71 -13
  63. package/dist/connectors/shopify.js +38 -11
  64. package/dist/connectors/sqlserver.js +64 -13
  65. package/dist/connectors/stripe-api-key.js +96 -18
  66. package/dist/connectors/stripe-oauth.js +98 -22
  67. package/dist/connectors/supabase.js +55 -11
  68. package/dist/connectors/tableau.js +262 -92
  69. package/dist/connectors/tiktok-ads.js +67 -19
  70. package/dist/connectors/wix-store.js +38 -11
  71. package/dist/connectors/zendesk-oauth.js +83 -15
  72. package/dist/connectors/zendesk.js +42 -15
  73. package/dist/index.d.ts +1 -0
  74. package/dist/index.js +4902 -1077
  75. package/dist/main.js +4891 -1071
  76. package/dist/vite-plugin.js +4871 -1071
  77. package/package.json +1 -1
@@ -16,6 +16,7 @@ var init_parameter_definition = __esm({
16
16
  type;
17
17
  secret;
18
18
  required;
19
+ isDeprecated;
19
20
  constructor(config) {
20
21
  this.slug = config.slug;
21
22
  this.name = config.name;
@@ -24,6 +25,7 @@ var init_parameter_definition = __esm({
24
25
  this.type = config.type;
25
26
  this.secret = config.secret;
26
27
  this.required = config.required;
28
+ this.isDeprecated = config.isDeprecated ?? false;
27
29
  }
28
30
  /**
29
31
  * Get the parameter value from a ConnectorConnectionObject.
@@ -185,7 +187,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
185
187
  /**
186
188
  * Create tools for connections that belong to this connector.
187
189
  * Filters connections by connectorKey internally.
188
- * Returns tools keyed as `${connectorKey}_${toolName}`.
190
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
189
191
  */
190
192
  createTools(connections, config, opts) {
191
193
  const myConnections = connections.filter(
@@ -195,7 +197,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
195
197
  for (const t of Object.values(this.tools)) {
196
198
  const tool = t.createTool(myConnections, config);
197
199
  const originalToModelOutput = tool.toModelOutput;
198
- result[`${this.connectorKey}_${t.name}`] = {
200
+ result[`connector_${this.connectorKey}_${t.name}`] = {
199
201
  ...tool,
200
202
  toModelOutput: async (options) => {
201
203
  if (!originalToModelOutput) {
@@ -251,19 +253,34 @@ async function runSetupFlow(flow, params, ctx, config) {
251
253
  };
252
254
  let state = flow.initialState();
253
255
  let answerIdx = 0;
256
+ const pendingParameterUpdates = [];
254
257
  for (const step of flow.steps) {
255
258
  const ans = ctx.answers[answerIdx];
256
259
  if (ans && ans.questionSlug === step.slug) {
257
260
  state = step.applyAnswer(state, ans.answer);
261
+ if (step.toParameterUpdates) {
262
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
263
+ }
258
264
  answerIdx += 1;
259
265
  continue;
260
266
  }
267
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
261
268
  if (step.type === "text") {
269
+ if (step.fetchOptions) {
270
+ const options2 = await step.fetchOptions(state, runtime);
271
+ if (options2.length === 0) {
272
+ continue;
273
+ }
274
+ }
262
275
  return {
263
276
  type: "nextQuestion",
264
277
  questionSlug: step.slug,
265
278
  question: step.question[ctx.language],
266
- questionType: "text"
279
+ questionType: "text",
280
+ allowFreeText: resolvedAllowFreeText,
281
+ ...pendingParameterUpdates.length > 0 && {
282
+ parameterUpdates: pendingParameterUpdates
283
+ }
267
284
  };
268
285
  }
269
286
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -275,11 +292,21 @@ async function runSetupFlow(flow, params, ctx, config) {
275
292
  questionSlug: step.slug,
276
293
  question: step.question[ctx.language],
277
294
  questionType: step.type,
278
- options
295
+ options,
296
+ allowFreeText: resolvedAllowFreeText,
297
+ ...pendingParameterUpdates.length > 0 && {
298
+ parameterUpdates: pendingParameterUpdates
299
+ }
279
300
  };
280
301
  }
281
302
  const dataInvestigationResult = await flow.finalize(state, runtime);
282
- return { type: "fulfilled", dataInvestigationResult };
303
+ return {
304
+ type: "fulfilled",
305
+ dataInvestigationResult,
306
+ ...pendingParameterUpdates.length > 0 && {
307
+ parameterUpdates: pendingParameterUpdates
308
+ }
309
+ };
283
310
  }
284
311
  async function resolveSetupSelection(params) {
285
312
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -451,10 +478,10 @@ var airtableOauthOnboarding = new ConnectorOnboarding({
451
478
  - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
452
479
  },
453
480
  dataOverviewInstructions: {
454
- en: `1. Call airtable-oauth_request with GET /meta/bases/{baseId}/tables to list tables and their fields
455
- 2. Call airtable-oauth_request with GET /{baseId}/{tableIdOrName}?maxRecords=5 to sample records from key tables`,
456
- ja: `1. airtable-oauth_request \u3067 GET /meta/bases/{baseId}/tables \u3092\u547C\u3073\u51FA\u3057\u3001\u30C6\u30FC\u30D6\u30EB\u3068\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u4E00\u89A7\u3092\u53D6\u5F97
457
- 2. airtable-oauth_request \u3067 GET /{baseId}/{tableIdOrName}?maxRecords=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u4E3B\u8981\u30C6\u30FC\u30D6\u30EB\u306E\u30EC\u30B3\u30FC\u30C9\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0`
481
+ en: `1. Call connector_airtable-oauth_request with GET /meta/bases/{baseId}/tables to list tables and their fields
482
+ 2. Call connector_airtable-oauth_request with GET /{baseId}/{tableIdOrName}?maxRecords=5 to sample records from key tables`,
483
+ ja: `1. connector_airtable-oauth_request \u3067 GET /meta/bases/{baseId}/tables \u3092\u547C\u3073\u51FA\u3057\u3001\u30C6\u30FC\u30D6\u30EB\u3068\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u4E00\u89A7\u3092\u53D6\u5F97
484
+ 2. connector_airtable-oauth_request \u3067 GET /{baseId}/{tableIdOrName}?maxRecords=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u4E3B\u8981\u30C6\u30FC\u30D6\u30EB\u306E\u30EC\u30B3\u30FC\u30C9\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0`
458
485
  }
459
486
  });
460
487
 
@@ -490,6 +517,26 @@ async function listTables(proxyFetch, baseId) {
490
517
  const data = await res.json();
491
518
  return data.tables ?? [];
492
519
  }
520
+ async function listSampleRecords(proxyFetch, baseId, tableId) {
521
+ try {
522
+ const res = await apiFetch(
523
+ proxyFetch,
524
+ `/${baseId}/${encodeURIComponent(tableId)}?maxRecords=3`
525
+ );
526
+ if (!res.ok) return [];
527
+ const data = await res.json();
528
+ return data.records ?? [];
529
+ } catch {
530
+ return [];
531
+ }
532
+ }
533
+ function formatCell(val) {
534
+ if (val == null) return "";
535
+ if (typeof val === "string") return val.length > 40 ? `${val.slice(0, 40)}\u2026` : val;
536
+ if (Array.isArray(val)) return `[${val.length} items]`;
537
+ if (typeof val === "object") return JSON.stringify(val).slice(0, 40);
538
+ return String(val);
539
+ }
493
540
  var airtableOauthSetupFlow = {
494
541
  initialState: () => ({}),
495
542
  steps: [
@@ -561,6 +608,26 @@ var airtableOauthSetupFlow = {
561
608
  sections.push(`| ${f.name} | ${f.type} | ${description || "-"} |`);
562
609
  }
563
610
  sections.push("");
611
+ const records = await listSampleRecords(
612
+ rt.config.proxyFetch,
613
+ baseId,
614
+ table.id
615
+ );
616
+ if (records.length > 0) {
617
+ const sampleFields = (table.fields ?? []).slice(0, 5).map((f) => f.name);
618
+ if (sampleFields.length > 0) {
619
+ sections.push(`##### Sample records (${records.length})`, "");
620
+ sections.push(`| ${sampleFields.join(" | ")} |`);
621
+ sections.push(`| ${sampleFields.map(() => "---").join(" | ")} |`);
622
+ for (const record of records) {
623
+ const cells = sampleFields.map(
624
+ (name) => formatCell(record.fields?.[name]).replace(/\|/g, "\\|")
625
+ );
626
+ sections.push(`| ${cells.join(" | ")} |`);
627
+ }
628
+ sections.push("");
629
+ }
630
+ }
564
631
  }
565
632
  return sections.join("\n");
566
633
  }
@@ -590,7 +657,7 @@ var airtableOauthConnector = new ConnectorPlugin({
590
657
  systemPrompt: {
591
658
  en: `### Tools
592
659
 
593
- - \`airtable-oauth_request\`: The only way to call the Airtable REST API. Use it to list tables, query/create/update/delete records. Authentication is configured automatically via OAuth. The {baseId} placeholder in paths is automatically replaced with the configured default base ID.
660
+ - \`connector_airtable-oauth_request\`: The only way to call the Airtable REST API. Use it to list tables, query/create/update/delete records. Authentication is configured automatically via OAuth. The {baseId} placeholder in paths is automatically replaced with the configured default base ID.
594
661
 
595
662
  ### Airtable API Reference
596
663
 
@@ -638,7 +705,7 @@ const recordsData = await records.json();
638
705
  \`\`\``,
639
706
  ja: `### \u30C4\u30FC\u30EB
640
707
 
641
- - \`airtable-oauth_request\`: Airtable REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30C6\u30FC\u30D6\u30EB\u4E00\u89A7\u306E\u53D6\u5F97\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u691C\u7D22\u30FB\u4F5C\u6210\u30FB\u66F4\u65B0\u30FB\u524A\u9664\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002\u30D1\u30B9\u5185\u306E{baseId}\u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u306F\u8A2D\u5B9A\u6E08\u307F\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u30D9\u30FC\u30B9ID\u3067\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002
708
+ - \`connector_airtable-oauth_request\`: Airtable REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30C6\u30FC\u30D6\u30EB\u4E00\u89A7\u306E\u53D6\u5F97\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u691C\u7D22\u30FB\u4F5C\u6210\u30FB\u66F4\u65B0\u30FB\u524A\u9664\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth\u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002\u30D1\u30B9\u5185\u306E{baseId}\u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u30FC\u306F\u8A2D\u5B9A\u6E08\u307F\u306E\u30C7\u30D5\u30A9\u30EB\u30C8\u30D9\u30FC\u30B9ID\u3067\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002
642
709
 
643
710
  ### Airtable API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
644
711
 
@@ -16,6 +16,7 @@ var init_parameter_definition = __esm({
16
16
  type;
17
17
  secret;
18
18
  required;
19
+ isDeprecated;
19
20
  constructor(config) {
20
21
  this.slug = config.slug;
21
22
  this.name = config.name;
@@ -24,6 +25,7 @@ var init_parameter_definition = __esm({
24
25
  this.type = config.type;
25
26
  this.secret = config.secret;
26
27
  this.required = config.required;
28
+ this.isDeprecated = config.isDeprecated ?? false;
27
29
  }
28
30
  /**
29
31
  * Get the parameter value from a ConnectorConnectionObject.
@@ -315,7 +317,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
315
317
  /**
316
318
  * Create tools for connections that belong to this connector.
317
319
  * Filters connections by connectorKey internally.
318
- * Returns tools keyed as `${connectorKey}_${toolName}`.
320
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
319
321
  */
320
322
  createTools(connections, config, opts) {
321
323
  const myConnections = connections.filter(
@@ -325,7 +327,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
325
327
  for (const t of Object.values(this.tools)) {
326
328
  const tool = t.createTool(myConnections, config);
327
329
  const originalToModelOutput = tool.toModelOutput;
328
- result[`${this.connectorKey}_${t.name}`] = {
330
+ result[`connector_${this.connectorKey}_${t.name}`] = {
329
331
  ...tool,
330
332
  toModelOutput: async (options) => {
331
333
  if (!originalToModelOutput) {
@@ -381,19 +383,34 @@ async function runSetupFlow(flow, params, ctx, config) {
381
383
  };
382
384
  let state = flow.initialState();
383
385
  let answerIdx = 0;
386
+ const pendingParameterUpdates = [];
384
387
  for (const step of flow.steps) {
385
388
  const ans = ctx.answers[answerIdx];
386
389
  if (ans && ans.questionSlug === step.slug) {
387
390
  state = step.applyAnswer(state, ans.answer);
391
+ if (step.toParameterUpdates) {
392
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
393
+ }
388
394
  answerIdx += 1;
389
395
  continue;
390
396
  }
397
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
391
398
  if (step.type === "text") {
399
+ if (step.fetchOptions) {
400
+ const options2 = await step.fetchOptions(state, runtime);
401
+ if (options2.length === 0) {
402
+ continue;
403
+ }
404
+ }
392
405
  return {
393
406
  type: "nextQuestion",
394
407
  questionSlug: step.slug,
395
408
  question: step.question[ctx.language],
396
- questionType: "text"
409
+ questionType: "text",
410
+ allowFreeText: resolvedAllowFreeText,
411
+ ...pendingParameterUpdates.length > 0 && {
412
+ parameterUpdates: pendingParameterUpdates
413
+ }
397
414
  };
398
415
  }
399
416
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -405,11 +422,21 @@ async function runSetupFlow(flow, params, ctx, config) {
405
422
  questionSlug: step.slug,
406
423
  question: step.question[ctx.language],
407
424
  questionType: step.type,
408
- options
425
+ options,
426
+ allowFreeText: resolvedAllowFreeText,
427
+ ...pendingParameterUpdates.length > 0 && {
428
+ parameterUpdates: pendingParameterUpdates
429
+ }
409
430
  };
410
431
  }
411
432
  const dataInvestigationResult = await flow.finalize(state, runtime);
412
- return { type: "fulfilled", dataInvestigationResult };
433
+ return {
434
+ type: "fulfilled",
435
+ dataInvestigationResult,
436
+ ...pendingParameterUpdates.length > 0 && {
437
+ parameterUpdates: pendingParameterUpdates
438
+ }
439
+ };
413
440
  }
414
441
  async function resolveSetupSelection(params) {
415
442
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -430,10 +457,10 @@ var AUTH_TYPES = {
430
457
  // ../connectors/src/connectors/airtable/setup.ts
431
458
  var airtableOnboarding = new ConnectorOnboarding({
432
459
  dataOverviewInstructions: {
433
- en: `1. Call airtable_request with GET meta/bases/{baseId}/tables to list tables and their fields
434
- 2. Call airtable_request with GET {baseId}/{tableIdOrName}?maxRecords=5 to sample records from key tables`,
435
- ja: `1. airtable_request \u3067 GET meta/bases/{baseId}/tables \u3092\u547C\u3073\u51FA\u3057\u3001\u30C6\u30FC\u30D6\u30EB\u3068\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u4E00\u89A7\u3092\u53D6\u5F97
436
- 2. airtable_request \u3067 GET {baseId}/{tableIdOrName}?maxRecords=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u4E3B\u8981\u30C6\u30FC\u30D6\u30EB\u306E\u30EC\u30B3\u30FC\u30C9\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0`
460
+ en: `1. Call connector_airtable_request with GET meta/bases/{baseId}/tables to list tables and their fields
461
+ 2. Call connector_airtable_request with GET {baseId}/{tableIdOrName}?maxRecords=5 to sample records from key tables`,
462
+ ja: `1. connector_airtable_request \u3067 GET meta/bases/{baseId}/tables \u3092\u547C\u3073\u51FA\u3057\u3001\u30C6\u30FC\u30D6\u30EB\u3068\u30D5\u30A3\u30FC\u30EB\u30C9\u306E\u4E00\u89A7\u3092\u53D6\u5F97
463
+ 2. connector_airtable_request \u3067 GET {baseId}/{tableIdOrName}?maxRecords=5 \u3092\u547C\u3073\u51FA\u3057\u3001\u4E3B\u8981\u30C6\u30FC\u30D6\u30EB\u306E\u30EC\u30B3\u30FC\u30C9\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0`
437
464
  }
438
465
  });
439
466
 
@@ -471,6 +498,26 @@ async function listTables(params, baseId) {
471
498
  const data = await res.json();
472
499
  return data.tables ?? [];
473
500
  }
501
+ async function listSampleRecords(params, baseId, tableId) {
502
+ try {
503
+ const res = await apiFetch(
504
+ params,
505
+ `/${baseId}/${encodeURIComponent(tableId)}?maxRecords=3`
506
+ );
507
+ if (!res.ok) return [];
508
+ const data = await res.json();
509
+ return data.records ?? [];
510
+ } catch {
511
+ return [];
512
+ }
513
+ }
514
+ function formatCell(val) {
515
+ if (val == null) return "";
516
+ if (typeof val === "string") return val.length > 40 ? `${val.slice(0, 40)}\u2026` : val;
517
+ if (Array.isArray(val)) return `[${val.length} items]`;
518
+ if (typeof val === "object") return JSON.stringify(val).slice(0, 40);
519
+ return String(val);
520
+ }
474
521
  var airtableSetupFlow = {
475
522
  initialState: () => ({}),
476
523
  steps: [
@@ -542,6 +589,22 @@ var airtableSetupFlow = {
542
589
  sections.push(`| ${f.name} | ${f.type} | ${description || "-"} |`);
543
590
  }
544
591
  sections.push("");
592
+ const records = await listSampleRecords(rt.params, baseId, table.id);
593
+ if (records.length > 0) {
594
+ const sampleFields = (table.fields ?? []).slice(0, 5).map((f) => f.name);
595
+ if (sampleFields.length > 0) {
596
+ sections.push(`##### Sample records (${records.length})`, "");
597
+ sections.push(`| ${sampleFields.join(" | ")} |`);
598
+ sections.push(`| ${sampleFields.map(() => "---").join(" | ")} |`);
599
+ for (const record of records) {
600
+ const cells = sampleFields.map(
601
+ (name) => formatCell(record.fields?.[name]).replace(/\|/g, "\\|")
602
+ );
603
+ sections.push(`| ${cells.join(" | ")} |`);
604
+ }
605
+ sections.push("");
606
+ }
607
+ }
545
608
  }
546
609
  return sections.join("\n");
547
610
  }
@@ -633,7 +696,7 @@ var airtableConnector = new ConnectorPlugin({
633
696
  systemPrompt: {
634
697
  en: `### Tools
635
698
 
636
- - \`airtable_request\`: The only way to call the Airtable REST API. Use it to list tables, read records, and create/update records. The \`{baseId}\` placeholder in the path is automatically replaced. See the Airtable API Reference below for available endpoints and query parameters.
699
+ - \`connector_airtable_request\`: The only way to call the Airtable REST API. Use it to list tables, read records, and create/update records. The \`{baseId}\` placeholder in the path is automatically replaced. See the Airtable API Reference below for available endpoints and query parameters.
637
700
 
638
701
  ### Business Logic
639
702
 
@@ -692,7 +755,7 @@ export default async function handler(c: Context) {
692
755
  - If the response contains an \`offset\`, fetch the next page by appending \`?offset={offset}\` to the next request`,
693
756
  ja: `### \u30C4\u30FC\u30EB
694
757
 
695
- - \`airtable_request\`: Airtable REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30C6\u30FC\u30D6\u30EB\u4E00\u89A7\u306E\u53D6\u5F97\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u8AAD\u307F\u53D6\u308A\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u4F5C\u6210\u30FB\u66F4\u65B0\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u30D1\u30B9\u5185\u306E \`{baseId}\` \u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u306F\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002\u5229\u7528\u53EF\u80FD\u306A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3068\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u306F\u4E0B\u90E8\u306E\u300CAirtable API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
758
+ - \`connector_airtable_request\`: Airtable REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30C6\u30FC\u30D6\u30EB\u4E00\u89A7\u306E\u53D6\u5F97\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u8AAD\u307F\u53D6\u308A\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u4F5C\u6210\u30FB\u66F4\u65B0\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u30D1\u30B9\u5185\u306E \`{baseId}\` \u30D7\u30EC\u30FC\u30B9\u30DB\u30EB\u30C0\u306F\u81EA\u52D5\u7684\u306B\u7F6E\u63DB\u3055\u308C\u307E\u3059\u3002\u5229\u7528\u53EF\u80FD\u306A\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u3068\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u306F\u4E0B\u90E8\u306E\u300CAirtable API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
696
759
 
697
760
  ### Business Logic
698
761
 
@@ -16,6 +16,7 @@ var init_parameter_definition = __esm({
16
16
  type;
17
17
  secret;
18
18
  required;
19
+ isDeprecated;
19
20
  constructor(config) {
20
21
  this.slug = config.slug;
21
22
  this.name = config.name;
@@ -24,6 +25,7 @@ var init_parameter_definition = __esm({
24
25
  this.type = config.type;
25
26
  this.secret = config.secret;
26
27
  this.required = config.required;
28
+ this.isDeprecated = config.isDeprecated ?? false;
27
29
  }
28
30
  /**
29
31
  * Get the parameter value from a ConnectorConnectionObject.
@@ -275,7 +277,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
275
277
  /**
276
278
  * Create tools for connections that belong to this connector.
277
279
  * Filters connections by connectorKey internally.
278
- * Returns tools keyed as `${connectorKey}_${toolName}`.
280
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
279
281
  */
280
282
  createTools(connections, config, opts) {
281
283
  const myConnections = connections.filter(
@@ -285,7 +287,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
285
287
  for (const t of Object.values(this.tools)) {
286
288
  const tool = t.createTool(myConnections, config);
287
289
  const originalToModelOutput = tool.toModelOutput;
288
- result[`${this.connectorKey}_${t.name}`] = {
290
+ result[`connector_${this.connectorKey}_${t.name}`] = {
289
291
  ...tool,
290
292
  toModelOutput: async (options) => {
291
293
  if (!originalToModelOutput) {
@@ -341,19 +343,34 @@ async function runSetupFlow(flow, params, ctx, config) {
341
343
  };
342
344
  let state = flow.initialState();
343
345
  let answerIdx = 0;
346
+ const pendingParameterUpdates = [];
344
347
  for (const step of flow.steps) {
345
348
  const ans = ctx.answers[answerIdx];
346
349
  if (ans && ans.questionSlug === step.slug) {
347
350
  state = step.applyAnswer(state, ans.answer);
351
+ if (step.toParameterUpdates) {
352
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
353
+ }
348
354
  answerIdx += 1;
349
355
  continue;
350
356
  }
357
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
351
358
  if (step.type === "text") {
359
+ if (step.fetchOptions) {
360
+ const options2 = await step.fetchOptions(state, runtime);
361
+ if (options2.length === 0) {
362
+ continue;
363
+ }
364
+ }
352
365
  return {
353
366
  type: "nextQuestion",
354
367
  questionSlug: step.slug,
355
368
  question: step.question[ctx.language],
356
- questionType: "text"
369
+ questionType: "text",
370
+ allowFreeText: resolvedAllowFreeText,
371
+ ...pendingParameterUpdates.length > 0 && {
372
+ parameterUpdates: pendingParameterUpdates
373
+ }
357
374
  };
358
375
  }
359
376
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -365,11 +382,21 @@ async function runSetupFlow(flow, params, ctx, config) {
365
382
  questionSlug: step.slug,
366
383
  question: step.question[ctx.language],
367
384
  questionType: step.type,
368
- options
385
+ options,
386
+ allowFreeText: resolvedAllowFreeText,
387
+ ...pendingParameterUpdates.length > 0 && {
388
+ parameterUpdates: pendingParameterUpdates
389
+ }
369
390
  };
370
391
  }
371
392
  const dataInvestigationResult = await flow.finalize(state, runtime);
372
- return { type: "fulfilled", dataInvestigationResult };
393
+ return {
394
+ type: "fulfilled",
395
+ dataInvestigationResult,
396
+ ...pendingParameterUpdates.length > 0 && {
397
+ parameterUpdates: pendingParameterUpdates
398
+ }
399
+ };
373
400
  }
374
401
 
375
402
  // ../connectors/src/auth-types.ts
@@ -386,13 +413,13 @@ var AUTH_TYPES = {
386
413
  var amplitudeOnboarding = new ConnectorOnboarding({
387
414
  dataOverviewInstructions: {
388
415
  en: `1. Check the connection's region parameter: use https://analytics.eu.amplitude.com for EU, https://amplitude.com for US (default)
389
- 2. Call amplitude_request with GET {baseUrl}/api/2/events/list to list available event types
390
- 3. Call amplitude_request with GET {baseUrl}/api/2/export?start=YYYYMMDDTHH&end=YYYYMMDDTHH to export raw event data for a time range
416
+ 2. Call connector_amplitude_request with GET {baseUrl}/api/2/events/list to list available event types
417
+ 3. Call connector_amplitude_request with GET {baseUrl}/api/2/export?start=YYYYMMDDTHH&end=YYYYMMDDTHH to export raw event data for a time range
391
418
  4. Use GET {baseUrl}/api/2/usersearch?user=QUERY and GET {baseUrl}/api/2/useractivity?user=AMPLITUDE_ID to explore user-level data
392
419
  NOTE: The Dashboard REST API endpoints (events/segmentation, funnels, retention, etc.) require a paid Growth or Enterprise plan. If you get a 403 Forbidden error, fall back to the Export API (/api/2/export) to retrieve raw events and perform aggregation in code instead.`,
393
420
  ja: `1. \u63A5\u7D9A\u306Eregion\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u78BA\u8A8D\uFF1AEU\u306E\u5834\u5408\u306F https://analytics.eu.amplitude.com\u3001US\uFF08\u30C7\u30D5\u30A9\u30EB\u30C8\uFF09\u306E\u5834\u5408\u306F https://amplitude.com \u3092\u4F7F\u7528
394
- 2. amplitude_request \u3067 GET {baseUrl}/api/2/events/list \u3092\u547C\u3073\u51FA\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\u4E00\u89A7\u3092\u53D6\u5F97
395
- 3. amplitude_request \u3067 GET {baseUrl}/api/2/export?start=YYYYMMDDTHH&end=YYYYMMDDTHH \u3092\u547C\u3073\u51FA\u3057\u3001\u6307\u5B9A\u671F\u9593\u306E\u751F\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF\u3092\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
421
+ 2. connector_amplitude_request \u3067 GET {baseUrl}/api/2/events/list \u3092\u547C\u3073\u51FA\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\u4E00\u89A7\u3092\u53D6\u5F97
422
+ 3. connector_amplitude_request \u3067 GET {baseUrl}/api/2/export?start=YYYYMMDDTHH&end=YYYYMMDDTHH \u3092\u547C\u3073\u51FA\u3057\u3001\u6307\u5B9A\u671F\u9593\u306E\u751F\u30A4\u30D9\u30F3\u30C8\u30C7\u30FC\u30BF\u3092\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8
396
423
  4. GET {baseUrl}/api/2/usersearch?user=QUERY \u3084 GET {baseUrl}/api/2/useractivity?user=AMPLITUDE_ID \u3067\u30E6\u30FC\u30B6\u30FC\u30EC\u30D9\u30EB\u306E\u30C7\u30FC\u30BF\u3092\u63A2\u7D22
397
424
  \u6CE8\u610F: Dashboard REST API\uFF08events/segmentation\u3001funnels\u3001retention\u7B49\uFF09\u306F\u6709\u6599\u306EGrowth\u307E\u305F\u306FEnterprise\u30D7\u30E9\u30F3\u304C\u5FC5\u8981\u3067\u3059\u3002403 Forbidden\u30A8\u30E9\u30FC\u304C\u8FD4\u3055\u308C\u305F\u5834\u5408\u306F\u3001Export API\uFF08/api/2/export\uFF09\u3067\u751F\u30A4\u30D9\u30F3\u30C8\u3092\u53D6\u5F97\u3057\u3001\u30B3\u30FC\u30C9\u4E0A\u3067\u96C6\u8A08\u3092\u884C\u3063\u3066\u304F\u3060\u3055\u3044\u3002`
398
425
  }
@@ -618,7 +645,7 @@ var amplitudeConnector = new ConnectorPlugin({
618
645
  systemPrompt: {
619
646
  en: `### Tools
620
647
 
621
- - \`amplitude_request\`: The only way to call the Amplitude REST API. Use it for event segmentation, listing event types, user search, user activity, and data export. Authentication (Basic auth with API Key + Secret Key) is configured automatically. Provide the full URL including query parameters \u2014 the base URL varies by endpoint.
648
+ - \`connector_amplitude_request\`: The only way to call the Amplitude REST API. Use it for event segmentation, listing event types, user search, user activity, and data export. Authentication (Basic auth with API Key + Secret Key) is configured automatically. Provide the full URL including query parameters \u2014 the base URL varies by endpoint.
622
649
 
623
650
  ### Business Logic
624
651
 
@@ -682,7 +709,7 @@ IMPORTANT: Always start with the endpoints available on all plans. If you need a
682
709
  - \`g\` \u2014 Group by property`,
683
710
  ja: `### \u30C4\u30FC\u30EB
684
711
 
685
- - \`amplitude_request\`: Amplitude REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30A4\u30D9\u30F3\u30C8\u30BB\u30B0\u30E1\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u3001\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\u4E00\u89A7\u3001\u30E6\u30FC\u30B6\u30FC\u691C\u7D22\u3001\u30E6\u30FC\u30B6\u30FC\u30A2\u30AF\u30C6\u30A3\u30D3\u30C6\u30A3\u3001\u30C7\u30FC\u30BF\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08API Key + Secret Key\u306B\u3088\u308BBasic\u8A8D\u8A3C\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u542B\u3080\u5B8C\u5168\u306AURL\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 \u2014 \u30D9\u30FC\u30B9URL\u306F\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306B\u3088\u3063\u3066\u7570\u306A\u308A\u307E\u3059\u3002
712
+ - \`connector_amplitude_request\`: Amplitude REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30A4\u30D9\u30F3\u30C8\u30BB\u30B0\u30E1\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u3001\u30A4\u30D9\u30F3\u30C8\u30BF\u30A4\u30D7\u4E00\u89A7\u3001\u30E6\u30FC\u30B6\u30FC\u691C\u7D22\u3001\u30E6\u30FC\u30B6\u30FC\u30A2\u30AF\u30C6\u30A3\u30D3\u30C6\u30A3\u3001\u30C7\u30FC\u30BF\u30A8\u30AF\u30B9\u30DD\u30FC\u30C8\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\uFF08API Key + Secret Key\u306B\u3088\u308BBasic\u8A8D\u8A3C\uFF09\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002\u30AF\u30A8\u30EA\u30D1\u30E9\u30E1\u30FC\u30BF\u3092\u542B\u3080\u5B8C\u5168\u306AURL\u3092\u6307\u5B9A\u3057\u3066\u304F\u3060\u3055\u3044 \u2014 \u30D9\u30FC\u30B9URL\u306F\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u306B\u3088\u3063\u3066\u7570\u306A\u308A\u307E\u3059\u3002
686
713
 
687
714
  ### Business Logic
688
715
 
@@ -16,6 +16,7 @@ var init_parameter_definition = __esm({
16
16
  type;
17
17
  secret;
18
18
  required;
19
+ isDeprecated;
19
20
  constructor(config) {
20
21
  this.slug = config.slug;
21
22
  this.name = config.name;
@@ -24,6 +25,7 @@ var init_parameter_definition = __esm({
24
25
  this.type = config.type;
25
26
  this.secret = config.secret;
26
27
  this.required = config.required;
28
+ this.isDeprecated = config.isDeprecated ?? false;
27
29
  }
28
30
  /**
29
31
  * Get the parameter value from a ConnectorConnectionObject.
@@ -142,7 +144,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
142
144
  /**
143
145
  * Create tools for connections that belong to this connector.
144
146
  * Filters connections by connectorKey internally.
145
- * Returns tools keyed as `${connectorKey}_${toolName}`.
147
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
146
148
  */
147
149
  createTools(connections, config, opts) {
148
150
  const myConnections = connections.filter(
@@ -152,7 +154,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
152
154
  for (const t of Object.values(this.tools)) {
153
155
  const tool = t.createTool(myConnections, config);
154
156
  const originalToModelOutput = tool.toModelOutput;
155
- result[`${this.connectorKey}_${t.name}`] = {
157
+ result[`connector_${this.connectorKey}_${t.name}`] = {
156
158
  ...tool,
157
159
  toModelOutput: async (options) => {
158
160
  if (!originalToModelOutput) {