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