@vfarcic/dot-ai 1.16.2 → 1.17.0
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/core/ai-provider-factory.d.ts.map +1 -1
- package/dist/core/ai-provider-factory.js +1 -0
- package/dist/core/ai-provider.interface.d.ts +2 -2
- package/dist/core/ai-provider.interface.d.ts.map +1 -1
- package/dist/core/internal-tools.d.ts.map +1 -1
- package/dist/core/internal-tools.js +18 -8
- package/dist/core/model-config.d.ts +2 -2
- package/dist/core/model-config.js +2 -2
- package/dist/core/tracing/ai-tracing.d.ts +3 -3
- package/dist/core/tracing/ai-tracing.d.ts.map +1 -1
- package/dist/core/tracing/ai-tracing.js +7 -5
- package/dist/tools/answer-question.d.ts +21 -0
- package/dist/tools/answer-question.d.ts.map +1 -1
- package/dist/tools/answer-question.js +13 -2
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-provider-factory.d.ts","sourceRoot":"","sources":["../../src/core/ai-provider-factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"ai-provider-factory.d.ts","sourceRoot":"","sources":["../../src/core/ai-provider-factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAiCvE;;;;;;;;;;;;;;GAcG;AACH,qBAAa,iBAAiB;IAC5B;;;;;;OAMG;IACH,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG,UAAU;IA+BnD;;;;;;;;;;OAUG;IACH,MAAM,CAAC,aAAa,IAAI,UAAU;IAsGlC;;;;;OAKG;IACH,MAAM,CAAC,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAWrD;;;;OAIG;IACH,MAAM,CAAC,qBAAqB,IAAI,MAAM,EAAE;IAMxC;;;;;OAKG;IACH,MAAM,CAAC,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAGxD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,UAAU,CAE7C"}
|
|
@@ -30,6 +30,7 @@ const PROVIDER_ENV_KEYS = {
|
|
|
30
30
|
kimi: 'MOONSHOT_API_KEY', // PRD #353: Moonshot AI Kimi K2.5
|
|
31
31
|
alibaba: 'ALIBABA_API_KEY', // PRD #382: Alibaba Qwen 3.5 Plus
|
|
32
32
|
xai: 'XAI_API_KEY',
|
|
33
|
+
custom: 'CUSTOM_LLM_API_KEY', // PRD #194 / Issue #474: Explicit opt-in to custom OpenAI-compatible endpoint
|
|
33
34
|
};
|
|
34
35
|
const IMPLEMENTED_PROVIDERS = Object.keys(model_config_1.CURRENT_MODELS);
|
|
35
36
|
/**
|
|
@@ -180,7 +180,7 @@ export interface AIProvider {
|
|
|
180
180
|
* NEW: Required to replace hardcoded model at claude.ts:181
|
|
181
181
|
* Each provider has different model naming conventions.
|
|
182
182
|
*
|
|
183
|
-
* @returns Model identifier (e.g., 'claude-sonnet-4-
|
|
183
|
+
* @returns Model identifier (e.g., 'claude-sonnet-4-6', 'gpt-5.4', 'gemini-3.1-pro-preview')
|
|
184
184
|
*/
|
|
185
185
|
getDefaultModel(): string;
|
|
186
186
|
/**
|
|
@@ -194,7 +194,7 @@ export interface AIProvider {
|
|
|
194
194
|
/**
|
|
195
195
|
* Get the current model name being used
|
|
196
196
|
*
|
|
197
|
-
* @returns Model name (e.g., 'grok-4', 'claude-sonnet-4-
|
|
197
|
+
* @returns Model name (e.g., 'grok-4', 'claude-sonnet-4-6')
|
|
198
198
|
*/
|
|
199
199
|
getModelName(): string;
|
|
200
200
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-provider.interface.d.ts","sourceRoot":"","sources":["../../src/core/ai-provider.interface.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,2BAA2B,CAAC,EAAE,MAAM,CAAC;QACrC,uBAAuB,CAAC,EAAE,MAAM,CAAC;KAClC,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+BAA+B;IAC/B,MAAM,EAAE,MAAM,CAAC;IAEf,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IAEjB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf,oDAAoD;IACpD,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACxC;AAED;;;GAGG;AACH,MAAM,WAAW,MAAM;IACrB,oEAAoE;IACpE,IAAI,EAAE,MAAM,CAAC;IAEb,0EAA0E;IAC1E,WAAW,EAAE,MAAM,CAAC;IAEpB,4CAA4C;IAC5C,WAAW,EAAE;QACX,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACpC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED;;;GAGG;AACH,MAAM,MAAM,YAAY,GAAG,
|
|
1
|
+
{"version":3,"file":"ai-provider.interface.d.ts","sourceRoot":"","sources":["../../src/core/ai-provider.interface.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"internal-tools.d.ts","sourceRoot":"","sources":["../../src/core/internal-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAsBvE;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAUlE;
|
|
1
|
+
{"version":3,"file":"internal-tools.d.ts","sourceRoot":"","sources":["../../src/core/internal-tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,4BAA4B,CAAC;AAsBvE;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAUlE;AAgBD;;;GAGG;AACH,wBAAgB,gBAAgB,IAAI,MAAM,EAAE,CAkD3C;AAiHD,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,iBAAiB,GACzB;IACE,OAAO,EAAE,IAAI,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB,GACD;IACE,OAAO,EAAE,IAAI,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACf,GACD;IAAE,OAAO,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AA4ItC;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAqB1E;AAID;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,GAAE,MAAuB,GAAG,IAAI,CAuBxE"}
|
|
@@ -89,9 +89,7 @@ function validatePathWithinClones(inputPath) {
|
|
|
89
89
|
function repoUrlToDirectoryName(repoUrl) {
|
|
90
90
|
try {
|
|
91
91
|
const url = new URL(repoUrl);
|
|
92
|
-
const repoPath = url.pathname
|
|
93
|
-
.replace(/^\//, '')
|
|
94
|
-
.replace(/\.git$/, '');
|
|
92
|
+
const repoPath = url.pathname.replace(/^\//, '').replace(/\.git$/, '');
|
|
95
93
|
return (0, solution_utils_js_1.sanitizeIntentForLabel)(repoPath);
|
|
96
94
|
}
|
|
97
95
|
catch {
|
|
@@ -196,7 +194,7 @@ function handleFsList(args) {
|
|
|
196
194
|
return `Error: path is not a directory: ${inputPath}`;
|
|
197
195
|
}
|
|
198
196
|
const entries = fs.readdirSync(resolved, { withFileTypes: true });
|
|
199
|
-
return entries.map(
|
|
197
|
+
return entries.map(entry => ({
|
|
200
198
|
name: entry.name,
|
|
201
199
|
type: entry.isDirectory() ? 'directory' : 'file',
|
|
202
200
|
}));
|
|
@@ -257,7 +255,10 @@ async function handleGitCreatePr(args) {
|
|
|
257
255
|
return { success: false, error: 'repoPath is required' };
|
|
258
256
|
}
|
|
259
257
|
if (!files || !Array.isArray(files) || files.length === 0) {
|
|
260
|
-
return {
|
|
258
|
+
return {
|
|
259
|
+
success: false,
|
|
260
|
+
error: 'files array is required and must not be empty',
|
|
261
|
+
};
|
|
261
262
|
}
|
|
262
263
|
if (!title) {
|
|
263
264
|
return { success: false, error: 'title is required' };
|
|
@@ -324,6 +325,12 @@ async function handleGitCreatePr(args) {
|
|
|
324
325
|
body,
|
|
325
326
|
head: branchName,
|
|
326
327
|
base: baseBranch,
|
|
328
|
+
// Test-only switch: integration tests set this so PRs they create
|
|
329
|
+
// don't trigger CodeRabbit (which has drafts: false in .coderabbit.yaml).
|
|
330
|
+
// Production never sets this env var.
|
|
331
|
+
...(process.env.DOT_AI_GIT_CREATE_DRAFT_PRS === 'true' && {
|
|
332
|
+
draft: true,
|
|
333
|
+
}),
|
|
327
334
|
}),
|
|
328
335
|
signal: AbortSignal.timeout(30000),
|
|
329
336
|
});
|
|
@@ -356,7 +363,7 @@ async function handleGitCreatePr(args) {
|
|
|
356
363
|
*/
|
|
357
364
|
function createInternalToolExecutor(sessionId) {
|
|
358
365
|
const handlers = {
|
|
359
|
-
git_clone:
|
|
366
|
+
git_clone: args => handleGitClone(args, sessionId),
|
|
360
367
|
fs_list: handleFsList,
|
|
361
368
|
fs_read: handleFsRead,
|
|
362
369
|
git_create_pr: handleGitCreatePr,
|
|
@@ -380,7 +387,9 @@ function createInternalToolExecutor(sessionId) {
|
|
|
380
387
|
*/
|
|
381
388
|
function cleanupOldClones(maxAgeMs = DEFAULT_TTL_MS) {
|
|
382
389
|
const clonesDir = getClonesDir();
|
|
383
|
-
fs.promises
|
|
390
|
+
fs.promises
|
|
391
|
+
.access(clonesDir)
|
|
392
|
+
.then(async () => {
|
|
384
393
|
const now = Date.now();
|
|
385
394
|
const entries = await fs.promises.readdir(clonesDir);
|
|
386
395
|
for (const entry of entries) {
|
|
@@ -395,7 +404,8 @@ function cleanupOldClones(maxAgeMs = DEFAULT_TTL_MS) {
|
|
|
395
404
|
// Ignore errors during cleanup (e.g., concurrent deletion)
|
|
396
405
|
}
|
|
397
406
|
}
|
|
398
|
-
})
|
|
407
|
+
})
|
|
408
|
+
.catch(() => {
|
|
399
409
|
// Directory doesn't exist yet, nothing to clean
|
|
400
410
|
});
|
|
401
411
|
}
|
|
@@ -6,13 +6,13 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export declare const CURRENT_MODELS: {
|
|
8
8
|
readonly anthropic: "claude-sonnet-4-6";
|
|
9
|
-
readonly anthropic_opus: "claude-opus-4-
|
|
9
|
+
readonly anthropic_opus: "claude-opus-4-7";
|
|
10
10
|
readonly anthropic_haiku: "claude-haiku-4-5-20251001";
|
|
11
11
|
readonly openai: "gpt-5.4";
|
|
12
12
|
readonly google: "gemini-3.1-pro-preview";
|
|
13
13
|
readonly google_flash: "gemini-3-flash-preview";
|
|
14
14
|
readonly kimi: "kimi-k2.5";
|
|
15
|
-
readonly alibaba: "qwen3.
|
|
15
|
+
readonly alibaba: "qwen3.6-plus";
|
|
16
16
|
readonly xai: "grok-4";
|
|
17
17
|
readonly host: "host";
|
|
18
18
|
readonly openrouter: "anthropic/claude-haiku-4.5";
|
|
@@ -10,13 +10,13 @@ exports.CURRENT_MODELS = void 0;
|
|
|
10
10
|
exports.getCurrentModel = getCurrentModel;
|
|
11
11
|
exports.CURRENT_MODELS = {
|
|
12
12
|
anthropic: 'claude-sonnet-4-6',
|
|
13
|
-
anthropic_opus: 'claude-opus-4-
|
|
13
|
+
anthropic_opus: 'claude-opus-4-7',
|
|
14
14
|
anthropic_haiku: 'claude-haiku-4-5-20251001',
|
|
15
15
|
openai: 'gpt-5.4',
|
|
16
16
|
google: 'gemini-3.1-pro-preview',
|
|
17
17
|
google_flash: 'gemini-3-flash-preview', // PRD #294: Gemini 3 Flash - faster/cheaper variant with same 1M context
|
|
18
18
|
kimi: 'kimi-k2.5', // PRD #353: Moonshot AI Kimi K2.5 - single model with thinking by default, 256K context
|
|
19
|
-
alibaba: 'qwen3.
|
|
19
|
+
alibaba: 'qwen3.6-plus', // PRD #480: Alibaba Qwen 3.6-Plus - 262K context, 201 languages, MoE architecture
|
|
20
20
|
xai: 'grok-4',
|
|
21
21
|
host: 'host', // Delegates generation to the client via MCP Sampling
|
|
22
22
|
openrouter: 'anthropic/claude-haiku-4.5', // PRD #194: OpenRouter default model (overridden by AI_MODEL env var)
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
export interface AITracingOptions {
|
|
18
18
|
/** AI provider name (e.g., 'anthropic', 'openai', 'google') */
|
|
19
19
|
provider: string;
|
|
20
|
-
/** Model identifier (e.g., 'claude-
|
|
20
|
+
/** Model identifier (e.g., 'claude-sonnet-4-6', 'gpt-5.4', 'text-embedding-3-small') */
|
|
21
21
|
model: string;
|
|
22
22
|
/** Operation type: 'chat', 'tool_loop', 'embeddings' */
|
|
23
23
|
operation: 'chat' | 'tool_loop' | 'embeddings';
|
|
@@ -57,14 +57,14 @@ export interface AITracingResult {
|
|
|
57
57
|
*
|
|
58
58
|
* @example Chat operation
|
|
59
59
|
* const response = await withAITracing(
|
|
60
|
-
* { provider: 'anthropic', model: 'claude-
|
|
60
|
+
* { provider: 'anthropic', model: 'claude-sonnet-4-6', operation: 'chat' },
|
|
61
61
|
* async () => await client.messages.create(...),
|
|
62
62
|
* (result) => ({ inputTokens: result.usage.input_tokens, outputTokens: result.usage.output_tokens })
|
|
63
63
|
* );
|
|
64
64
|
*
|
|
65
65
|
* @example Tool loop operation
|
|
66
66
|
* const result = await withAITracing(
|
|
67
|
-
* { provider: 'anthropic', model: 'claude-
|
|
67
|
+
* { provider: 'anthropic', model: 'claude-sonnet-4-6', operation: 'tool_loop' },
|
|
68
68
|
* async () => await provider.toolLoop(...),
|
|
69
69
|
* (result) => ({ inputTokens: result.totalTokens.input, outputTokens: result.totalTokens.output })
|
|
70
70
|
* );
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-tracing.d.ts","sourceRoot":"","sources":["../../../src/core/tracing/ai-tracing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IAEjB,
|
|
1
|
+
{"version":3,"file":"ai-tracing.d.ts","sourceRoot":"","sources":["../../../src/core/tracing/ai-tracing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAIH;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+DAA+D;IAC/D,QAAQ,EAAE,MAAM,CAAC;IAEjB,wFAAwF;IACxF,KAAK,EAAE,MAAM,CAAC;IAEd,wDAAwD;IACxD,SAAS,EAAE,MAAM,GAAG,WAAW,GAAG,YAAY,CAAC;IAE/C,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IAErB,oDAAoD;IACpD,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB,uDAAuD;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;IAEzB,2DAA2D;IAC3D,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAE7B,uDAAuD;IACvD,cAAc,CAAC,EAAE,MAAM,CAAC;IAExB,qDAAqD;IACrD,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,OAAO,EAAE,gBAAgB,EACzB,OAAO,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACzB,cAAc,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,eAAe,GAC7C,OAAO,CAAC,CAAC,CAAC,CA6GZ"}
|
|
@@ -28,14 +28,14 @@ const api_1 = require("@opentelemetry/api");
|
|
|
28
28
|
*
|
|
29
29
|
* @example Chat operation
|
|
30
30
|
* const response = await withAITracing(
|
|
31
|
-
* { provider: 'anthropic', model: 'claude-
|
|
31
|
+
* { provider: 'anthropic', model: 'claude-sonnet-4-6', operation: 'chat' },
|
|
32
32
|
* async () => await client.messages.create(...),
|
|
33
33
|
* (result) => ({ inputTokens: result.usage.input_tokens, outputTokens: result.usage.output_tokens })
|
|
34
34
|
* );
|
|
35
35
|
*
|
|
36
36
|
* @example Tool loop operation
|
|
37
37
|
* const result = await withAITracing(
|
|
38
|
-
* { provider: 'anthropic', model: 'claude-
|
|
38
|
+
* { provider: 'anthropic', model: 'claude-sonnet-4-6', operation: 'tool_loop' },
|
|
39
39
|
* async () => await provider.toolLoop(...),
|
|
40
40
|
* (result) => ({ inputTokens: result.totalTokens.input, outputTokens: result.totalTokens.output })
|
|
41
41
|
* );
|
|
@@ -51,7 +51,7 @@ async function withAITracing(options, handler, extractMetrics) {
|
|
|
51
51
|
// Get tracer (returns no-op if tracing disabled)
|
|
52
52
|
const tracer = api_1.trace.getTracer('dot-ai-mcp');
|
|
53
53
|
// Span name format: "{operation} {model}"
|
|
54
|
-
// Examples: "chat claude-
|
|
54
|
+
// Examples: "chat claude-sonnet-4-6", "tool_loop claude-sonnet-4-6", "embeddings text-embedding-3-small"
|
|
55
55
|
const spanName = `${options.operation} ${options.model}`;
|
|
56
56
|
return await tracer.startActiveSpan(spanName, {
|
|
57
57
|
kind: api_1.SpanKind.CLIENT,
|
|
@@ -86,10 +86,12 @@ async function withAITracing(options, handler, extractMetrics) {
|
|
|
86
86
|
span.setAttribute('gen_ai.usage.output_tokens', metrics.outputTokens);
|
|
87
87
|
}
|
|
88
88
|
// Cache metrics (Anthropic-specific for chat operations)
|
|
89
|
-
if (metrics.cacheReadTokens !== undefined &&
|
|
89
|
+
if (metrics.cacheReadTokens !== undefined &&
|
|
90
|
+
metrics.cacheReadTokens > 0) {
|
|
90
91
|
span.setAttribute('gen_ai.usage.cache_read_tokens', metrics.cacheReadTokens);
|
|
91
92
|
}
|
|
92
|
-
if (metrics.cacheCreationTokens !== undefined &&
|
|
93
|
+
if (metrics.cacheCreationTokens !== undefined &&
|
|
94
|
+
metrics.cacheCreationTokens > 0) {
|
|
93
95
|
span.setAttribute('gen_ai.usage.cache_creation_tokens', metrics.cacheCreationTokens);
|
|
94
96
|
}
|
|
95
97
|
}
|
|
@@ -4,6 +4,22 @@
|
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { DotAI } from '../core/index';
|
|
6
6
|
import { Logger } from '../core/error-handling';
|
|
7
|
+
interface QuestionValidation {
|
|
8
|
+
required?: boolean;
|
|
9
|
+
message?: string;
|
|
10
|
+
min?: number;
|
|
11
|
+
max?: number;
|
|
12
|
+
pattern?: string;
|
|
13
|
+
options?: string[];
|
|
14
|
+
}
|
|
15
|
+
interface Question {
|
|
16
|
+
id?: string;
|
|
17
|
+
question: string;
|
|
18
|
+
type?: 'text' | 'number' | 'boolean' | 'select' | 'multiSelect';
|
|
19
|
+
validation?: QuestionValidation;
|
|
20
|
+
answer?: unknown;
|
|
21
|
+
options?: string[];
|
|
22
|
+
}
|
|
7
23
|
export declare const ANSWERQUESTION_TOOL_NAME = "answerQuestion";
|
|
8
24
|
export declare const ANSWERQUESTION_TOOL_DESCRIPTION = "Process user answers and return remaining questions or completion status. For open stage, use \"open\" as the answer key.";
|
|
9
25
|
export declare const ANSWERQUESTION_TOOL_INPUT_SCHEMA: {
|
|
@@ -17,6 +33,10 @@ export declare const ANSWERQUESTION_TOOL_INPUT_SCHEMA: {
|
|
|
17
33
|
answers: z.ZodRecord<z.ZodString, z.ZodAny>;
|
|
18
34
|
interaction_id: z.ZodOptional<z.ZodString>;
|
|
19
35
|
};
|
|
36
|
+
/**
|
|
37
|
+
* Validate answer against question schema
|
|
38
|
+
*/
|
|
39
|
+
export declare function validateAnswer(answer: unknown, question: Question): string | null;
|
|
20
40
|
/**
|
|
21
41
|
* Direct MCP tool handler for answerQuestion functionality
|
|
22
42
|
*/
|
|
@@ -31,4 +51,5 @@ export declare function handleAnswerQuestionTool(args: {
|
|
|
31
51
|
text: string;
|
|
32
52
|
}[];
|
|
33
53
|
}>;
|
|
54
|
+
export {};
|
|
34
55
|
//# sourceMappingURL=answer-question.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"answer-question.d.ts","sourceRoot":"","sources":["../../src/tools/answer-question.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"answer-question.d.ts","sourceRoot":"","sources":["../../src/tools/answer-question.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAOxB,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,MAAM,wBAAwB,CAAC;AAUhD,UAAU,kBAAkB;IAC1B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,UAAU,QAAQ;IAChB,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,GAAG,aAAa,CAAC;IAChE,UAAU,CAAC,EAAE,kBAAkB,CAAC;IAChC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;CACpB;AAgDD,eAAO,MAAM,wBAAwB,mBAAmB,CAAC;AACzD,eAAO,MAAM,+BAA+B,8HAC+E,CAAC;AAG5H,eAAO,MAAM,gCAAgC;;;;;;;;;;CAmB5C,CAAC;AAIF;;GAEG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,OAAO,EACf,QAAQ,EAAE,QAAQ,GACjB,MAAM,GAAG,IAAI,CA4Ef;AAyiBD;;GAEG;AACH,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE;IACJ,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,MAAM,CAAC;IAClD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,EACD,KAAK,EAAE,KAAK,EACZ,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAA;CAAE,CAAC,CAgZxD"}
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
6
|
exports.ANSWERQUESTION_TOOL_INPUT_SCHEMA = exports.ANSWERQUESTION_TOOL_DESCRIPTION = exports.ANSWERQUESTION_TOOL_NAME = void 0;
|
|
7
|
+
exports.validateAnswer = validateAnswer;
|
|
7
8
|
exports.handleAnswerQuestionTool = handleAnswerQuestionTool;
|
|
8
9
|
const zod_1 = require("zod");
|
|
9
10
|
const error_handling_1 = require("../core/error-handling");
|
|
@@ -36,9 +37,19 @@ exports.ANSWERQUESTION_TOOL_INPUT_SCHEMA = {
|
|
|
36
37
|
* Validate answer against question schema
|
|
37
38
|
*/
|
|
38
39
|
function validateAnswer(answer, question) {
|
|
39
|
-
// Check required validation
|
|
40
|
+
// Check required validation.
|
|
41
|
+
// Issue #474: For 'select' questions, empty string is a valid answer when it
|
|
42
|
+
// is explicitly listed in `options` (e.g., options=["", "soft", "hard"] where
|
|
43
|
+
// "" represents the "none/disabled" choice). Skip the empty-string rejection
|
|
44
|
+
// in that case so the question's own option list is the source of truth.
|
|
45
|
+
const emptyAnswer = answer === undefined || answer === null || answer === '';
|
|
46
|
+
const isExplicitEmptySelectOption = question.type === 'select' &&
|
|
47
|
+
answer === '' &&
|
|
48
|
+
Array.isArray(question.options) &&
|
|
49
|
+
question.options.includes('');
|
|
40
50
|
if (question.validation?.required &&
|
|
41
|
-
|
|
51
|
+
emptyAnswer &&
|
|
52
|
+
!isExplicitEmptySelectOption) {
|
|
42
53
|
return question.validation.message || `${question.question} is required`;
|
|
43
54
|
}
|
|
44
55
|
// Skip validation if answer is empty and not required
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vfarcic/dot-ai",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.17.0",
|
|
4
4
|
"description": "AI-powered development productivity platform that enhances software development workflows through intelligent automation and AI-driven assistance",
|
|
5
5
|
"mcpName": "io.github.vfarcic/dot-ai",
|
|
6
6
|
"main": "dist/index.js",
|