@squadbase/vite-server 0.1.17-dev.a9ddcfa → 0.1.17-dev.e4768d1
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 +8941 -3700
- package/dist/connectors/airtable-oauth.js +87 -23
- package/dist/connectors/airtable.js +130 -23
- package/dist/connectors/amplitude.js +47 -23
- package/dist/connectors/anthropic.js +41 -17
- package/dist/connectors/asana.js +76 -25
- package/dist/connectors/attio.js +69 -28
- package/dist/connectors/aws-billing.js +47 -23
- package/dist/connectors/azure-sql.js +322 -25
- package/dist/connectors/backlog-api-key.js +79 -30
- package/dist/connectors/clickup.js +89 -25
- package/dist/connectors/cosmosdb.js +51 -27
- package/dist/connectors/customerio.js +47 -23
- package/dist/connectors/dbt.js +725 -40
- package/dist/connectors/freshdesk.js +121 -23
- package/dist/connectors/freshsales.js +47 -23
- package/dist/connectors/freshservice.js +47 -23
- package/dist/connectors/gamma.js +54 -30
- package/dist/connectors/gemini.js +41 -17
- package/dist/connectors/github.js +51 -27
- package/dist/connectors/gmail-oauth.js +42 -23
- package/dist/connectors/gmail.js +43 -19
- package/dist/connectors/google-ads.js +47 -23
- package/dist/connectors/google-analytics-oauth.js +191 -40
- package/dist/connectors/google-analytics.js +529 -111
- package/dist/connectors/google-audit-log.js +43 -19
- package/dist/connectors/google-calendar-oauth.js +100 -30
- package/dist/connectors/google-calendar.js +100 -26
- package/dist/connectors/google-docs.js +42 -23
- package/dist/connectors/google-drive.js +64 -23
- package/dist/connectors/google-search-console-oauth.js +165 -32
- package/dist/connectors/google-sheets.js +142 -199
- package/dist/connectors/google-slides.js +42 -23
- package/dist/connectors/grafana.js +84 -25
- package/dist/connectors/hackernews.d.ts +5 -0
- package/dist/connectors/hackernews.js +909 -0
- package/dist/connectors/hubspot-oauth.js +73 -22
- package/dist/connectors/hubspot.js +64 -24
- package/dist/connectors/influxdb.js +47 -23
- package/dist/connectors/intercom-oauth.js +104 -25
- package/dist/connectors/intercom.js +51 -27
- package/dist/connectors/jdbc.js +76 -25
- package/dist/connectors/jira-api-key.js +107 -26
- package/dist/connectors/kintone-api-token.js +105 -33
- package/dist/connectors/kintone.js +182 -26
- package/dist/connectors/linear.js +93 -27
- package/dist/connectors/linkedin-ads.js +80 -29
- package/dist/connectors/mailchimp-oauth.js +45 -21
- package/dist/connectors/mailchimp.js +45 -21
- package/dist/connectors/meta-ads-oauth.js +72 -29
- package/dist/connectors/meta-ads.js +74 -29
- package/dist/connectors/mixpanel.js +47 -23
- package/dist/connectors/monday.js +48 -24
- package/dist/connectors/mongodb.js +47 -23
- package/dist/connectors/notion-oauth.js +92 -24
- package/dist/connectors/notion.js +144 -26
- package/dist/connectors/openai.js +41 -17
- package/dist/connectors/oracle.js +316 -26
- package/dist/connectors/outlook-oauth.js +53 -34
- package/dist/connectors/powerbi-oauth.js +45 -26
- package/dist/connectors/salesforce.js +150 -24
- package/dist/connectors/semrush.js +45 -21
- package/dist/connectors/sentry.js +75 -25
- package/dist/connectors/shopify-oauth.js +75 -23
- package/dist/connectors/shopify.js +47 -23
- package/dist/connectors/sqlserver.js +322 -25
- package/dist/connectors/stripe-api-key.js +105 -30
- package/dist/connectors/stripe-oauth.js +102 -32
- package/dist/connectors/supabase.js +315 -21
- package/dist/connectors/tableau.js +54 -30
- package/dist/connectors/tiktok-ads.js +76 -31
- package/dist/connectors/wix-store.js +47 -23
- package/dist/connectors/x.d.ts +5 -0
- package/dist/connectors/x.js +951 -0
- package/dist/connectors/zendesk-oauth.js +87 -25
- package/dist/connectors/zendesk.js +51 -27
- package/dist/index.js +9005 -3709
- package/dist/main.js +9005 -3709
- package/dist/vite-plugin.js +8939 -3698
- package/package.json +12 -4
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2
|
-
var __esm = (fn, res) => function __init() {
|
|
3
|
-
|
|
2
|
+
var __esm = (fn, res, err) => function __init() {
|
|
3
|
+
if (err) throw err[0];
|
|
4
|
+
try {
|
|
5
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
+
} catch (e) {
|
|
7
|
+
throw err = [e], e;
|
|
8
|
+
}
|
|
4
9
|
};
|
|
5
10
|
|
|
6
11
|
// ../connectors/src/parameter-definition.ts
|
|
@@ -223,6 +228,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
223
228
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
224
229
|
*/
|
|
225
230
|
setup;
|
|
231
|
+
/**
|
|
232
|
+
* 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
|
|
233
|
+
* メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
|
|
234
|
+
* {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
|
|
235
|
+
* 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
|
|
236
|
+
* `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
|
|
237
|
+
* coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
|
|
238
|
+
*/
|
|
239
|
+
introspect;
|
|
226
240
|
/**
|
|
227
241
|
* Opt-out of the default "verify before save" behavior on connection
|
|
228
242
|
* creation. The backend invokes `checkConnection` synchronously while
|
|
@@ -237,6 +251,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
237
251
|
* the default verify-on-create behavior without opt-in.
|
|
238
252
|
*/
|
|
239
253
|
skipConnectionCheckOnCreate;
|
|
254
|
+
/**
|
|
255
|
+
* 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
|
|
256
|
+
* read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
|
|
257
|
+
* recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
|
|
258
|
+
* driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
|
|
259
|
+
* 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
|
|
260
|
+
*/
|
|
261
|
+
surveyProbes;
|
|
240
262
|
constructor(config) {
|
|
241
263
|
this.slug = config.slug;
|
|
242
264
|
this.authType = config.authType;
|
|
@@ -254,7 +276,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
254
276
|
this.query = config.query;
|
|
255
277
|
this.checkConnection = config.checkConnection;
|
|
256
278
|
this.setup = config.setup;
|
|
279
|
+
this.introspect = config.introspect;
|
|
257
280
|
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
281
|
+
this.surveyProbes = config.surveyProbes;
|
|
258
282
|
}
|
|
259
283
|
get connectorKey() {
|
|
260
284
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -262,7 +286,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
262
286
|
/**
|
|
263
287
|
* Create tools for connections that belong to this connector.
|
|
264
288
|
* Filters connections by connectorKey internally.
|
|
265
|
-
* Returns tools keyed as
|
|
289
|
+
* Returns tools keyed as `connector_${connectorKey}_${toolName}`.
|
|
266
290
|
*/
|
|
267
291
|
createTools(connections, config, opts) {
|
|
268
292
|
const myConnections = connections.filter(
|
|
@@ -272,7 +296,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
272
296
|
for (const t of Object.values(this.tools)) {
|
|
273
297
|
const tool = t.createTool(myConnections, config);
|
|
274
298
|
const originalToModelOutput = tool.toModelOutput;
|
|
275
|
-
result[
|
|
299
|
+
result[`connector_${this.connectorKey}_${t.name}`] = {
|
|
276
300
|
...tool,
|
|
277
301
|
toModelOutput: async (options) => {
|
|
278
302
|
if (!originalToModelOutput) {
|
|
@@ -292,25 +316,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
292
316
|
if (authType) return `${slug}-${authType}`;
|
|
293
317
|
const LEGACY_NULL_AUTH_TYPE_MAP = {
|
|
294
318
|
// user-password
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
319
|
+
postgresql: "user-password",
|
|
320
|
+
mysql: "user-password",
|
|
321
|
+
clickhouse: "user-password",
|
|
322
|
+
kintone: "user-password",
|
|
299
323
|
"squadbase-db": "user-password",
|
|
300
324
|
// service-account
|
|
301
|
-
|
|
302
|
-
|
|
325
|
+
snowflake: "service-account",
|
|
326
|
+
bigquery: "service-account",
|
|
303
327
|
"google-analytics": "service-account",
|
|
304
328
|
"google-calendar": "service-account",
|
|
305
329
|
"aws-athena": "service-account",
|
|
306
|
-
|
|
330
|
+
redshift: "service-account",
|
|
307
331
|
// api-key
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
332
|
+
databricks: "api-key",
|
|
333
|
+
dbt: "api-key",
|
|
334
|
+
airtable: "api-key",
|
|
335
|
+
openai: "api-key",
|
|
336
|
+
gemini: "api-key",
|
|
337
|
+
anthropic: "api-key",
|
|
314
338
|
"wix-store": "api-key"
|
|
315
339
|
};
|
|
316
340
|
const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
|
|
@@ -389,6 +413,24 @@ async function resolveSetupSelection(params) {
|
|
|
389
413
|
return resolved.slice(0, limit);
|
|
390
414
|
}
|
|
391
415
|
|
|
416
|
+
// ../connectors/src/introspect-concurrency.ts
|
|
417
|
+
async function mapWithConcurrency(items, limit, fn) {
|
|
418
|
+
const results = new Array(items.length);
|
|
419
|
+
let next = 0;
|
|
420
|
+
const workers = Array.from(
|
|
421
|
+
{ length: Math.min(Math.max(limit, 1), items.length) },
|
|
422
|
+
async () => {
|
|
423
|
+
for (; ; ) {
|
|
424
|
+
const i = next++;
|
|
425
|
+
if (i >= items.length) return;
|
|
426
|
+
results[i] = await fn(items[i]);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
);
|
|
430
|
+
await Promise.all(workers);
|
|
431
|
+
return results;
|
|
432
|
+
}
|
|
433
|
+
|
|
392
434
|
// ../connectors/src/auth-types.ts
|
|
393
435
|
var AUTH_TYPES = {
|
|
394
436
|
OAUTH: "oauth",
|
|
@@ -402,12 +444,12 @@ var AUTH_TYPES = {
|
|
|
402
444
|
// ../connectors/src/connectors/kintone/setup.ts
|
|
403
445
|
var kintoneOnboarding = new ConnectorOnboarding({
|
|
404
446
|
dataOverviewInstructions: {
|
|
405
|
-
en: `1. Call
|
|
406
|
-
2. For key apps, call
|
|
407
|
-
3. Call
|
|
408
|
-
ja: `1.
|
|
409
|
-
2. \u4E3B\u8981\u30A2\u30D7\u30EA\u306B\u3064\u3044\u3066
|
|
410
|
-
3.
|
|
447
|
+
en: `1. Call connector_kintone_request with GET apps.json to list available apps
|
|
448
|
+
2. For key apps, call connector_kintone_request with GET app/form/fields.json?app={appId} to get field definitions
|
|
449
|
+
3. Call connector_kintone_request with GET records.json?app={appId}&query=limit 5 to sample records`,
|
|
450
|
+
ja: `1. connector_kintone_request \u3067 GET apps.json \u3092\u547C\u3073\u51FA\u3057\u3001\u5229\u7528\u53EF\u80FD\u306A\u30A2\u30D7\u30EA\u4E00\u89A7\u3092\u53D6\u5F97
|
|
451
|
+
2. \u4E3B\u8981\u30A2\u30D7\u30EA\u306B\u3064\u3044\u3066 connector_kintone_request \u3067 GET app/form/fields.json?app={appId} \u3092\u547C\u3073\u51FA\u3057\u3001\u30D5\u30A3\u30FC\u30EB\u30C9\u5B9A\u7FA9\u3092\u53D6\u5F97
|
|
452
|
+
3. connector_kintone_request \u3067 GET records.json?app={appId}&query=limit 5 \u3092\u547C\u3073\u51FA\u3057\u3001\u30EC\u30B3\u30FC\u30C9\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0`
|
|
411
453
|
}
|
|
412
454
|
});
|
|
413
455
|
|
|
@@ -435,6 +477,7 @@ async function apiFetch(params, path2, init) {
|
|
|
435
477
|
// ../connectors/src/connectors/kintone/setup-flow.ts
|
|
436
478
|
var ALL_APPS = "__ALL_APPS__";
|
|
437
479
|
var KINTONE_SETUP_MAX_APPS = 20;
|
|
480
|
+
var SAMPLE_RECORD_LIMIT = 5;
|
|
438
481
|
async function listApps(params) {
|
|
439
482
|
const results = [];
|
|
440
483
|
let offset = 0;
|
|
@@ -468,6 +511,25 @@ async function getFormFields(params, appId) {
|
|
|
468
511
|
}
|
|
469
512
|
return await res.json();
|
|
470
513
|
}
|
|
514
|
+
async function getSampleRecords(params, appId) {
|
|
515
|
+
try {
|
|
516
|
+
const res = await apiFetch(
|
|
517
|
+
params,
|
|
518
|
+
`records.json?app=${encodeURIComponent(appId)}&query=${encodeURIComponent(`limit ${SAMPLE_RECORD_LIMIT}`)}&totalCount=true`
|
|
519
|
+
);
|
|
520
|
+
if (!res.ok) return { records: [], totalCount: null };
|
|
521
|
+
return await res.json();
|
|
522
|
+
} catch {
|
|
523
|
+
return { records: [], totalCount: null };
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
function formatRecordValue(val) {
|
|
527
|
+
if (val == null) return "";
|
|
528
|
+
if (typeof val === "string") return val.length > 50 ? `${val.slice(0, 50)}\u2026` : val;
|
|
529
|
+
if (Array.isArray(val)) return `[${val.length} items]`;
|
|
530
|
+
if (typeof val === "object") return JSON.stringify(val).slice(0, 50);
|
|
531
|
+
return String(val);
|
|
532
|
+
}
|
|
471
533
|
var kintoneSetupFlow = {
|
|
472
534
|
initialState: () => ({}),
|
|
473
535
|
steps: [
|
|
@@ -513,20 +575,82 @@ var kintoneSetupFlow = {
|
|
|
513
575
|
sections.push(app.description, "");
|
|
514
576
|
}
|
|
515
577
|
const fields = await getFormFields(rt.params, appId);
|
|
578
|
+
const fieldEntries = Object.entries(fields.properties ?? {});
|
|
516
579
|
sections.push("| Field code | Label | Type | Required |");
|
|
517
580
|
sections.push("|------------|-------|------|----------|");
|
|
518
|
-
for (const [code, def] of
|
|
581
|
+
for (const [code, def] of fieldEntries) {
|
|
519
582
|
const escapedLabel = (def.label ?? "").replace(/\|/g, "\\|");
|
|
520
583
|
sections.push(
|
|
521
584
|
`| ${code} | ${escapedLabel || "-"} | ${def.type} | ${def.required ? "yes" : "no"} |`
|
|
522
585
|
);
|
|
523
586
|
}
|
|
524
587
|
sections.push("");
|
|
588
|
+
const sampleData = await getSampleRecords(rt.params, appId);
|
|
589
|
+
const totalCount = sampleData.totalCount ? Number(sampleData.totalCount) : null;
|
|
590
|
+
if (totalCount != null) {
|
|
591
|
+
sections.push(`#### Record count: ${totalCount.toLocaleString()}`, "");
|
|
592
|
+
}
|
|
593
|
+
const records = sampleData.records ?? [];
|
|
594
|
+
if (records.length > 0) {
|
|
595
|
+
const sampleFields = fieldEntries.slice(0, 8).map(([code]) => code);
|
|
596
|
+
if (sampleFields.length > 0) {
|
|
597
|
+
sections.push(`#### Sample records (${records.length})`, "");
|
|
598
|
+
sections.push(`| ${sampleFields.join(" | ")} |`);
|
|
599
|
+
sections.push(`| ${sampleFields.map(() => "---").join(" | ")} |`);
|
|
600
|
+
for (const record of records) {
|
|
601
|
+
const cells = sampleFields.map((code) => {
|
|
602
|
+
const cell = record[code];
|
|
603
|
+
return formatRecordValue(cell?.value).replace(/\|/g, "\\|");
|
|
604
|
+
});
|
|
605
|
+
sections.push(`| ${cells.join(" | ")} |`);
|
|
606
|
+
}
|
|
607
|
+
sections.push("");
|
|
608
|
+
}
|
|
609
|
+
}
|
|
525
610
|
}
|
|
526
611
|
return sections.join("\n");
|
|
527
612
|
}
|
|
528
613
|
};
|
|
529
614
|
|
|
615
|
+
// ../connectors/src/connectors/kintone/introspect.ts
|
|
616
|
+
var MAX_APPS = 100;
|
|
617
|
+
var CONCURRENCY = 5;
|
|
618
|
+
async function introspectKintone(ctx) {
|
|
619
|
+
const appsRes = await apiFetch(ctx.params, "apps.json");
|
|
620
|
+
if (!appsRes.ok) {
|
|
621
|
+
throw new Error(`kintone: apps.json failed (${appsRes.status})`);
|
|
622
|
+
}
|
|
623
|
+
const appsData = await appsRes.json();
|
|
624
|
+
const apps = (appsData.apps ?? []).slice(0, MAX_APPS);
|
|
625
|
+
const tables = (await mapWithConcurrency(apps, CONCURRENCY, async (app) => {
|
|
626
|
+
try {
|
|
627
|
+
const res = await apiFetch(
|
|
628
|
+
ctx.params,
|
|
629
|
+
`app/form/fields.json?app=${encodeURIComponent(app.appId)}`
|
|
630
|
+
);
|
|
631
|
+
if (!res.ok) return [];
|
|
632
|
+
const data = await res.json();
|
|
633
|
+
const columns = Object.values(
|
|
634
|
+
data.properties ?? {}
|
|
635
|
+
).filter((f) => f.code || f.label).map((f) => ({
|
|
636
|
+
name: f.code || f.label || "",
|
|
637
|
+
dataType: f.type ?? "UNKNOWN",
|
|
638
|
+
nullable: f.required !== true
|
|
639
|
+
}));
|
|
640
|
+
const table = {
|
|
641
|
+
schema: String(app.appId),
|
|
642
|
+
name: app.name,
|
|
643
|
+
type: "table",
|
|
644
|
+
columns
|
|
645
|
+
};
|
|
646
|
+
return [table];
|
|
647
|
+
} catch {
|
|
648
|
+
return [];
|
|
649
|
+
}
|
|
650
|
+
})).flat();
|
|
651
|
+
return { tables };
|
|
652
|
+
}
|
|
653
|
+
|
|
530
654
|
// ../connectors/src/connectors/kintone/tools/request.ts
|
|
531
655
|
import { z } from "zod";
|
|
532
656
|
var REQUEST_TIMEOUT_MS = 6e4;
|
|
@@ -614,7 +738,7 @@ var kintoneConnector = new ConnectorPlugin({
|
|
|
614
738
|
systemPrompt: {
|
|
615
739
|
en: `### Tools
|
|
616
740
|
|
|
617
|
-
- \`
|
|
741
|
+
- \`connector_kintone_request\`: The only way to call the kintone REST API. Use it to list apps, fetch field definitions, and read/write records. The base URL (e.g., \`https://example.cybozu.com\`) is automatically resolved. See the kintone REST API Reference below for endpoints and the kintone query syntax.
|
|
618
742
|
|
|
619
743
|
### Business Logic
|
|
620
744
|
|
|
@@ -681,7 +805,7 @@ export default async function handler(c: Context) {
|
|
|
681
805
|
- String: \`like "partial match"\``,
|
|
682
806
|
ja: `### \u30C4\u30FC\u30EB
|
|
683
807
|
|
|
684
|
-
- \`
|
|
808
|
+
- \`connector_kintone_request\`: kintone REST API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002\u30A2\u30D7\u30EA\u4E00\u89A7\u306E\u53D6\u5F97\u3001\u30D5\u30A3\u30FC\u30EB\u30C9\u5B9A\u7FA9\u306E\u53D6\u5F97\u3001\u30EC\u30B3\u30FC\u30C9\u306E\u8AAD\u307F\u66F8\u304D\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u30D9\u30FC\u30B9URL\uFF08\u4F8B: \`https://example.cybozu.com\`\uFF09\u306F\u81EA\u52D5\u7684\u306B\u89E3\u6C7A\u3055\u308C\u307E\u3059\u3002\u30A8\u30F3\u30C9\u30DD\u30A4\u30F3\u30C8\u304A\u3088\u3073kintone\u30AF\u30A8\u30EA\u69CB\u6587\u306F\u4E0B\u90E8\u306E\u300Ckintone REST API \u30EA\u30D5\u30A1\u30EC\u30F3\u30B9\u300D\u3092\u53C2\u7167\u3057\u3066\u304F\u3060\u3055\u3044\u3002
|
|
685
809
|
|
|
686
810
|
### Business Logic
|
|
687
811
|
|
|
@@ -748,6 +872,38 @@ export default async function handler(c: Context) {
|
|
|
748
872
|
- \u6587\u5B57\u5217: \`like "\u90E8\u5206\u4E00\u81F4"\``
|
|
749
873
|
},
|
|
750
874
|
tools,
|
|
875
|
+
// 決定論的な立ち上げ survey(ルールベース prewarm)。round1: `apps.json` でアプリ一覧 → round2: 先頭アプリの
|
|
876
|
+
// フィールド定義を read-only GET(kintone の「テーブル」= アプリ)。
|
|
877
|
+
surveyProbes: (_connectionId, prior) => {
|
|
878
|
+
if (prior.length === 0) {
|
|
879
|
+
return [
|
|
880
|
+
{
|
|
881
|
+
tool: "request",
|
|
882
|
+
input: {
|
|
883
|
+
method: "GET",
|
|
884
|
+
path: "apps.json",
|
|
885
|
+
toolUseIntent: "List kintone apps"
|
|
886
|
+
}
|
|
887
|
+
}
|
|
888
|
+
];
|
|
889
|
+
}
|
|
890
|
+
if (prior.length === 1) {
|
|
891
|
+
const out = prior[0]?.output;
|
|
892
|
+
const apps = out?.success !== false ? out?.data?.apps ?? [] : [];
|
|
893
|
+
return apps.map((a) => a.appId).filter(
|
|
894
|
+
(id) => typeof id === "string" || typeof id === "number"
|
|
895
|
+
).slice(0, 3).map((appId) => ({
|
|
896
|
+
tool: "request",
|
|
897
|
+
input: {
|
|
898
|
+
method: "GET",
|
|
899
|
+
path: `app/form/fields.json?app=${appId}`,
|
|
900
|
+
toolUseIntent: `Fields for app ${appId}`
|
|
901
|
+
}
|
|
902
|
+
}));
|
|
903
|
+
}
|
|
904
|
+
return [];
|
|
905
|
+
},
|
|
906
|
+
introspect: (ctx) => introspectKintone(ctx),
|
|
751
907
|
setup: (params, ctx, config) => runSetupFlow(kintoneSetupFlow, params, ctx, config),
|
|
752
908
|
async checkConnection(params, _config) {
|
|
753
909
|
const baseUrl = params[parameters.baseUrl.slug];
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
2
|
-
var __esm = (fn, res) => function __init() {
|
|
3
|
-
|
|
2
|
+
var __esm = (fn, res, err) => function __init() {
|
|
3
|
+
if (err) throw err[0];
|
|
4
|
+
try {
|
|
5
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
6
|
+
} catch (e) {
|
|
7
|
+
throw err = [e], e;
|
|
8
|
+
}
|
|
4
9
|
};
|
|
5
10
|
|
|
6
11
|
// ../connectors/src/parameter-definition.ts
|
|
@@ -229,6 +234,15 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
229
234
|
* `runSetupFlow` from `setup-flow.ts`.
|
|
230
235
|
*/
|
|
231
236
|
setup;
|
|
237
|
+
/**
|
|
238
|
+
* 統一 introspection。SQL DB の `information_schema` / `SHOW` / `DESCRIBE` や SaaS の
|
|
239
|
+
* メタデータ API といった取得経路の差を吸収し、tables / columns / PK / FK を共通型
|
|
240
|
+
* {@link IntrospectedSchema} へ正規化して返す。取得経路は {@link IntrospectContext} で
|
|
241
|
+
* 抽象化され、SQL DB は `ctx.query`、SaaS は `ctx.proxyFetch` + `ctx.params` を使う。
|
|
242
|
+
* `ctx.profile === true` のときは L2 プロファイル(行数・NULL 率等)も best-effort で埋める。
|
|
243
|
+
* coding-agent の `DataContextIndex` がデータ地図を構築する際に使う。
|
|
244
|
+
*/
|
|
245
|
+
introspect;
|
|
232
246
|
/**
|
|
233
247
|
* Opt-out of the default "verify before save" behavior on connection
|
|
234
248
|
* creation. The backend invokes `checkConnection` synchronously while
|
|
@@ -243,6 +257,14 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
243
257
|
* the default verify-on-create behavior without opt-in.
|
|
244
258
|
*/
|
|
245
259
|
skipConnectionCheckOnCreate;
|
|
260
|
+
/**
|
|
261
|
+
* 決定論的な「立ち上げ survey」レシピ(ルールベース prewarm 基盤)。実装した connector は、LLM を使わずに
|
|
262
|
+
* read-only で自分を survey する probe 列(テーブル/列メタデータ → 小サンプル)を宣言する。coding-agent の
|
|
263
|
+
* recon driver がこれを読み、connector ツールの `execute` を直接呼んで結果を seed にする。未実装の connector は
|
|
264
|
+
* driver 側で safely skip される(その connection は listConnections のみ seed)。標準 `information_schema` を
|
|
265
|
+
* 持つ SQL connector は `makeStandardSqlSurveyProbes` を使える。**probe は必ず read-only**。
|
|
266
|
+
*/
|
|
267
|
+
surveyProbes;
|
|
246
268
|
constructor(config) {
|
|
247
269
|
this.slug = config.slug;
|
|
248
270
|
this.authType = config.authType;
|
|
@@ -260,7 +282,9 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
260
282
|
this.query = config.query;
|
|
261
283
|
this.checkConnection = config.checkConnection;
|
|
262
284
|
this.setup = config.setup;
|
|
285
|
+
this.introspect = config.introspect;
|
|
263
286
|
this.skipConnectionCheckOnCreate = config.skipConnectionCheckOnCreate;
|
|
287
|
+
this.surveyProbes = config.surveyProbes;
|
|
264
288
|
}
|
|
265
289
|
get connectorKey() {
|
|
266
290
|
return _ConnectorPlugin.deriveKey(this.slug, this.authType);
|
|
@@ -268,7 +292,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
268
292
|
/**
|
|
269
293
|
* Create tools for connections that belong to this connector.
|
|
270
294
|
* Filters connections by connectorKey internally.
|
|
271
|
-
* Returns tools keyed as
|
|
295
|
+
* Returns tools keyed as `connector_${connectorKey}_${toolName}`.
|
|
272
296
|
*/
|
|
273
297
|
createTools(connections, config, opts) {
|
|
274
298
|
const myConnections = connections.filter(
|
|
@@ -278,7 +302,7 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
278
302
|
for (const t of Object.values(this.tools)) {
|
|
279
303
|
const tool = t.createTool(myConnections, config);
|
|
280
304
|
const originalToModelOutput = tool.toModelOutput;
|
|
281
|
-
result[
|
|
305
|
+
result[`connector_${this.connectorKey}_${t.name}`] = {
|
|
282
306
|
...tool,
|
|
283
307
|
toModelOutput: async (options) => {
|
|
284
308
|
if (!originalToModelOutput) {
|
|
@@ -298,25 +322,25 @@ var ConnectorPlugin = class _ConnectorPlugin {
|
|
|
298
322
|
if (authType) return `${slug}-${authType}`;
|
|
299
323
|
const LEGACY_NULL_AUTH_TYPE_MAP = {
|
|
300
324
|
// user-password
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
325
|
+
postgresql: "user-password",
|
|
326
|
+
mysql: "user-password",
|
|
327
|
+
clickhouse: "user-password",
|
|
328
|
+
kintone: "user-password",
|
|
305
329
|
"squadbase-db": "user-password",
|
|
306
330
|
// service-account
|
|
307
|
-
|
|
308
|
-
|
|
331
|
+
snowflake: "service-account",
|
|
332
|
+
bigquery: "service-account",
|
|
309
333
|
"google-analytics": "service-account",
|
|
310
334
|
"google-calendar": "service-account",
|
|
311
335
|
"aws-athena": "service-account",
|
|
312
|
-
|
|
336
|
+
redshift: "service-account",
|
|
313
337
|
// api-key
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
338
|
+
databricks: "api-key",
|
|
339
|
+
dbt: "api-key",
|
|
340
|
+
airtable: "api-key",
|
|
341
|
+
openai: "api-key",
|
|
342
|
+
gemini: "api-key",
|
|
343
|
+
anthropic: "api-key",
|
|
320
344
|
"wix-store": "api-key"
|
|
321
345
|
};
|
|
322
346
|
const fallbackAuthType = LEGACY_NULL_AUTH_TYPE_MAP[slug];
|
|
@@ -408,15 +432,15 @@ var AUTH_TYPES = {
|
|
|
408
432
|
// ../connectors/src/connectors/linear/setup.ts
|
|
409
433
|
var linearOnboarding = new ConnectorOnboarding({
|
|
410
434
|
dataOverviewInstructions: {
|
|
411
|
-
en: `1. Call
|
|
412
|
-
2. Call
|
|
413
|
-
3. Call
|
|
414
|
-
4. Call
|
|
435
|
+
en: `1. Call connector_linear_request with query \`{ teams { nodes { id name } } }\` to list all teams
|
|
436
|
+
2. Call connector_linear_request with query \`{ workflowStates { nodes { id name type } } }\` to list workflow states
|
|
437
|
+
3. Call connector_linear_request with query \`{ issues(first: 5, orderBy: updatedAt) { nodes { id identifier title state { name } assignee { name } priority } } }\` to sample recent issues
|
|
438
|
+
4. Call connector_linear_request with query \`{ projects(first: 5) { nodes { id name state } } }\` to list projects
|
|
415
439
|
5. Explore other resources (cycles, labels, users) as needed`,
|
|
416
|
-
ja: `1.
|
|
417
|
-
2.
|
|
418
|
-
3.
|
|
419
|
-
4.
|
|
440
|
+
ja: `1. connector_linear_request \u3067\u30AF\u30A8\u30EA \`{ teams { nodes { id name } } }\` \u3092\u547C\u3073\u51FA\u3057\u3001\u30C1\u30FC\u30E0\u4E00\u89A7\u3092\u53D6\u5F97
|
|
441
|
+
2. connector_linear_request \u3067\u30AF\u30A8\u30EA \`{ workflowStates { nodes { id name type } } }\` \u3092\u547C\u3073\u51FA\u3057\u3001\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u72B6\u614B\u4E00\u89A7\u3092\u53D6\u5F97
|
|
442
|
+
3. connector_linear_request \u3067\u30AF\u30A8\u30EA \`{ issues(first: 5, orderBy: updatedAt) { nodes { id identifier title state { name } assignee { name } priority } } }\` \u3092\u547C\u3073\u51FA\u3057\u3001\u6700\u8FD1\u306EIssue\u3092\u30B5\u30F3\u30D7\u30EA\u30F3\u30B0
|
|
443
|
+
4. connector_linear_request \u3067\u30AF\u30A8\u30EA \`{ projects(first: 5) { nodes { id name state } } }\` \u3092\u547C\u3073\u51FA\u3057\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u4E00\u89A7\u3092\u53D6\u5F97
|
|
420
444
|
5. \u5FC5\u8981\u306B\u5FDC\u3058\u3066\u4ED6\u306E\u30EA\u30BD\u30FC\u30B9\uFF08cycles\u3001labels\u3001users\uFF09\u3092\u63A2\u7D22`
|
|
421
445
|
}
|
|
422
446
|
});
|
|
@@ -473,6 +497,35 @@ async function getTeamDetail(params, teamId) {
|
|
|
473
497
|
);
|
|
474
498
|
return data.team ?? null;
|
|
475
499
|
}
|
|
500
|
+
async function getIssueBreakdown(params, teamId) {
|
|
501
|
+
try {
|
|
502
|
+
const data = await gqlFetch(
|
|
503
|
+
params,
|
|
504
|
+
`query($id: String!) {
|
|
505
|
+
team(id: $id) {
|
|
506
|
+
issues(first: 250) { nodes { state { name type } } }
|
|
507
|
+
}
|
|
508
|
+
}`,
|
|
509
|
+
{ id: teamId }
|
|
510
|
+
);
|
|
511
|
+
const nodes = data.team?.issues?.nodes ?? [];
|
|
512
|
+
const counts = /* @__PURE__ */ new Map();
|
|
513
|
+
for (const n of nodes) {
|
|
514
|
+
const key = `${n.state?.name ?? "Unknown"}|${n.state?.type ?? "unknown"}`;
|
|
515
|
+
const existing = counts.get(key);
|
|
516
|
+
if (existing) existing.count++;
|
|
517
|
+
else
|
|
518
|
+
counts.set(key, {
|
|
519
|
+
stateName: n.state?.name ?? "Unknown",
|
|
520
|
+
stateType: n.state?.type ?? "unknown",
|
|
521
|
+
count: 1
|
|
522
|
+
});
|
|
523
|
+
}
|
|
524
|
+
return { total: nodes.length, byState: Array.from(counts.values()) };
|
|
525
|
+
} catch {
|
|
526
|
+
return null;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
476
529
|
var linearSetupFlow = {
|
|
477
530
|
initialState: () => ({}),
|
|
478
531
|
steps: [
|
|
@@ -529,6 +582,19 @@ var linearSetupFlow = {
|
|
|
529
582
|
sections.push(` - ${s.name} (${s.type})`);
|
|
530
583
|
}
|
|
531
584
|
sections.push("");
|
|
585
|
+
const breakdown = await getIssueBreakdown(rt.params, teamId);
|
|
586
|
+
if (breakdown && breakdown.byState.length > 0) {
|
|
587
|
+
sections.push(
|
|
588
|
+
`#### Issues (${breakdown.total}${breakdown.total === 250 ? "+" : ""})`,
|
|
589
|
+
""
|
|
590
|
+
);
|
|
591
|
+
sections.push("| State | Type | Count |");
|
|
592
|
+
sections.push("|-------|------|-------|");
|
|
593
|
+
for (const b of breakdown.byState) {
|
|
594
|
+
sections.push(`| ${b.stateName} | ${b.stateType} | ${b.count} |`);
|
|
595
|
+
}
|
|
596
|
+
sections.push("");
|
|
597
|
+
}
|
|
532
598
|
}
|
|
533
599
|
return sections.join("\n");
|
|
534
600
|
}
|
|
@@ -639,7 +705,7 @@ var linearConnector = new ConnectorPlugin({
|
|
|
639
705
|
systemPrompt: {
|
|
640
706
|
en: `### Tools
|
|
641
707
|
|
|
642
|
-
- \`
|
|
708
|
+
- \`connector_linear_request\`: The only way to call the Linear GraphQL API. Use it to query and mutate all Linear resources: issues, projects, teams, cycles, users, labels, workflow states, and comments. Authentication is configured automatically. Linear's API is GraphQL-only \u2014 send a query string and optional variables. Pagination uses Relay-style cursors with \`first\`/\`after\` and \`last\`/\`before\` arguments. Archived resources are hidden by default; pass \`includeArchived: true\` to include them.
|
|
643
709
|
|
|
644
710
|
### Business Logic
|
|
645
711
|
|
|
@@ -700,7 +766,7 @@ export default async function handler(c: Context) {
|
|
|
700
766
|
- \`mutation { commentCreate(input: { issueId: "...", body: "..." }) { success comment { id body } } }\` \u2014 add comment`,
|
|
701
767
|
ja: `### \u30C4\u30FC\u30EB
|
|
702
768
|
|
|
703
|
-
- \`
|
|
769
|
+
- \`connector_linear_request\`: Linear GraphQL API\u3092\u547C\u3073\u51FA\u3059\u552F\u4E00\u306E\u624B\u6BB5\u3067\u3059\u3002Issue\u3001\u30D7\u30ED\u30B8\u30A7\u30AF\u30C8\u3001\u30C1\u30FC\u30E0\u3001\u30B5\u30A4\u30AF\u30EB\u3001\u30E6\u30FC\u30B6\u30FC\u3001\u30E9\u30D9\u30EB\u3001\u30EF\u30FC\u30AF\u30D5\u30ED\u30FC\u72B6\u614B\u3001\u30B3\u30E1\u30F3\u30C8\u306A\u3069\u3059\u3079\u3066\u306ELinear\u30EA\u30BD\u30FC\u30B9\u306E\u30AF\u30A8\u30EA\u3068\u30DF\u30E5\u30FC\u30C6\u30FC\u30B7\u30E7\u30F3\u306B\u4F7F\u7528\u3057\u307E\u3059\u3002\u8A8D\u8A3C\u306F\u81EA\u52D5\u7684\u306B\u8A2D\u5B9A\u3055\u308C\u307E\u3059\u3002Linear\u306EAPI\u306FGraphQL\u306E\u307F\u3067\u3059\u3002\u30AF\u30A8\u30EA\u6587\u5B57\u5217\u3068\u30AA\u30D7\u30B7\u30E7\u30F3\u306E\u5909\u6570\u3092\u9001\u4FE1\u3057\u307E\u3059\u3002\u30DA\u30FC\u30B8\u30CD\u30FC\u30B7\u30E7\u30F3\u306FRelay\u5F62\u5F0F\u306E\u30AB\u30FC\u30BD\u30EB\u30D9\u30FC\u30B9\u3067\u3001\`first\`/\`after\`\u304A\u3088\u3073\`last\`/\`before\`\u5F15\u6570\u3092\u4F7F\u7528\u3057\u307E\u3059\u3002\u30A2\u30FC\u30AB\u30A4\u30D6\u3055\u308C\u305F\u30EA\u30BD\u30FC\u30B9\u306F\u30C7\u30D5\u30A9\u30EB\u30C8\u3067\u975E\u8868\u793A\u3067\u3059\u3002\`includeArchived: true\`\u3092\u6E21\u3059\u3068\u542B\u3081\u3089\u308C\u307E\u3059\u3002
|
|
704
770
|
|
|
705
771
|
### Business Logic
|
|
706
772
|
|