@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
@@ -172,7 +172,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
172
172
  /**
173
173
  * Create tools for connections that belong to this connector.
174
174
  * Filters connections by connectorKey internally.
175
- * Returns tools keyed as `${connectorKey}_${toolName}`.
175
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
176
176
  */
177
177
  createTools(connections, config, opts) {
178
178
  const myConnections = connections.filter(
@@ -182,7 +182,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
182
182
  for (const t of Object.values(this.tools)) {
183
183
  const tool = t.createTool(myConnections, config);
184
184
  const originalToModelOutput = tool.toModelOutput;
185
- result[`${this.connectorKey}_${t.name}`] = {
185
+ result[`connector_${this.connectorKey}_${t.name}`] = {
186
186
  ...tool,
187
187
  toModelOutput: async (options) => {
188
188
  if (!originalToModelOutput) {
@@ -238,19 +238,34 @@ async function runSetupFlow(flow, params, ctx, config) {
238
238
  };
239
239
  let state = flow.initialState();
240
240
  let answerIdx = 0;
241
+ const pendingParameterUpdates = [];
241
242
  for (const step of flow.steps) {
242
243
  const ans = ctx.answers[answerIdx];
243
244
  if (ans && ans.questionSlug === step.slug) {
244
245
  state = step.applyAnswer(state, ans.answer);
246
+ if (step.toParameterUpdates) {
247
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
248
+ }
245
249
  answerIdx += 1;
246
250
  continue;
247
251
  }
252
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
248
253
  if (step.type === "text") {
254
+ if (step.fetchOptions) {
255
+ const options2 = await step.fetchOptions(state, runtime);
256
+ if (options2.length === 0) {
257
+ continue;
258
+ }
259
+ }
249
260
  return {
250
261
  type: "nextQuestion",
251
262
  questionSlug: step.slug,
252
263
  question: step.question[ctx.language],
253
- questionType: "text"
264
+ questionType: "text",
265
+ allowFreeText: resolvedAllowFreeText,
266
+ ...pendingParameterUpdates.length > 0 && {
267
+ parameterUpdates: pendingParameterUpdates
268
+ }
254
269
  };
255
270
  }
256
271
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -262,11 +277,21 @@ async function runSetupFlow(flow, params, ctx, config) {
262
277
  questionSlug: step.slug,
263
278
  question: step.question[ctx.language],
264
279
  questionType: step.type,
265
- options
280
+ options,
281
+ allowFreeText: resolvedAllowFreeText,
282
+ ...pendingParameterUpdates.length > 0 && {
283
+ parameterUpdates: pendingParameterUpdates
284
+ }
266
285
  };
267
286
  }
268
287
  const dataInvestigationResult = await flow.finalize(state, runtime);
269
- return { type: "fulfilled", dataInvestigationResult };
288
+ return {
289
+ type: "fulfilled",
290
+ dataInvestigationResult,
291
+ ...pendingParameterUpdates.length > 0 && {
292
+ parameterUpdates: pendingParameterUpdates
293
+ }
294
+ };
270
295
  }
271
296
  async function resolveSetupSelection(params) {
272
297
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -297,10 +322,10 @@ function normalizeRequestPath(path2, basePathSegment) {
297
322
  // ../connectors/src/connectors/google-slides/setup.ts
298
323
  var googleSlidesOnboarding = new ConnectorOnboarding({
299
324
  dataOverviewInstructions: {
300
- en: `1. Create a new presentation with google-slides-oauth_request (POST with body { title: "..." }) or use an existing presentation ID.
301
- 2. Call google-slides-oauth_request with GET /{presentationId} to fetch presentation metadata (title, slide count, layout info).`,
302
- ja: `1. google-slides-oauth_request \u3092 POST\uFF08Body: { title: "..." }\uFF09\u3067\u547C\u3073\u51FA\u3057\u3066\u65B0\u3057\u3044\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u3092\u4F5C\u6210\u3059\u308B\u304B\u3001\u65E2\u5B58\u306E\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3ID\u3092\u5229\u7528\u3057\u307E\u3059\u3002
303
- 2. google-slides-oauth_request \u3067 GET /{presentationId} \u3092\u547C\u3073\u51FA\u3057\u3001\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\uFF08\u30BF\u30A4\u30C8\u30EB\u3001\u30B9\u30E9\u30A4\u30C9\u6570\u3001\u30EC\u30A4\u30A2\u30A6\u30C8\u60C5\u5831\uFF09\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002`
325
+ en: `1. Create a new presentation with connector_google-slides-oauth_request (POST with body { title: "..." }) or use an existing presentation ID.
326
+ 2. Call connector_google-slides-oauth_request with GET /{presentationId} to fetch presentation metadata (title, slide count, layout info).`,
327
+ ja: `1. connector_google-slides-oauth_request \u3092 POST\uFF08Body: { title: "..." }\uFF09\u3067\u547C\u3073\u51FA\u3057\u3066\u65B0\u3057\u3044\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u3092\u4F5C\u6210\u3059\u308B\u304B\u3001\u65E2\u5B58\u306E\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3ID\u3092\u5229\u7528\u3057\u307E\u3059\u3002
328
+ 2. connector_google-slides-oauth_request \u3067 GET /{presentationId} \u3092\u547C\u3073\u51FA\u3057\u3001\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\uFF08\u30BF\u30A4\u30C8\u30EB\u3001\u30B9\u30E9\u30A4\u30C9\u6570\u3001\u30EC\u30A4\u30A2\u30A6\u30C8\u60C5\u5831\uFF09\u3092\u53D6\u5F97\u3057\u307E\u3059\u3002`
304
329
  }
305
330
  });
306
331
 
@@ -536,9 +561,9 @@ var googleSlidesConnector = new ConnectorPlugin({
536
561
  systemPrompt: {
537
562
  en: `### Tools (setup-time only)
538
563
 
539
- - \`google-slides-oauth_request\`: Call the Google Slides API directly during setup / data overview. Supports read and write operations. Use it to get presentation metadata, slide content, create new presentations, and modify slides. Authentication is configured automatically via OAuth.
564
+ - \`connector_google-slides-oauth_request\`: Call the Google Slides API directly during setup / data overview. Supports read and write operations. Use it to get presentation metadata, slide content, create new presentations, and modify slides. Authentication is configured automatically via OAuth.
540
565
 
541
- > **Important**: The \`google-slides-oauth_request\` tool is only available at setup time. Inside server-logic handlers, use the SDK (\`connection(id).createPresentation\`, etc.) \u2014 the SDK's fetch is already wired through the OAuth proxy. **Do NOT** hand-roll HTTP calls to \`_sqcore/connections/*/request\` from a handler.
566
+ > **Important**: The \`connector_google-slides-oauth_request\` tool is only available at setup time. Inside server-logic handlers, use the SDK (\`connection(id).createPresentation\`, etc.) \u2014 the SDK's fetch is already wired through the OAuth proxy. **Do NOT** hand-roll HTTP calls to \`_sqcore/connections/*/request\` from a handler.
542
567
 
543
568
  ### Google Slides API Reference
544
569
 
@@ -615,9 +640,9 @@ await slides.batchUpdate(presentationId, [
615
640
  If a handler test fails with \`Connection proxy is not configured\`, retry \u2014 this usually means the sandbox is still initializing. Do NOT abandon the SDK and construct OAuth proxy URLs manually.`,
616
641
  ja: `### \u30C4\u30FC\u30EB\uFF08\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306E\u307F\uFF09
617
642
 
618
- - \`google-slides-oauth_request\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3084\u30C7\u30FC\u30BF\u6982\u8981\u628A\u63E1\u6642\u306B Google Slides API \u3092\u76F4\u63A5\u53E9\u304F\u30C4\u30FC\u30EB\u3067\u3059\u3002\u8AAD\u307F\u53D6\u308A\u3068\u66F8\u304D\u8FBC\u307F\u306E\u4E21\u65B9\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u30FB\u30B9\u30E9\u30A4\u30C9\u5185\u5BB9\u306E\u53D6\u5F97\u3001\u65B0\u3057\u3044\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u4F5C\u6210\u3001\u30B9\u30E9\u30A4\u30C9\u306E\u5909\u66F4\u306A\u3069\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth \u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
643
+ - \`connector_google-slides-oauth_request\`: \u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u3084\u30C7\u30FC\u30BF\u6982\u8981\u628A\u63E1\u6642\u306B Google Slides API \u3092\u76F4\u63A5\u53E9\u304F\u30C4\u30FC\u30EB\u3067\u3059\u3002\u8AAD\u307F\u53D6\u308A\u3068\u66F8\u304D\u8FBC\u307F\u306E\u4E21\u65B9\u3092\u30B5\u30DD\u30FC\u30C8\u3057\u307E\u3059\u3002\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u30E1\u30BF\u30C7\u30FC\u30BF\u30FB\u30B9\u30E9\u30A4\u30C9\u5185\u5BB9\u306E\u53D6\u5F97\u3001\u65B0\u3057\u3044\u30D7\u30EC\u30BC\u30F3\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u4F5C\u6210\u3001\u30B9\u30E9\u30A4\u30C9\u306E\u5909\u66F4\u306A\u3069\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002OAuth \u7D4C\u7531\u3067\u8A8D\u8A3C\u306F\u81EA\u52D5\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002
619
644
 
620
- > **\u91CD\u8981**: \`google-slides-oauth_request\` \u306F\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306E\u307F\u5229\u7528\u53EF\u80FD\u3067\u3059\u3002\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u306E\u30CF\u30F3\u30C9\u30E9\u5185\u3067\u306F\u5FC5\u305A SDK\uFF08\`connection(id).createPresentation\` \u306A\u3069\uFF09\u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002SDK \u306E fetch \u306F OAuth \u30D7\u30ED\u30AD\u30B7\u7D4C\u7531\u3067\u65E2\u306B\u914D\u7DDA\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30CF\u30F3\u30C9\u30E9\u304B\u3089 \`_sqcore/connections/*/request\` \u3092\u624B\u66F8\u304D\u3067\u547C\u3073\u51FA\u3055\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
645
+ > **\u91CD\u8981**: \`connector_google-slides-oauth_request\` \u306F\u30BB\u30C3\u30C8\u30A2\u30C3\u30D7\u6642\u306E\u307F\u5229\u7528\u53EF\u80FD\u3067\u3059\u3002\u30B5\u30FC\u30D0\u30FC\u30ED\u30B8\u30C3\u30AF\u306E\u30CF\u30F3\u30C9\u30E9\u5185\u3067\u306F\u5FC5\u305A SDK\uFF08\`connection(id).createPresentation\` \u306A\u3069\uFF09\u3092\u4F7F\u3063\u3066\u304F\u3060\u3055\u3044\u3002SDK \u306E fetch \u306F OAuth \u30D7\u30ED\u30AD\u30B7\u7D4C\u7531\u3067\u65E2\u306B\u914D\u7DDA\u3055\u308C\u3066\u3044\u307E\u3059\u3002\u30CF\u30F3\u30C9\u30E9\u304B\u3089 \`_sqcore/connections/*/request\` \u3092\u624B\u66F8\u304D\u3067\u547C\u3073\u51FA\u3055\u306A\u3044\u3067\u304F\u3060\u3055\u3044\u3002
621
646
 
622
647
  ### Google Slides API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
623
648
 
@@ -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.
@@ -281,7 +283,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
281
283
  /**
282
284
  * Create tools for connections that belong to this connector.
283
285
  * Filters connections by connectorKey internally.
284
- * Returns tools keyed as `${connectorKey}_${toolName}`.
286
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
285
287
  */
286
288
  createTools(connections, config, opts) {
287
289
  const myConnections = connections.filter(
@@ -291,7 +293,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
291
293
  for (const t of Object.values(this.tools)) {
292
294
  const tool = t.createTool(myConnections, config);
293
295
  const originalToModelOutput = tool.toModelOutput;
294
- result[`${this.connectorKey}_${t.name}`] = {
296
+ result[`connector_${this.connectorKey}_${t.name}`] = {
295
297
  ...tool,
296
298
  toModelOutput: async (options) => {
297
299
  if (!originalToModelOutput) {
@@ -347,19 +349,34 @@ async function runSetupFlow(flow, params, ctx, config) {
347
349
  };
348
350
  let state = flow.initialState();
349
351
  let answerIdx = 0;
352
+ const pendingParameterUpdates = [];
350
353
  for (const step of flow.steps) {
351
354
  const ans = ctx.answers[answerIdx];
352
355
  if (ans && ans.questionSlug === step.slug) {
353
356
  state = step.applyAnswer(state, ans.answer);
357
+ if (step.toParameterUpdates) {
358
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
359
+ }
354
360
  answerIdx += 1;
355
361
  continue;
356
362
  }
363
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
357
364
  if (step.type === "text") {
365
+ if (step.fetchOptions) {
366
+ const options2 = await step.fetchOptions(state, runtime);
367
+ if (options2.length === 0) {
368
+ continue;
369
+ }
370
+ }
358
371
  return {
359
372
  type: "nextQuestion",
360
373
  questionSlug: step.slug,
361
374
  question: step.question[ctx.language],
362
- questionType: "text"
375
+ questionType: "text",
376
+ allowFreeText: resolvedAllowFreeText,
377
+ ...pendingParameterUpdates.length > 0 && {
378
+ parameterUpdates: pendingParameterUpdates
379
+ }
363
380
  };
364
381
  }
365
382
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -371,11 +388,21 @@ async function runSetupFlow(flow, params, ctx, config) {
371
388
  questionSlug: step.slug,
372
389
  question: step.question[ctx.language],
373
390
  questionType: step.type,
374
- options
391
+ options,
392
+ allowFreeText: resolvedAllowFreeText,
393
+ ...pendingParameterUpdates.length > 0 && {
394
+ parameterUpdates: pendingParameterUpdates
395
+ }
375
396
  };
376
397
  }
377
398
  const dataInvestigationResult = await flow.finalize(state, runtime);
378
- return { type: "fulfilled", dataInvestigationResult };
399
+ return {
400
+ type: "fulfilled",
401
+ dataInvestigationResult,
402
+ ...pendingParameterUpdates.length > 0 && {
403
+ parameterUpdates: pendingParameterUpdates
404
+ }
405
+ };
379
406
  }
380
407
  async function resolveSetupSelection(params) {
381
408
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -396,12 +423,12 @@ var AUTH_TYPES = {
396
423
  // ../connectors/src/connectors/grafana/setup.ts
397
424
  var grafanaOnboarding = new ConnectorOnboarding({
398
425
  dataOverviewInstructions: {
399
- en: `1. Call grafana_request with GET /api/datasources to list all configured datasources
400
- 2. Call grafana_request with GET /api/search?type=dash-db&limit=10 to list dashboards
401
- 3. For a specific datasource, call grafana_request with POST /api/ds/query to run a test query`,
402
- ja: `1. grafana_request \u3067 GET /api/datasources \u3092\u547C\u3073\u51FA\u3057\u3001\u8A2D\u5B9A\u6E08\u307F\u306E\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97
403
- 2. grafana_request \u3067 GET /api/search?type=dash-db&limit=10 \u3092\u547C\u3073\u51FA\u3057\u3001\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u4E00\u89A7\u3092\u53D6\u5F97
404
- 3. \u7279\u5B9A\u306E\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u306B\u5BFE\u3057\u3066 grafana_request \u3067 POST /api/ds/query \u3092\u547C\u3073\u51FA\u3057\u3001\u30C6\u30B9\u30C8\u30AF\u30A8\u30EA\u3092\u5B9F\u884C`
426
+ en: `1. Call connector_grafana_request with GET /api/datasources to list all configured datasources
427
+ 2. Call connector_grafana_request with GET /api/search?type=dash-db&limit=10 to list dashboards
428
+ 3. For a specific datasource, call connector_grafana_request with POST /api/ds/query to run a test query`,
429
+ ja: `1. connector_grafana_request \u3067 GET /api/datasources \u3092\u547C\u3073\u51FA\u3057\u3001\u8A2D\u5B9A\u6E08\u307F\u306E\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u4E00\u89A7\u3092\u53D6\u5F97
430
+ 2. connector_grafana_request \u3067 GET /api/search?type=dash-db&limit=10 \u3092\u547C\u3073\u51FA\u3057\u3001\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u4E00\u89A7\u3092\u53D6\u5F97
431
+ 3. \u7279\u5B9A\u306E\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u306B\u5BFE\u3057\u3066 connector_grafana_request \u3067 POST /api/ds/query \u3092\u547C\u3073\u51FA\u3057\u3001\u30C6\u30B9\u30C8\u30AF\u30A8\u30EA\u3092\u5B9F\u884C`
405
432
  }
406
433
  });
407
434
 
@@ -452,6 +479,26 @@ async function listDatasources(params) {
452
479
  const data = await res.json();
453
480
  return data ?? [];
454
481
  }
482
+ async function countDashboards(params) {
483
+ try {
484
+ const res = await apiFetch(params, "/api/search?type=dash-db&limit=5000");
485
+ if (!res.ok) return null;
486
+ const data = await res.json();
487
+ return Array.isArray(data) ? data.length : null;
488
+ } catch {
489
+ return null;
490
+ }
491
+ }
492
+ async function countAlertRules(params) {
493
+ try {
494
+ const res = await apiFetch(params, "/api/alert-rules");
495
+ if (!res.ok) return null;
496
+ const data = await res.json();
497
+ return Array.isArray(data) ? data.length : null;
498
+ } catch {
499
+ return null;
500
+ }
501
+ }
455
502
  var grafanaSetupFlow = {
456
503
  initialState: () => ({}),
457
504
  steps: [
@@ -524,6 +571,21 @@ var grafanaSetupFlow = {
524
571
  sections.push(`| Default | ${ds.isDefault ? "yes" : "no"} |`);
525
572
  sections.push("");
526
573
  }
574
+ const [dashboardCount, alertCount] = await Promise.all([
575
+ countDashboards(rt.params),
576
+ countAlertRules(rt.params)
577
+ ]);
578
+ if (dashboardCount != null || alertCount != null) {
579
+ sections.push(
580
+ rt.language === "ja" ? "### \u30B3\u30F3\u30C6\u30F3\u30C4\u6982\u8981" : "### Content overview",
581
+ ""
582
+ );
583
+ sections.push("| Resource | Count |");
584
+ sections.push("|----------|-------|");
585
+ sections.push(`| Dashboards | ${dashboardCount ?? "-"} |`);
586
+ sections.push(`| Alert rules | ${alertCount ?? "-"} |`);
587
+ sections.push("");
588
+ }
527
589
  return sections.join("\n");
528
590
  }
529
591
  };
@@ -625,7 +687,7 @@ var grafanaConnector = new ConnectorPlugin({
625
687
  systemPrompt: {
626
688
  en: `### Tools
627
689
 
628
- - \`grafana_request\`: The only way to call the Grafana HTTP API. Use it to list datasources, search dashboards, execute datasource queries, manage alerts, and read annotations. Authentication is handled automatically via Bearer token. The path must start with \`/\`.
690
+ - \`connector_grafana_request\`: The only way to call the Grafana HTTP API. Use it to list datasources, search dashboards, execute datasource queries, manage alerts, and read annotations. Authentication is handled automatically via Bearer token. The path must start with \`/\`.
629
691
 
630
692
  ### Business Logic
631
693
 
@@ -683,7 +745,7 @@ export default async function handler(c: Context) {
683
745
  - \`GET /api/health\` \u2014 Health check`,
684
746
  ja: `### \u30C4\u30FC\u30EB
685
747
 
686
- - \`grafana_request\`: Grafana HTTP API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u306E\u4E00\u89A7\u53D6\u5F97\u3001\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u691C\u7D22\u3001\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u30AF\u30A8\u30EA\u306E\u5B9F\u884C\u3001\u30A2\u30E9\u30FC\u30C8\u7BA1\u7406\u3001\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u8AAD\u307F\u53D6\u308A\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\u306FBearer\u30C8\u30FC\u30AF\u30F3\u3067\u81EA\u52D5\u51E6\u7406\u3055\u308C\u307E\u3059\u3002\u30D1\u30B9\u306F \`/\` \u3067\u59CB\u3081\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
748
+ - \`connector_grafana_request\`: Grafana HTTP API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u306E\u4E00\u89A7\u53D6\u5F97\u3001\u30C0\u30C3\u30B7\u30E5\u30DC\u30FC\u30C9\u691C\u7D22\u3001\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9\u30AF\u30A8\u30EA\u306E\u5B9F\u884C\u3001\u30A2\u30E9\u30FC\u30C8\u7BA1\u7406\u3001\u30A2\u30CE\u30C6\u30FC\u30B7\u30E7\u30F3\u306E\u8AAD\u307F\u53D6\u308A\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\u306FBearer\u30C8\u30FC\u30AF\u30F3\u3067\u81EA\u52D5\u51E6\u7406\u3055\u308C\u307E\u3059\u3002\u30D1\u30B9\u306F \`/\` \u3067\u59CB\u3081\u308B\u5FC5\u8981\u304C\u3042\u308A\u307E\u3059\u3002
687
749
 
688
750
  ### Business Logic
689
751
 
@@ -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) {
@@ -180,19 +180,34 @@ async function runSetupFlow(flow, params, ctx, config) {
180
180
  };
181
181
  let state = flow.initialState();
182
182
  let answerIdx = 0;
183
+ const pendingParameterUpdates = [];
183
184
  for (const step of flow.steps) {
184
185
  const ans = ctx.answers[answerIdx];
185
186
  if (ans && ans.questionSlug === step.slug) {
186
187
  state = step.applyAnswer(state, ans.answer);
188
+ if (step.toParameterUpdates) {
189
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
190
+ }
187
191
  answerIdx += 1;
188
192
  continue;
189
193
  }
194
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
190
195
  if (step.type === "text") {
196
+ if (step.fetchOptions) {
197
+ const options2 = await step.fetchOptions(state, runtime);
198
+ if (options2.length === 0) {
199
+ continue;
200
+ }
201
+ }
191
202
  return {
192
203
  type: "nextQuestion",
193
204
  questionSlug: step.slug,
194
205
  question: step.question[ctx.language],
195
- questionType: "text"
206
+ questionType: "text",
207
+ allowFreeText: resolvedAllowFreeText,
208
+ ...pendingParameterUpdates.length > 0 && {
209
+ parameterUpdates: pendingParameterUpdates
210
+ }
196
211
  };
197
212
  }
198
213
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -204,11 +219,21 @@ async function runSetupFlow(flow, params, ctx, config) {
204
219
  questionSlug: step.slug,
205
220
  question: step.question[ctx.language],
206
221
  questionType: step.type,
207
- options
222
+ options,
223
+ allowFreeText: resolvedAllowFreeText,
224
+ ...pendingParameterUpdates.length > 0 && {
225
+ parameterUpdates: pendingParameterUpdates
226
+ }
208
227
  };
209
228
  }
210
229
  const dataInvestigationResult = await flow.finalize(state, runtime);
211
- return { type: "fulfilled", dataInvestigationResult };
230
+ return {
231
+ type: "fulfilled",
232
+ dataInvestigationResult,
233
+ ...pendingParameterUpdates.length > 0 && {
234
+ parameterUpdates: pendingParameterUpdates
235
+ }
236
+ };
212
237
  }
213
238
  async function resolveSetupSelection(params) {
214
239
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -367,11 +392,11 @@ var hubspotOnboarding = new ConnectorOnboarding({
367
392
  - Write only 1 sentence between tool calls, then immediately call the next tool. Skip unnecessary explanations and proceed efficiently`
368
393
  },
369
394
  dataOverviewInstructions: {
370
- en: `1. Call hubspot-oauth_request with GET /crm/v3/objects/contacts?limit=5 to explore contacts structure
371
- 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
372
397
  3. Explore other object types (companies, etc.) as needed to understand available data`,
373
- 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
374
- 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
375
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`
376
401
  }
377
402
  });
@@ -409,6 +434,19 @@ async function listProperties(proxyFetch, objectType) {
409
434
  const data = await res.json();
410
435
  return data.results ?? [];
411
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
+ }
412
450
  var hubspotOauthSetupFlow = {
413
451
  initialState: () => ({}),
414
452
  steps: [
@@ -439,8 +477,27 @@ var hubspotOauthSetupFlow = {
439
477
  limit: HUBSPOT_SETUP_MAX_OBJECT_TYPES
440
478
  });
441
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("");
442
497
  for (const objectType of targetObjectTypes) {
443
- sections.push(`### Object: ${objectType}`, "");
498
+ const count = countByType.get(objectType);
499
+ const countLabel = count == null ? "" : ` (${count.toLocaleString()} records)`;
500
+ sections.push(`### Object: ${objectType}${countLabel}`, "");
444
501
  const props = await listProperties(rt.config.proxyFetch, objectType);
445
502
  const limited = props.slice(0, HUBSPOT_SETUP_MAX_PROPERTIES);
446
503
  sections.push("| Property | Type | Label |");
@@ -490,7 +547,7 @@ var hubspotOauthConnector = new ConnectorPlugin({
490
547
  systemPrompt: {
491
548
  en: `### Tools
492
549
 
493
- - \`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.
494
551
 
495
552
  ### HubSpot API Reference
496
553
 
@@ -535,7 +592,7 @@ const data = await res.json();
535
592
  \`\`\``,
536
593
  ja: `### \u30C4\u30FC\u30EB
537
594
 
538
- - \`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
539
596
 
540
597
  ### HubSpot API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9
541
598
 
@@ -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.
@@ -255,7 +257,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
255
257
  /**
256
258
  * Create tools for connections that belong to this connector.
257
259
  * Filters connections by connectorKey internally.
258
- * Returns tools keyed as `${connectorKey}_${toolName}`.
260
+ * Returns tools keyed as `connector_${connectorKey}_${toolName}`.
259
261
  */
260
262
  createTools(connections, config, opts) {
261
263
  const myConnections = connections.filter(
@@ -265,7 +267,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
265
267
  for (const t of Object.values(this.tools)) {
266
268
  const tool = t.createTool(myConnections, config);
267
269
  const originalToModelOutput = tool.toModelOutput;
268
- result[`${this.connectorKey}_${t.name}`] = {
270
+ result[`connector_${this.connectorKey}_${t.name}`] = {
269
271
  ...tool,
270
272
  toModelOutput: async (options) => {
271
273
  if (!originalToModelOutput) {
@@ -321,19 +323,34 @@ async function runSetupFlow(flow, params, ctx, config) {
321
323
  };
322
324
  let state = flow.initialState();
323
325
  let answerIdx = 0;
326
+ const pendingParameterUpdates = [];
324
327
  for (const step of flow.steps) {
325
328
  const ans = ctx.answers[answerIdx];
326
329
  if (ans && ans.questionSlug === step.slug) {
327
330
  state = step.applyAnswer(state, ans.answer);
331
+ if (step.toParameterUpdates) {
332
+ pendingParameterUpdates.push(...step.toParameterUpdates(state));
333
+ }
328
334
  answerIdx += 1;
329
335
  continue;
330
336
  }
337
+ const resolvedAllowFreeText = step.allowFreeText !== void 0 ? step.allowFreeText : true;
331
338
  if (step.type === "text") {
339
+ if (step.fetchOptions) {
340
+ const options2 = await step.fetchOptions(state, runtime);
341
+ if (options2.length === 0) {
342
+ continue;
343
+ }
344
+ }
332
345
  return {
333
346
  type: "nextQuestion",
334
347
  questionSlug: step.slug,
335
348
  question: step.question[ctx.language],
336
- questionType: "text"
349
+ questionType: "text",
350
+ allowFreeText: resolvedAllowFreeText,
351
+ ...pendingParameterUpdates.length > 0 && {
352
+ parameterUpdates: pendingParameterUpdates
353
+ }
337
354
  };
338
355
  }
339
356
  const options = step.fetchOptions ? await step.fetchOptions(state, runtime) : [];
@@ -345,11 +362,21 @@ async function runSetupFlow(flow, params, ctx, config) {
345
362
  questionSlug: step.slug,
346
363
  question: step.question[ctx.language],
347
364
  questionType: step.type,
348
- options
365
+ options,
366
+ allowFreeText: resolvedAllowFreeText,
367
+ ...pendingParameterUpdates.length > 0 && {
368
+ parameterUpdates: pendingParameterUpdates
369
+ }
349
370
  };
350
371
  }
351
372
  const dataInvestigationResult = await flow.finalize(state, runtime);
352
- return { type: "fulfilled", dataInvestigationResult };
373
+ return {
374
+ type: "fulfilled",
375
+ dataInvestigationResult,
376
+ ...pendingParameterUpdates.length > 0 && {
377
+ parameterUpdates: pendingParameterUpdates
378
+ }
379
+ };
353
380
  }
354
381
  async function resolveSetupSelection(params) {
355
382
  const { selected, allSentinel, fetchAll, limit } = params;
@@ -370,11 +397,11 @@ var AUTH_TYPES = {
370
397
  // ../connectors/src/connectors/hubspot/setup.ts
371
398
  var hubspotOnboarding = new ConnectorOnboarding({
372
399
  dataOverviewInstructions: {
373
- en: `1. Call hubspot_request with GET /crm/v3/objects/contacts?limit=5 to explore contacts structure
374
- 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
375
402
  3. Explore other object types (companies, tickets, etc.) as needed to understand available data`,
376
- 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
377
- 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
378
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`
379
406
  }
380
407
  });
@@ -408,6 +435,20 @@ var HUBSPOT_OBJECT_TYPES = [
408
435
  { value: "meetings", label: "Meetings" },
409
436
  { value: "tasks", label: "Tasks" }
410
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
+ }
411
452
  async function listProperties(params, objectType) {
412
453
  const res = await apiFetch(params, `/crm/v3/properties/${objectType}`);
413
454
  if (!res.ok) {
@@ -452,7 +493,9 @@ var hubspotSetupFlow = {
452
493
  });
453
494
  const sections = ["## HubSpot", ""];
454
495
  for (const objectType of targetObjectTypes) {
455
- 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, "");
456
499
  const props = await listProperties(rt.params, objectType);
457
500
  const limited = props.slice(0, HUBSPOT_SETUP_MAX_PROPERTIES);
458
501
  sections.push("| Property | Type | Label |");
@@ -568,7 +611,7 @@ var hubspotConnector = new ConnectorPlugin({
568
611
  systemPrompt: {
569
612
  en: `### Tools
570
613
 
571
- - \`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.
572
615
 
573
616
  ### Business Logic
574
617
 
@@ -634,7 +677,7 @@ export default async function handler(c: Context) {
634
677
  - \`after\` \u2014 Pagination offset`,
635
678
  ja: `### \u30C4\u30FC\u30EB
636
679
 
637
- - \`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
638
681
 
639
682
  ### Business Logic
640
683