@duckcodeailabs/dql-cli 1.6.11 → 1.6.12
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/assets/dql-notebook/assets/index-McpLeeN0.js +3802 -0
- package/dist/assets/dql-notebook/index.html +1 -1
- package/dist/llm/analytics-tools.d.ts +7 -0
- package/dist/llm/analytics-tools.d.ts.map +1 -0
- package/dist/llm/analytics-tools.js +178 -0
- package/dist/llm/analytics-tools.js.map +1 -0
- package/dist/llm/index.d.ts.map +1 -1
- package/dist/llm/index.js +3 -1
- package/dist/llm/index.js.map +1 -1
- package/dist/llm/mcp-config.d.ts +43 -0
- package/dist/llm/mcp-config.d.ts.map +1 -0
- package/dist/llm/mcp-config.js +327 -0
- package/dist/llm/mcp-config.js.map +1 -0
- package/dist/llm/providers/dql-agent-provider.d.ts +1 -1
- package/dist/llm/providers/dql-agent-provider.d.ts.map +1 -1
- package/dist/llm/providers/dql-agent-provider.js +9 -1
- package/dist/llm/providers/dql-agent-provider.js.map +1 -1
- package/dist/llm/providers/native-sdk-provider.d.ts +4 -0
- package/dist/llm/providers/native-sdk-provider.d.ts.map +1 -0
- package/dist/llm/providers/native-sdk-provider.js +319 -0
- package/dist/llm/providers/native-sdk-provider.js.map +1 -0
- package/dist/llm/types.d.ts +1 -1
- package/dist/llm/types.d.ts.map +1 -1
- package/dist/local-runtime.d.ts +2 -0
- package/dist/local-runtime.d.ts.map +1 -1
- package/dist/local-runtime.js +132 -19
- package/dist/local-runtime.js.map +1 -1
- package/dist/package.json +13 -11
- package/dist/settings/provider-settings.d.ts +2 -0
- package/dist/settings/provider-settings.d.ts.map +1 -1
- package/dist/settings/provider-settings.js +49 -10
- package/dist/settings/provider-settings.js.map +1 -1
- package/package.json +14 -12
package/dist/local-runtime.js
CHANGED
|
@@ -3,14 +3,17 @@ import { createServer } from 'node:http';
|
|
|
3
3
|
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, statSync, watch, writeFileSync } from 'node:fs';
|
|
4
4
|
import { homedir } from 'node:os';
|
|
5
5
|
import { dirname, extname, join, normalize, relative, resolve } from 'node:path';
|
|
6
|
+
import Anthropic from '@anthropic-ai/sdk';
|
|
7
|
+
import OpenAI from 'openai';
|
|
6
8
|
import { buildExecutionPlan, createWelcomeNotebook, deserializeNotebook, getConnectorFormSchemas, hasSemanticRefs, resolveSemanticRefs, } from '@duckcodeailabs/dql-notebook';
|
|
7
9
|
import { loadSemanticLayerFromDir, resolveSemanticLayerAsync, getDialect, Parser, buildLineageGraph, buildManifest, findAppDocuments, findDashboardsForApp, isBlockIdRef, loadAppDocument, loadDashboardDocument, analyzeImpact, buildTrustChain, detectDomainFlows, getDomainTrustOverview, queryLineage, queryCompleteLineagePaths, LineageGraph, canonicalize, canonicalizeNotebook, diffDQL, diffNotebook, } from '@duckcodeailabs/dql-core';
|
|
8
10
|
import { load as loadYaml } from 'js-yaml';
|
|
9
11
|
import { listBlockTemplates } from './block-templates.js';
|
|
10
12
|
import { getRunner as getLLMRunner } from './llm/index.js';
|
|
13
|
+
import { listRemoteMcpSettings, saveRemoteMcpSettings } from './llm/mcp-config.js';
|
|
11
14
|
import { ClaudeProvider, GeminiProvider, MemoryStore, OllamaProvider, OpenAIProvider, buildLocalContextPack, defaultMemoryPath, ensureDefaultMemoryFiles, ensureMetadataCatalogFresh, recordRuntimeSchemaSnapshot, } from '@duckcodeailabs/dql-agent';
|
|
12
15
|
import { handleAppsApi } from './apps-api.js';
|
|
13
|
-
import { getEffectiveProviderConfig, listProviderSettings, saveProviderSettings, } from './settings/provider-settings.js';
|
|
16
|
+
import { getActiveProvider, getEffectiveProviderConfig, listProviderSettings, saveProviderSettings, } from './settings/provider-settings.js';
|
|
14
17
|
import { DQLAccessDeniedError, activePersonaAppId, assertAppAccess, loadRuntimeApp, runtimeVariables, } from './governance-runtime.js';
|
|
15
18
|
import { LocalAppStorage, defaultLocalAppsDbPath } from '@duckcodeailabs/dql-project';
|
|
16
19
|
import { Certifier } from '@duckcodeailabs/dql-governance';
|
|
@@ -606,6 +609,24 @@ export async function startLocalServer(opts) {
|
|
|
606
609
|
}
|
|
607
610
|
return;
|
|
608
611
|
}
|
|
612
|
+
if (req.method === 'GET' && path === '/api/settings/mcp') {
|
|
613
|
+
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
614
|
+
res.end(serializeJSON({ settings: listRemoteMcpSettings(projectRoot) }));
|
|
615
|
+
return;
|
|
616
|
+
}
|
|
617
|
+
if (req.method === 'POST' && path === '/api/settings/mcp') {
|
|
618
|
+
try {
|
|
619
|
+
const body = await readJSON(req);
|
|
620
|
+
const settings = saveRemoteMcpSettings(projectRoot, { entries: body?.entries });
|
|
621
|
+
res.writeHead(200, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
622
|
+
res.end(serializeJSON({ ok: true, settings }));
|
|
623
|
+
}
|
|
624
|
+
catch (error) {
|
|
625
|
+
res.writeHead(500, { 'Content-Type': 'application/json; charset=utf-8' });
|
|
626
|
+
res.end(serializeJSON({ ok: false, error: error instanceof Error ? error.message : String(error) }));
|
|
627
|
+
}
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
609
630
|
if (req.method === 'GET' && path === '/api/agent/memory') {
|
|
610
631
|
const memory = new MemoryStore(defaultMemoryPath(projectRoot));
|
|
611
632
|
try {
|
|
@@ -3465,16 +3486,23 @@ function normalizeQueryResult(result, semanticRefs) {
|
|
|
3465
3486
|
};
|
|
3466
3487
|
}
|
|
3467
3488
|
function isLLMProviderId(value) {
|
|
3468
|
-
return value === '
|
|
3489
|
+
return value === 'anthropic'
|
|
3490
|
+
|| value === 'claude-agent-sdk'
|
|
3469
3491
|
|| value === 'claude-code'
|
|
3470
3492
|
|| value === 'openai'
|
|
3471
3493
|
|| value === 'gemini'
|
|
3472
3494
|
|| value === 'ollama'
|
|
3473
3495
|
|| value === 'custom-openai';
|
|
3474
3496
|
}
|
|
3475
|
-
function resolveDefaultLLMProvider(projectRoot) {
|
|
3497
|
+
export function resolveDefaultLLMProvider(projectRoot) {
|
|
3476
3498
|
const settings = listProviderSettings(projectRoot);
|
|
3477
|
-
const
|
|
3499
|
+
const activeProvider = getActiveProvider(projectRoot);
|
|
3500
|
+
if (activeProvider) {
|
|
3501
|
+
const active = settings.find((item) => item.id === activeProvider);
|
|
3502
|
+
if (active?.enabled)
|
|
3503
|
+
return activeProvider;
|
|
3504
|
+
}
|
|
3505
|
+
const preferred = ['openai', 'gemini', 'anthropic', 'custom-openai', 'ollama'];
|
|
3478
3506
|
for (const id of preferred) {
|
|
3479
3507
|
const provider = settings.find((item) => item.id === id);
|
|
3480
3508
|
if (provider?.enabled && provider.hasApiKey)
|
|
@@ -4931,9 +4959,11 @@ async function buildBlockStudioAiAssistSummary(projectRoot, action, candidate, v
|
|
|
4931
4959
|
}
|
|
4932
4960
|
async function createBlockStudioAssistProvider(projectRoot, requestedProvider) {
|
|
4933
4961
|
const settings = listProviderSettings(projectRoot);
|
|
4962
|
+
const activeProvider = getActiveProvider(projectRoot);
|
|
4934
4963
|
const selected = requestedProvider
|
|
4935
4964
|
? settings.find((provider) => provider.id === requestedProvider && provider.enabled && provider.hasApiKey)
|
|
4936
|
-
: settings.find((provider) => provider.
|
|
4965
|
+
: settings.find((provider) => provider.id === activeProvider && provider.enabled)
|
|
4966
|
+
?? settings.find((provider) => provider.enabled && provider.hasApiKey);
|
|
4937
4967
|
if (!selected)
|
|
4938
4968
|
return null;
|
|
4939
4969
|
const config = getEffectiveProviderConfig(projectRoot, selected.id);
|
|
@@ -6497,11 +6527,17 @@ function isProviderSettingsId(value) {
|
|
|
6497
6527
|
}
|
|
6498
6528
|
async function testProviderConfig(projectRoot, id) {
|
|
6499
6529
|
const config = getEffectiveProviderConfig(projectRoot, id);
|
|
6530
|
+
const label = providerSettingsLabel(id);
|
|
6531
|
+
const details = providerConfigDetails(id, config);
|
|
6532
|
+
if (!config.enabled) {
|
|
6533
|
+
return { ok: false, message: `${label} is disabled in Settings.` };
|
|
6534
|
+
}
|
|
6535
|
+
if (id === 'openai')
|
|
6536
|
+
return testOpenAIProviderConfig(config, label, details);
|
|
6537
|
+
if (id === 'anthropic')
|
|
6538
|
+
return testAnthropicProviderConfig(config, label, details);
|
|
6500
6539
|
let provider;
|
|
6501
6540
|
switch (id) {
|
|
6502
|
-
case 'anthropic':
|
|
6503
|
-
provider = new ClaudeProvider({ apiKey: config.apiKey, model: config.model });
|
|
6504
|
-
break;
|
|
6505
6541
|
case 'gemini':
|
|
6506
6542
|
provider = new GeminiProvider({ apiKey: config.apiKey, model: config.model });
|
|
6507
6543
|
break;
|
|
@@ -6509,20 +6545,97 @@ async function testProviderConfig(projectRoot, id) {
|
|
|
6509
6545
|
provider = new OllamaProvider({ baseUrl: config.baseUrl, model: config.model });
|
|
6510
6546
|
break;
|
|
6511
6547
|
case 'custom-openai':
|
|
6512
|
-
provider = new OpenAIProvider({ apiKey: config.apiKey, baseUrl: config.baseUrl, model: config.model, allowNoApiKey: true });
|
|
6513
|
-
break;
|
|
6514
|
-
case 'openai':
|
|
6515
6548
|
default:
|
|
6516
|
-
provider = new OpenAIProvider({ apiKey: config.apiKey, baseUrl: config.baseUrl, model: config.model });
|
|
6549
|
+
provider = new OpenAIProvider({ apiKey: config.apiKey, baseUrl: config.baseUrl, model: config.model, allowNoApiKey: true });
|
|
6517
6550
|
break;
|
|
6518
6551
|
}
|
|
6519
|
-
const
|
|
6520
|
-
|
|
6521
|
-
|
|
6522
|
-
|
|
6523
|
-
|
|
6524
|
-
|
|
6525
|
-
}
|
|
6552
|
+
const available = await provider.available().catch(() => false);
|
|
6553
|
+
if (!available) {
|
|
6554
|
+
return {
|
|
6555
|
+
ok: false,
|
|
6556
|
+
message: `${label} is not configured or reachable${details}. Check API key, base URL, and local service state.`,
|
|
6557
|
+
};
|
|
6558
|
+
}
|
|
6559
|
+
try {
|
|
6560
|
+
const text = await provider.generate([
|
|
6561
|
+
{ role: 'user', content: 'Reply with exactly: OK' },
|
|
6562
|
+
], { maxTokens: 8, temperature: 0 });
|
|
6563
|
+
return {
|
|
6564
|
+
ok: true,
|
|
6565
|
+
message: `${label} responded${details}: ${text.trim().slice(0, 80) || 'OK'}`,
|
|
6566
|
+
};
|
|
6567
|
+
}
|
|
6568
|
+
catch (error) {
|
|
6569
|
+
return {
|
|
6570
|
+
ok: false,
|
|
6571
|
+
message: `${label} is configured but the model call failed${details}: ${error instanceof Error ? error.message : String(error)}`,
|
|
6572
|
+
};
|
|
6573
|
+
}
|
|
6574
|
+
}
|
|
6575
|
+
async function testOpenAIProviderConfig(config, label, details) {
|
|
6576
|
+
if (!config.apiKey) {
|
|
6577
|
+
return { ok: false, message: `${label} is not configured${details}. Add an API key in Settings or OPENAI_API_KEY.` };
|
|
6578
|
+
}
|
|
6579
|
+
try {
|
|
6580
|
+
const client = new OpenAI({ apiKey: config.apiKey, baseURL: config.baseUrl });
|
|
6581
|
+
const response = await client.responses.create({
|
|
6582
|
+
model: config.model ?? 'gpt-5.5',
|
|
6583
|
+
input: 'Reply with exactly: OK',
|
|
6584
|
+
max_output_tokens: 16,
|
|
6585
|
+
});
|
|
6586
|
+
return {
|
|
6587
|
+
ok: true,
|
|
6588
|
+
message: `${label} SDK responded${details}: ${(response.output_text ?? 'OK').trim().slice(0, 80) || 'OK'}`,
|
|
6589
|
+
};
|
|
6590
|
+
}
|
|
6591
|
+
catch (error) {
|
|
6592
|
+
return {
|
|
6593
|
+
ok: false,
|
|
6594
|
+
message: `${label} SDK call failed${details}: ${error instanceof Error ? error.message : String(error)}`,
|
|
6595
|
+
};
|
|
6596
|
+
}
|
|
6597
|
+
}
|
|
6598
|
+
async function testAnthropicProviderConfig(config, label, details) {
|
|
6599
|
+
if (!config.apiKey) {
|
|
6600
|
+
return { ok: false, message: `${label} is not configured${details}. Add an API key in Settings or ANTHROPIC_API_KEY.` };
|
|
6601
|
+
}
|
|
6602
|
+
try {
|
|
6603
|
+
const client = new Anthropic({ apiKey: config.apiKey });
|
|
6604
|
+
const response = await client.messages.create({
|
|
6605
|
+
model: config.model ?? 'claude-opus-4-8',
|
|
6606
|
+
max_tokens: 16,
|
|
6607
|
+
temperature: 0,
|
|
6608
|
+
messages: [{ role: 'user', content: 'Reply with exactly: OK' }],
|
|
6609
|
+
});
|
|
6610
|
+
const text = response.content?.filter((block) => block.type === 'text').map((block) => block.text ?? '').join('') ?? '';
|
|
6611
|
+
return {
|
|
6612
|
+
ok: true,
|
|
6613
|
+
message: `${label} SDK responded${details}: ${text.trim().slice(0, 80) || 'OK'}`,
|
|
6614
|
+
};
|
|
6615
|
+
}
|
|
6616
|
+
catch (error) {
|
|
6617
|
+
return {
|
|
6618
|
+
ok: false,
|
|
6619
|
+
message: `${label} SDK call failed${details}: ${error instanceof Error ? error.message : String(error)}`,
|
|
6620
|
+
};
|
|
6621
|
+
}
|
|
6622
|
+
}
|
|
6623
|
+
function providerSettingsLabel(id) {
|
|
6624
|
+
switch (id) {
|
|
6625
|
+
case 'anthropic': return 'Anthropic Claude';
|
|
6626
|
+
case 'openai': return 'OpenAI';
|
|
6627
|
+
case 'gemini': return 'Gemini';
|
|
6628
|
+
case 'ollama': return 'Ollama';
|
|
6629
|
+
case 'custom-openai': return 'Custom OpenAI-compatible provider';
|
|
6630
|
+
}
|
|
6631
|
+
}
|
|
6632
|
+
function providerConfigDetails(id, config) {
|
|
6633
|
+
const parts = [
|
|
6634
|
+
config.model ? `model ${config.model}` : '',
|
|
6635
|
+
config.baseUrl ? `base URL ${config.baseUrl}` : '',
|
|
6636
|
+
id === 'ollama' ? 'local endpoint' : config.apiKey ? 'API key present' : 'API key missing',
|
|
6637
|
+
].filter(Boolean);
|
|
6638
|
+
return parts.length ? ` (${parts.join(', ')})` : '';
|
|
6526
6639
|
}
|
|
6527
6640
|
function isAiPinRefreshDue(lastRefreshedAt) {
|
|
6528
6641
|
if (!lastRefreshedAt)
|