@kkeve/suite 0.0.1 → 0.0.2
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/README.md +53 -0
- package/dist/bin/keve.d.ts +13 -0
- package/dist/bin/keve.js +164 -0
- package/dist/commands/auth-update.d.ts +16 -0
- package/dist/commands/auth-update.js +88 -0
- package/dist/commands/clean.d.ts +10 -0
- package/dist/commands/clean.js +78 -0
- package/dist/commands/config.d.ts +17 -0
- package/dist/commands/config.js +99 -0
- package/dist/commands/init.d.ts +15 -0
- package/dist/commands/init.js +292 -0
- package/dist/commands/report.d.ts +12 -0
- package/dist/commands/report.js +159 -0
- package/dist/commands/run.d.ts +29 -0
- package/dist/commands/run.js +417 -0
- package/dist/commands/test.d.ts +12 -0
- package/dist/commands/test.js +102 -0
- package/dist/commands/vitest.d.ts +14 -0
- package/dist/commands/vitest.js +166 -0
- package/dist/config.d.ts +109 -0
- package/dist/config.js +291 -0
- package/dist/core/action-log-writer.d.ts +47 -0
- package/dist/{tools/write-file.js → core/action-log-writer.js} +42 -26
- package/dist/core/auth.d.ts +17 -0
- package/dist/core/auth.js +224 -0
- package/dist/core/cdp-resolver.d.ts +5 -0
- package/dist/core/cdp-resolver.js +93 -0
- package/dist/core/generateReport/report.d.ts +19 -0
- package/dist/core/generateReport/report.js +91 -0
- package/dist/core/generateReport/reportData.d.ts +215 -0
- package/dist/core/generateReport/reportData.js +735 -0
- package/dist/core/global-setup.d.ts +6 -0
- package/dist/core/global-setup.js +113 -0
- package/dist/core/keve-aspect.d.ts +54 -0
- package/dist/core/keve-aspect.js +52 -0
- package/dist/core/keve-decorators.d.ts +51 -0
- package/dist/core/keve-decorators.js +95 -0
- package/dist/core/keve-registry.d.ts +38 -0
- package/dist/core/keve-registry.js +25 -0
- package/dist/core/keve-report.d.ts +27 -0
- package/dist/core/keve-report.js +357 -0
- package/dist/core/keve-test.d.ts +36 -0
- package/dist/core/keve-test.js +364 -0
- package/dist/core/learned-actions.d.ts +24 -0
- package/dist/core/learned-actions.js +65 -0
- package/dist/core/pw-config.d.ts +19 -0
- package/dist/core/pw-config.js +180 -0
- package/dist/index.d.ts +8 -23
- package/dist/index.js +36 -43
- package/dist/page-agent/agent.d.ts +129 -0
- package/dist/page-agent/agent.js +585 -0
- package/dist/page-agent/hooks.d.ts +13 -0
- package/dist/page-agent/hooks.js +218 -0
- package/dist/page-agent/tools.d.ts +29 -0
- package/dist/page-agent/tools.js +297 -0
- package/doc/README.md +124 -0
- package/doc/agents/keve-dev-test-agent.md +140 -0
- package/doc/agents/keve-test-agent.md +178 -0
- package/doc/asserts//346/265/213/350/257/225/345/220/204/351/230/266/346/256/265/350/257/264/346/230/216.png +0 -0
- package/doc/keve-agent-demo.html +370 -0
- package/doc/skills/keve-bddcase-gen/SKILL.md +332 -0
- package/doc/skills/keve-bddcase-gen/references/test-case-rules.md +91 -0
- package/doc/skills/keve-bddcase-gen/references/test-cases-example.md +103 -0
- package/doc/skills/keve-component-gen/SKILL.md +255 -0
- package/doc/skills/keve-component-gen/references/component-mock-strategy.md +74 -0
- package/doc/skills/keve-component-gen/references/component-model-template.md +98 -0
- package/doc/skills/keve-component-gen/references/component-test-template.md +100 -0
- package/doc/skills/keve-component-gen/references/vue-test-utils-guide.md +91 -0
- package/doc/skills/keve-e2e-gen/SKILL.md +179 -0
- package/doc/skills/keve-e2e-gen/references/code-analysis-guide.md +208 -0
- package/doc/skills/keve-e2e-gen/references/decisions.md +36 -0
- package/doc/skills/keve-e2e-gen/references/pom-generation-guide.md +140 -0
- package/doc/skills/keve-e2e-gen/references/script-generation-guide.md +236 -0
- package/doc/skills/keve-e2e-gen/references/test-auditor-guide.md +189 -0
- package/doc/skills/keve-e2e-gen/scripts/extract-components.sh +85 -0
- package/doc/skills/keve-e2e-gen/scripts/inject-testids.sh +95 -0
- package/doc/skills/keve-static-analysis/SKILL.md +362 -0
- package/doc/skills/keve-static-analysis/references/codegraph-analysis-guide.md +108 -0
- package/doc/skills/keve-static-analysis/references/git-impact-analysis.md +81 -0
- package/doc/skills/keve-static-analysis/references/lint-fix-guide.md +69 -0
- package/doc/skills/keve-static-analysis/references/runtime-risk-patterns.md +92 -0
- package/doc/skills/keve-static-analysis/references/security-scan-guide.md +32 -0
- package/doc/skills/keve-static-analysis/references/ts-error-patterns.md +98 -0
- package/doc/skills/keve-static-analysis/references/vue-security-guide.md +72 -0
- package/doc/skills/keve-test-eval/SKILL.md +78 -0
- package/doc/skills/keve-test-eval/references/common-fix-guide.md +166 -0
- package/doc/skills/keve-test-eval/references/confidence-data-guide.md +78 -0
- package/doc/skills/keve-test-eval/references/fix-loop-guide.md +67 -0
- package/doc/skills/keve-unit-gen/SKILL.md +203 -0
- package/doc/skills/keve-unit-gen/references/boundary-conditions.md +78 -0
- package/doc/skills/keve-unit-gen/references/unit-mock-strategy.md +71 -0
- package/doc/skills/keve-unit-gen/references/unit-test-template.md +105 -0
- package/package.json +47 -25
- package/dist/agent/factory.d.ts +0 -25
- package/dist/agent/factory.js +0 -99
- package/dist/agent/index.d.ts +0 -3
- package/dist/agent/index.js +0 -7
- package/dist/agent/loader.d.ts +0 -22
- package/dist/agent/loader.js +0 -117
- package/dist/agent/types.d.ts +0 -9
- package/dist/agent/types.js +0 -2
- package/dist/agent-loop/complete-task.d.ts +0 -28
- package/dist/agent-loop/complete-task.js +0 -70
- package/dist/agent-loop/index.d.ts +0 -16
- package/dist/agent-loop/index.js +0 -26
- package/dist/agent-loop/loop.d.ts +0 -42
- package/dist/agent-loop/loop.js +0 -282
- package/dist/agent-loop/runtime.d.ts +0 -40
- package/dist/agent-loop/runtime.js +0 -163
- package/dist/agent-loop/types.d.ts +0 -161
- package/dist/agent-loop/types.js +0 -105
- package/dist/context/index.d.ts +0 -8
- package/dist/context/index.js +0 -29
- package/dist/context/tokenCalculation.d.ts +0 -55
- package/dist/context/tokenCalculation.js +0 -95
- package/dist/context/truncation.d.ts +0 -67
- package/dist/context/truncation.js +0 -142
- package/dist/context/types.d.ts +0 -7
- package/dist/context/types.js +0 -27
- package/dist/llm/OpenAIClient.d.ts +0 -31
- package/dist/llm/OpenAIClient.js +0 -455
- package/dist/llm/constants.d.ts +0 -2
- package/dist/llm/constants.js +0 -6
- package/dist/llm/errors.d.ts +0 -25
- package/dist/llm/errors.js +0 -51
- package/dist/llm/index.d.ts +0 -49
- package/dist/llm/index.js +0 -158
- package/dist/llm/types.d.ts +0 -124
- package/dist/llm/types.js +0 -2
- package/dist/llm/utils.d.ts +0 -29
- package/dist/llm/utils.js +0 -284
- package/dist/skill/frontmatter-parser.d.ts +0 -50
- package/dist/skill/frontmatter-parser.js +0 -152
- package/dist/skill/index.d.ts +0 -12
- package/dist/skill/index.js +0 -17
- package/dist/skill/loader.d.ts +0 -96
- package/dist/skill/loader.js +0 -256
- package/dist/tools/ask-user.d.ts +0 -8
- package/dist/tools/ask-user.js +0 -47
- package/dist/tools/bash.d.ts +0 -47
- package/dist/tools/bash.js +0 -213
- package/dist/tools/edit-file.d.ts +0 -9
- package/dist/tools/edit-file.js +0 -76
- package/dist/tools/glob.d.ts +0 -8
- package/dist/tools/glob.js +0 -101
- package/dist/tools/grep.d.ts +0 -10
- package/dist/tools/grep.js +0 -76
- package/dist/tools/index.d.ts +0 -24
- package/dist/tools/index.js +0 -47
- package/dist/tools/read-files.d.ts +0 -8
- package/dist/tools/read-files.js +0 -81
- package/dist/tools/write-file.d.ts +0 -8
package/dist/llm/index.js
DELETED
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* LLM client with MacroTool support
|
|
4
|
-
*
|
|
5
|
-
* Key features:
|
|
6
|
-
* - Direct fetch to OpenAI API (no LangChain dependency)
|
|
7
|
-
* - Zod schema for tool definitions
|
|
8
|
-
* - toolChoiceName support (force specific tool call)
|
|
9
|
-
* - parallel_tool_calls: false (one tool per step)
|
|
10
|
-
* - Retry with error classification
|
|
11
|
-
* - Model-specific patches (Claude, Qwen, GPT, etc.)
|
|
12
|
-
*/
|
|
13
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
-
exports.LLM = exports.extractXMLTag = exports.parseXMLExtractionResponse = exports.InvokeErrorType = exports.InvokeError = void 0;
|
|
15
|
-
exports.parseLLMConfig = parseLLMConfig;
|
|
16
|
-
const OpenAIClient_1 = require("./OpenAIClient");
|
|
17
|
-
const constants_1 = require("./constants");
|
|
18
|
-
const errors_1 = require("./errors");
|
|
19
|
-
Object.defineProperty(exports, "InvokeError", { enumerable: true, get: function () { return errors_1.InvokeError; } });
|
|
20
|
-
Object.defineProperty(exports, "InvokeErrorType", { enumerable: true, get: function () { return errors_1.InvokeErrorType; } });
|
|
21
|
-
const utils_1 = require("./utils");
|
|
22
|
-
Object.defineProperty(exports, "parseXMLExtractionResponse", { enumerable: true, get: function () { return utils_1.parseXMLExtractionResponse; } });
|
|
23
|
-
Object.defineProperty(exports, "extractXMLTag", { enumerable: true, get: function () { return utils_1.extractXMLTag; } });
|
|
24
|
-
function parseLLMConfig(config) {
|
|
25
|
-
if (!config.baseURL || !config.model) {
|
|
26
|
-
throw new Error('[EVEAgent] LLM configuration required. Please provide: baseURL, model.');
|
|
27
|
-
}
|
|
28
|
-
return {
|
|
29
|
-
baseURL: config.baseURL,
|
|
30
|
-
model: config.model,
|
|
31
|
-
apiKey: config.apiKey || '',
|
|
32
|
-
temperature: config.temperature ?? constants_1.DEFAULT_TEMPERATURE,
|
|
33
|
-
maxRetries: config.maxRetries ?? constants_1.LLM_MAX_RETRIES,
|
|
34
|
-
disableNamedToolChoice: config.disableNamedToolChoice ?? false,
|
|
35
|
-
customFetch: (config.customFetch ?? fetch).bind(globalThis),
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
class LLM extends EventTarget {
|
|
39
|
-
config;
|
|
40
|
-
client;
|
|
41
|
-
constructor(config) {
|
|
42
|
-
super();
|
|
43
|
-
this.config = parseLLMConfig(config);
|
|
44
|
-
this.client = new OpenAIClient_1.OpenAIClient(this.config);
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Call LLM API once, invoke tool call once, return the result.
|
|
48
|
-
* This is the core method used by gui-agent's MacroTool loop.
|
|
49
|
-
*/
|
|
50
|
-
async invoke(messages, tools, abortSignal, options) {
|
|
51
|
-
const signal = abortSignal || new AbortController().signal;
|
|
52
|
-
return await withRetry(async () => {
|
|
53
|
-
if (signal.aborted)
|
|
54
|
-
throw new Error('AbortError');
|
|
55
|
-
return await this.client.invoke(messages, tools, signal, options);
|
|
56
|
-
}, {
|
|
57
|
-
maxRetries: this.config.maxRetries,
|
|
58
|
-
onRetry: (attempt) => {
|
|
59
|
-
this.dispatchEvent(new CustomEvent('retry', { detail: { attempt, maxAttempts: this.config.maxRetries } }));
|
|
60
|
-
},
|
|
61
|
-
onError: (error) => {
|
|
62
|
-
this.dispatchEvent(new CustomEvent('error', { detail: { error } }));
|
|
63
|
-
},
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Simple chat call — no tools, just text generation.
|
|
68
|
-
* Used for validation and other non-tool-call LLM tasks.
|
|
69
|
-
*/
|
|
70
|
-
async chat(messages, abortSignal) {
|
|
71
|
-
const requestBody = {
|
|
72
|
-
model: this.config.model,
|
|
73
|
-
temperature: this.config.temperature,
|
|
74
|
-
messages,
|
|
75
|
-
};
|
|
76
|
-
(0, utils_1.modelPatch)(requestBody);
|
|
77
|
-
const response = await this.config.customFetch(`${this.config.baseURL}/chat/completions`, {
|
|
78
|
-
method: 'POST',
|
|
79
|
-
headers: {
|
|
80
|
-
'Content-Type': 'application/json',
|
|
81
|
-
...(this.config.apiKey && { Authorization: `Bearer ${this.config.apiKey}` }),
|
|
82
|
-
},
|
|
83
|
-
body: JSON.stringify(requestBody),
|
|
84
|
-
signal: abortSignal,
|
|
85
|
-
});
|
|
86
|
-
if (!response.ok) {
|
|
87
|
-
const errorData = await response.json().catch(() => ({}));
|
|
88
|
-
throw new Error(`LLM chat failed: HTTP ${response.status} - ${errorData.error?.message || response.statusText}`);
|
|
89
|
-
}
|
|
90
|
-
const data = await response.json();
|
|
91
|
-
const content = data.choices?.[0]?.message?.content || '';
|
|
92
|
-
return {
|
|
93
|
-
content,
|
|
94
|
-
usage: {
|
|
95
|
-
prompt_tokens: data.usage?.prompt_tokens ?? 0,
|
|
96
|
-
completion_tokens: data.usage?.completion_tokens ?? 0,
|
|
97
|
-
total_tokens: data.usage?.total_tokens ?? 0,
|
|
98
|
-
},
|
|
99
|
-
};
|
|
100
|
-
}
|
|
101
|
-
/**
|
|
102
|
-
* Agent loop chat — call LLM with tools and return the full assistant message.
|
|
103
|
-
* Unlike invoke(), this does NOT execute tools. The agent loop handles tool
|
|
104
|
-
* execution via its own ToolRegistry after getting the response.
|
|
105
|
-
*
|
|
106
|
-
* Uses tool_choice: 'auto' by default (LLM can choose text or tool_calls).
|
|
107
|
-
* Includes retry logic with exponential backoff.
|
|
108
|
-
*/
|
|
109
|
-
async chatWithTools(messages, tools, abortSignal, options) {
|
|
110
|
-
const signal = abortSignal || new AbortController().signal;
|
|
111
|
-
return await withRetry(async () => {
|
|
112
|
-
if (signal.aborted)
|
|
113
|
-
throw new Error('AbortError');
|
|
114
|
-
return await this.client.chat(messages, tools, signal, options);
|
|
115
|
-
}, {
|
|
116
|
-
maxRetries: this.config.maxRetries,
|
|
117
|
-
onRetry: (attempt) => {
|
|
118
|
-
this.dispatchEvent(new CustomEvent('retry', { detail: { attempt, maxAttempts: this.config.maxRetries } }));
|
|
119
|
-
},
|
|
120
|
-
onError: (error) => {
|
|
121
|
-
this.dispatchEvent(new CustomEvent('error', { detail: { error } }));
|
|
122
|
-
},
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
exports.LLM = LLM;
|
|
127
|
-
async function withRetry(fn, settings) {
|
|
128
|
-
let attempt = 0;
|
|
129
|
-
let lastError = null;
|
|
130
|
-
while (attempt <= settings.maxRetries) {
|
|
131
|
-
if (attempt > 0) {
|
|
132
|
-
settings.onRetry(attempt);
|
|
133
|
-
// Exponential backoff: 1s, 2s, 4s, 8s...
|
|
134
|
-
const delay = Math.min(1000 * Math.pow(2, attempt - 1), 30000);
|
|
135
|
-
console.log(`[Retry] Attempt ${attempt}/${settings.maxRetries}, waiting ${delay}ms...`);
|
|
136
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
137
|
-
}
|
|
138
|
-
try {
|
|
139
|
-
return await fn();
|
|
140
|
-
}
|
|
141
|
-
catch (error) {
|
|
142
|
-
if (error?.rawError?.name === 'AbortError')
|
|
143
|
-
throw error;
|
|
144
|
-
settings.onError(error);
|
|
145
|
-
if (error instanceof errors_1.InvokeError && !error.retryable)
|
|
146
|
-
throw error;
|
|
147
|
-
// Rate limit (429): use longer backoff
|
|
148
|
-
if (error instanceof errors_1.InvokeError && error.type === 'rate_limit') {
|
|
149
|
-
const rateLimitDelay = Math.min(5000 * attempt + 5000, 60000); // 5s, 10s, 15s...
|
|
150
|
-
console.log(`[Retry] Rate limit hit, waiting ${rateLimitDelay}ms...`);
|
|
151
|
-
await new Promise((resolve) => setTimeout(resolve, rateLimitDelay));
|
|
152
|
-
}
|
|
153
|
-
lastError = error;
|
|
154
|
-
attempt++;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
throw lastError;
|
|
158
|
-
}
|
package/dist/llm/types.d.ts
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Core types for LLM integration
|
|
3
|
-
*/
|
|
4
|
-
import type * as z from 'zod/v4';
|
|
5
|
-
/**
|
|
6
|
-
* Content item for multimodal messages
|
|
7
|
-
*/
|
|
8
|
-
export type ContentItem = {
|
|
9
|
-
type: 'text';
|
|
10
|
-
text: string;
|
|
11
|
-
} | {
|
|
12
|
-
type: 'image_url';
|
|
13
|
-
image_url: {
|
|
14
|
-
url: string;
|
|
15
|
-
detail?: 'low' | 'high' | 'auto';
|
|
16
|
-
};
|
|
17
|
-
};
|
|
18
|
-
/**
|
|
19
|
-
* Message format - OpenAI standard
|
|
20
|
-
*/
|
|
21
|
-
export interface Message {
|
|
22
|
-
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
23
|
-
content?: string | ContentItem[] | null;
|
|
24
|
-
tool_calls?: {
|
|
25
|
-
id: string;
|
|
26
|
-
type: 'function';
|
|
27
|
-
function: {
|
|
28
|
-
name: string;
|
|
29
|
-
arguments: string;
|
|
30
|
-
};
|
|
31
|
-
}[];
|
|
32
|
-
tool_call_id?: string;
|
|
33
|
-
name?: string;
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Tool definition - uses Zod schema
|
|
37
|
-
* Optional customJsonSchema: If provided, this JSON Schema is sent to the LLM
|
|
38
|
-
* instead of converting inputSchema via zodToOpenAITool.
|
|
39
|
-
* This allows detailed tool parameter descriptions while keeping zod validation loose.
|
|
40
|
-
*/
|
|
41
|
-
export interface Tool<TParams = any, TResult = any> {
|
|
42
|
-
description?: string;
|
|
43
|
-
inputSchema: z.ZodType<TParams>;
|
|
44
|
-
execute: (args: TParams) => Promise<TResult>;
|
|
45
|
-
/** Custom JSON Schema sent to LLM (overrides zodToOpenAITool conversion) */
|
|
46
|
-
customJsonSchema?: Record<string, any>;
|
|
47
|
-
}
|
|
48
|
-
/**
|
|
49
|
-
* Invoke options for LLM call
|
|
50
|
-
*/
|
|
51
|
-
export interface InvokeOptions {
|
|
52
|
-
/**
|
|
53
|
-
* Force LLM to call a specific tool by name.
|
|
54
|
-
* If provided: tool_choice = { type: 'function', function: { name: toolChoiceName } }
|
|
55
|
-
* If not provided: tool_choice = 'required'
|
|
56
|
-
*/
|
|
57
|
-
toolChoiceName?: string;
|
|
58
|
-
/**
|
|
59
|
-
* Response normalization function.
|
|
60
|
-
*/
|
|
61
|
-
normalizeResponse?: (response: any) => any;
|
|
62
|
-
}
|
|
63
|
-
/**
|
|
64
|
-
* Invoke result
|
|
65
|
-
*/
|
|
66
|
-
export interface InvokeResult<TResult = unknown> {
|
|
67
|
-
toolCall: {
|
|
68
|
-
name: string;
|
|
69
|
-
args: any;
|
|
70
|
-
};
|
|
71
|
-
toolResult: TResult;
|
|
72
|
-
usage: {
|
|
73
|
-
promptTokens: number;
|
|
74
|
-
completionTokens: number;
|
|
75
|
-
totalTokens: number;
|
|
76
|
-
cachedTokens?: number;
|
|
77
|
-
reasoningTokens?: number;
|
|
78
|
-
};
|
|
79
|
-
rawResponse?: unknown;
|
|
80
|
-
rawRequest?: unknown;
|
|
81
|
-
}
|
|
82
|
-
/**
|
|
83
|
-
* Chat result — returns the full assistant message without executing tools.
|
|
84
|
-
* Used by the agent loop to get the LLM's response and then process tool_calls separately.
|
|
85
|
-
*/
|
|
86
|
-
export interface ChatResult {
|
|
87
|
-
/** The full assistant message from the LLM response. */
|
|
88
|
-
message: Message;
|
|
89
|
-
/** Token usage information. */
|
|
90
|
-
usage: {
|
|
91
|
-
promptTokens: number;
|
|
92
|
-
completionTokens: number;
|
|
93
|
-
totalTokens: number;
|
|
94
|
-
cachedTokens?: number;
|
|
95
|
-
reasoningTokens?: number;
|
|
96
|
-
};
|
|
97
|
-
/** The raw API response data. */
|
|
98
|
-
rawResponse?: unknown;
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* LLM Client interface
|
|
102
|
-
*/
|
|
103
|
-
export interface LLMClient {
|
|
104
|
-
invoke(messages: Message[], tools: Record<string, Tool>, abortSignal?: AbortSignal, options?: InvokeOptions): Promise<InvokeResult>;
|
|
105
|
-
/**
|
|
106
|
-
* Call the LLM and return the full assistant message.
|
|
107
|
-
* Unlike invoke(), this does NOT execute any tools — it just returns
|
|
108
|
-
* the raw response. The caller (agent loop) processes tool_calls and
|
|
109
|
-
* executes tools separately via its own ToolRegistry.
|
|
110
|
-
*/
|
|
111
|
-
chat(messages: Message[], tools: Record<string, Tool>, abortSignal?: AbortSignal, options?: InvokeOptions): Promise<ChatResult>;
|
|
112
|
-
}
|
|
113
|
-
/**
|
|
114
|
-
* LLM configuration
|
|
115
|
-
*/
|
|
116
|
-
export interface LLMConfig {
|
|
117
|
-
baseURL: string;
|
|
118
|
-
model: string;
|
|
119
|
-
apiKey?: string;
|
|
120
|
-
temperature?: number;
|
|
121
|
-
maxRetries?: number;
|
|
122
|
-
disableNamedToolChoice?: boolean;
|
|
123
|
-
customFetch?: typeof globalThis.fetch;
|
|
124
|
-
}
|
package/dist/llm/types.js
DELETED
package/dist/llm/utils.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import * as z from 'zod/v4';
|
|
2
|
-
import type { Tool } from './types';
|
|
3
|
-
/**
|
|
4
|
-
* Convert Zod schema to OpenAI tool format
|
|
5
|
-
*/
|
|
6
|
-
export declare function zodToOpenAITool(name: string, tool: Tool): {
|
|
7
|
-
type: "function";
|
|
8
|
-
function: {
|
|
9
|
-
name: string;
|
|
10
|
-
description: string | undefined;
|
|
11
|
-
parameters: z.core.ZodStandardJSONSchemaPayload<z.ZodType<any, unknown, z.core.$ZodTypeInternals<any, unknown>>>;
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
|
-
/**
|
|
15
|
-
* Patch model specific parameters
|
|
16
|
-
*/
|
|
17
|
-
export declare function modelPatch(body: Record<string, any>): Record<string, any>;
|
|
18
|
-
/**
|
|
19
|
-
* Parse XML response from LLM and convert to AIDataExtractionResponse
|
|
20
|
-
*/
|
|
21
|
-
export declare function parseXMLExtractionResponse<T>(xmlString: string): any;
|
|
22
|
-
export declare function safeParseJson(input: string, modelFamily: any | undefined): any;
|
|
23
|
-
/**
|
|
24
|
-
* Extract content from an XML tag in a string
|
|
25
|
-
* @param xmlString - The XML string to parse
|
|
26
|
-
* @param tagName - The name of the tag to extract (case-insensitive)
|
|
27
|
-
* @returns The trimmed content of the tag, or undefined if not found
|
|
28
|
-
*/
|
|
29
|
-
export declare function extractXMLTag(xmlString: string, tagName: string): string | undefined;
|
package/dist/llm/utils.js
DELETED
|
@@ -1,284 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
-
if (k2 === undefined) k2 = k;
|
|
4
|
-
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
-
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
-
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
-
}
|
|
8
|
-
Object.defineProperty(o, k2, desc);
|
|
9
|
-
}) : (function(o, m, k, k2) {
|
|
10
|
-
if (k2 === undefined) k2 = k;
|
|
11
|
-
o[k2] = m[k];
|
|
12
|
-
}));
|
|
13
|
-
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
-
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
-
}) : function(o, v) {
|
|
16
|
-
o["default"] = v;
|
|
17
|
-
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
-
var ownKeys = function(o) {
|
|
20
|
-
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
-
var ar = [];
|
|
22
|
-
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
-
return ar;
|
|
24
|
-
};
|
|
25
|
-
return ownKeys(o);
|
|
26
|
-
};
|
|
27
|
-
return function (mod) {
|
|
28
|
-
if (mod && mod.__esModule) return mod;
|
|
29
|
-
var result = {};
|
|
30
|
-
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
-
__setModuleDefault(result, mod);
|
|
32
|
-
return result;
|
|
33
|
-
};
|
|
34
|
-
})();
|
|
35
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.zodToOpenAITool = zodToOpenAITool;
|
|
37
|
-
exports.modelPatch = modelPatch;
|
|
38
|
-
exports.parseXMLExtractionResponse = parseXMLExtractionResponse;
|
|
39
|
-
exports.safeParseJson = safeParseJson;
|
|
40
|
-
exports.extractXMLTag = extractXMLTag;
|
|
41
|
-
/**
|
|
42
|
-
* Utility functions for LLM integration
|
|
43
|
-
*/
|
|
44
|
-
const jsonrepair_1 = require("jsonrepair");
|
|
45
|
-
const z = __importStar(require("zod/v4"));
|
|
46
|
-
/**
|
|
47
|
-
* Convert Zod schema to OpenAI tool format
|
|
48
|
-
*/
|
|
49
|
-
function zodToOpenAITool(name, tool) {
|
|
50
|
-
return {
|
|
51
|
-
type: 'function',
|
|
52
|
-
function: {
|
|
53
|
-
name,
|
|
54
|
-
description: tool.description,
|
|
55
|
-
parameters: z.toJSONSchema(tool.inputSchema, { target: 'openapi-3.0' }),
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
|
-
/**
|
|
60
|
-
* Patch model specific parameters
|
|
61
|
-
*/
|
|
62
|
-
function modelPatch(body) {
|
|
63
|
-
const model = body.model || '';
|
|
64
|
-
if (!model)
|
|
65
|
-
return body;
|
|
66
|
-
const modelName = normalizeModelName(model);
|
|
67
|
-
if (modelName.startsWith('qwen') || modelName.startsWith('app-')) {
|
|
68
|
-
body.temperature = Math.max(body.temperature || 0, 1.0);
|
|
69
|
-
body.enable_thinking = false;
|
|
70
|
-
}
|
|
71
|
-
if (modelName.startsWith('claude')) {
|
|
72
|
-
body.thinking = { type: 'disabled' };
|
|
73
|
-
if (body.tool_choice === 'required') {
|
|
74
|
-
body.tool_choice = { type: 'any' };
|
|
75
|
-
}
|
|
76
|
-
else if (body.tool_choice?.function?.name) {
|
|
77
|
-
body.tool_choice = { type: 'tool', name: body.tool_choice.function.name };
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
if (modelName.startsWith('grok')) {
|
|
81
|
-
delete body.tool_choice;
|
|
82
|
-
body.thinking = { type: 'disabled', effort: 'minimal' };
|
|
83
|
-
body.reasoning = { enabled: false, effort: 'low' };
|
|
84
|
-
}
|
|
85
|
-
if (modelName.startsWith('gpt')) {
|
|
86
|
-
if (modelName.startsWith('gpt-52')) {
|
|
87
|
-
body.reasoning_effort = 'none';
|
|
88
|
-
}
|
|
89
|
-
else if (modelName.startsWith('gpt-51')) {
|
|
90
|
-
body.reasoning_effort = 'none';
|
|
91
|
-
}
|
|
92
|
-
else if (modelName.startsWith('gpt-54')) {
|
|
93
|
-
delete body.reasoning_effort;
|
|
94
|
-
}
|
|
95
|
-
else if (modelName.startsWith('gpt-5-mini')) {
|
|
96
|
-
body.reasoning_effort = 'low';
|
|
97
|
-
body.temperature = 1;
|
|
98
|
-
}
|
|
99
|
-
else if (modelName.startsWith('gpt-5')) {
|
|
100
|
-
body.reasoning_effort = 'low';
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
if (modelName.startsWith('gemini')) {
|
|
104
|
-
body.reasoning_effort = 'minimal';
|
|
105
|
-
}
|
|
106
|
-
if (modelName.startsWith('minimax')) {
|
|
107
|
-
body.temperature = Math.max(body.temperature || 0, 0.01);
|
|
108
|
-
if (body.temperature > 1)
|
|
109
|
-
body.temperature = 1;
|
|
110
|
-
delete body.parallel_tool_calls;
|
|
111
|
-
}
|
|
112
|
-
return body;
|
|
113
|
-
}
|
|
114
|
-
function normalizeModelName(modelName) {
|
|
115
|
-
let normalizedName = modelName.toLowerCase();
|
|
116
|
-
if (normalizedName.includes('/')) {
|
|
117
|
-
normalizedName = normalizedName.split('/')[1];
|
|
118
|
-
}
|
|
119
|
-
normalizedName = normalizedName.replace(/_/g, '');
|
|
120
|
-
normalizedName = normalizedName.replace(/\./g, '');
|
|
121
|
-
return normalizedName;
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Parse XML response from LLM and convert to AIDataExtractionResponse
|
|
125
|
-
*/
|
|
126
|
-
function parseXMLExtractionResponse(xmlString) {
|
|
127
|
-
const thought = extractXMLTag(xmlString, 'thought');
|
|
128
|
-
const dataJsonStr = extractXMLTag(xmlString, 'data-json');
|
|
129
|
-
const errorsStr = extractXMLTag(xmlString, 'errors');
|
|
130
|
-
let data = '';
|
|
131
|
-
if (dataJsonStr) {
|
|
132
|
-
try {
|
|
133
|
-
data = safeParseJson(dataJsonStr, undefined);
|
|
134
|
-
}
|
|
135
|
-
catch (e) {
|
|
136
|
-
throw new Error(`Failed to parse data-json: ${e}`);
|
|
137
|
-
}
|
|
138
|
-
}
|
|
139
|
-
// Parse errors (optional)
|
|
140
|
-
let errors;
|
|
141
|
-
if (errorsStr) {
|
|
142
|
-
try {
|
|
143
|
-
const parsedErrors = safeParseJson(errorsStr, undefined);
|
|
144
|
-
if (Array.isArray(parsedErrors)) {
|
|
145
|
-
errors = parsedErrors;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
catch (e) {
|
|
149
|
-
// If errors parsing fails, just ignore it
|
|
150
|
-
}
|
|
151
|
-
}
|
|
152
|
-
return {
|
|
153
|
-
...(thought ? { thought } : {}),
|
|
154
|
-
data: data || xmlString,
|
|
155
|
-
...(errors && errors.length > 0 ? { errors } : {}),
|
|
156
|
-
};
|
|
157
|
-
}
|
|
158
|
-
function safeParseJson(input, modelFamily) {
|
|
159
|
-
const cleanJsonString = extractJSONFromCodeBlock(input);
|
|
160
|
-
// match the point
|
|
161
|
-
if (cleanJsonString?.match(/\((\d+),(\d+)\)/)) {
|
|
162
|
-
return cleanJsonString
|
|
163
|
-
.match(/\((\d+),(\d+)\)/)
|
|
164
|
-
?.slice(1)
|
|
165
|
-
.map(Number);
|
|
166
|
-
}
|
|
167
|
-
let parsed;
|
|
168
|
-
let lastError;
|
|
169
|
-
try {
|
|
170
|
-
parsed = JSON.parse(cleanJsonString);
|
|
171
|
-
return normalizeJsonObject(parsed);
|
|
172
|
-
}
|
|
173
|
-
catch (error) {
|
|
174
|
-
lastError = error;
|
|
175
|
-
}
|
|
176
|
-
try {
|
|
177
|
-
parsed = JSON.parse((0, jsonrepair_1.jsonrepair)(cleanJsonString));
|
|
178
|
-
return normalizeJsonObject(parsed);
|
|
179
|
-
}
|
|
180
|
-
catch (error) {
|
|
181
|
-
lastError = error;
|
|
182
|
-
}
|
|
183
|
-
if (modelFamily === 'doubao-vision' || isUITars(modelFamily)) {
|
|
184
|
-
const jsonString = preprocessDoubaoBboxJson(cleanJsonString);
|
|
185
|
-
try {
|
|
186
|
-
parsed = JSON.parse((0, jsonrepair_1.jsonrepair)(jsonString));
|
|
187
|
-
return normalizeJsonObject(parsed);
|
|
188
|
-
}
|
|
189
|
-
catch (error) {
|
|
190
|
-
lastError = error;
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
throw Error(`failed to parse LLM response into JSON. Error - ${String(lastError ?? 'unknown error')}. Response - \n ${input}`);
|
|
194
|
-
}
|
|
195
|
-
/**
|
|
196
|
-
* Extract content from an XML tag in a string
|
|
197
|
-
* @param xmlString - The XML string to parse
|
|
198
|
-
* @param tagName - The name of the tag to extract (case-insensitive)
|
|
199
|
-
* @returns The trimmed content of the tag, or undefined if not found
|
|
200
|
-
*/
|
|
201
|
-
function extractXMLTag(xmlString, tagName) {
|
|
202
|
-
const regex = new RegExp(`<${tagName}>([\\s\\S]*?)</${tagName}>`, 'i');
|
|
203
|
-
const match = xmlString.match(regex);
|
|
204
|
-
return match ? match[1].trim() : undefined;
|
|
205
|
-
}
|
|
206
|
-
function extractJSONFromCodeBlock(response) {
|
|
207
|
-
try {
|
|
208
|
-
// First, try to match a JSON object directly in the response
|
|
209
|
-
const jsonMatch = response.match(/^\s*(\{[\s\S]*\})\s*$/);
|
|
210
|
-
if (jsonMatch) {
|
|
211
|
-
return jsonMatch[1];
|
|
212
|
-
}
|
|
213
|
-
// If no direct JSON object is found, try to extract JSON from a code block
|
|
214
|
-
const codeBlockMatch = response.match(/```(?:json)?\s*(\{[\s\S]*?\})\s*```/);
|
|
215
|
-
if (codeBlockMatch) {
|
|
216
|
-
return codeBlockMatch[1];
|
|
217
|
-
}
|
|
218
|
-
// If no code block is found, try to find a JSON-like structure in the text
|
|
219
|
-
const jsonLikeMatch = response.match(/\{[\s\S]*\}/);
|
|
220
|
-
if (jsonLikeMatch) {
|
|
221
|
-
return jsonLikeMatch[0];
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
catch { }
|
|
225
|
-
// If no JSON-like structure is found, return the original response
|
|
226
|
-
return response;
|
|
227
|
-
}
|
|
228
|
-
/**
|
|
229
|
-
* Normalize a parsed JSON object by trimming whitespace from:
|
|
230
|
-
* 1. All object keys (e.g., " prompt " -> "prompt")
|
|
231
|
-
* 2. All string values (e.g., " Tap " -> "Tap")
|
|
232
|
-
* This handles LLM output that may include leading/trailing spaces.
|
|
233
|
-
*/
|
|
234
|
-
function normalizeJsonObject(obj) {
|
|
235
|
-
// Handle null and undefined
|
|
236
|
-
if (obj === null || obj === undefined) {
|
|
237
|
-
return obj;
|
|
238
|
-
}
|
|
239
|
-
// Handle arrays - recursively normalize each element
|
|
240
|
-
if (Array.isArray(obj)) {
|
|
241
|
-
return obj.map((item) => normalizeJsonObject(item));
|
|
242
|
-
}
|
|
243
|
-
// Handle objects
|
|
244
|
-
if (typeof obj === 'object') {
|
|
245
|
-
const normalized = {};
|
|
246
|
-
for (const [key, value] of Object.entries(obj)) {
|
|
247
|
-
// Trim the key to remove leading/trailing spaces
|
|
248
|
-
const trimmedKey = key.trim();
|
|
249
|
-
// Recursively normalize the value
|
|
250
|
-
let normalizedValue = normalizeJsonObject(value);
|
|
251
|
-
// Trim all string values
|
|
252
|
-
if (typeof normalizedValue === 'string') {
|
|
253
|
-
normalizedValue = normalizedValue.trim();
|
|
254
|
-
}
|
|
255
|
-
normalized[trimmedKey] = normalizedValue;
|
|
256
|
-
}
|
|
257
|
-
return normalized;
|
|
258
|
-
}
|
|
259
|
-
// Handle primitive strings
|
|
260
|
-
if (typeof obj === 'string') {
|
|
261
|
-
return obj.trim();
|
|
262
|
-
}
|
|
263
|
-
// Return other primitives as-is
|
|
264
|
-
return obj;
|
|
265
|
-
}
|
|
266
|
-
function preprocessDoubaoBboxJson(input) {
|
|
267
|
-
if (input.includes('bbox')) {
|
|
268
|
-
// when its values like 940 445 969 490, replace all /\d+\s+\d+/g with /$1,$2/g
|
|
269
|
-
while (/\d+\s+\d+/.test(input)) {
|
|
270
|
-
input = input.replace(/(\d+)\s+(\d+)/g, '$1,$2');
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
return input;
|
|
274
|
-
}
|
|
275
|
-
/**
|
|
276
|
-
* Check if the modelFamily is a UI-TARS variant
|
|
277
|
-
* @param modelFamily The model family to check
|
|
278
|
-
* @returns true if modelFamily is any UI-TARS variant
|
|
279
|
-
*/
|
|
280
|
-
function isUITars(modelFamily) {
|
|
281
|
-
return (modelFamily === 'vlm-ui-tars' ||
|
|
282
|
-
modelFamily === 'vlm-ui-tars-doubao' ||
|
|
283
|
-
modelFamily === 'vlm-ui-tars-doubao-1.5');
|
|
284
|
-
}
|
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SKILL.md Frontmatter Parser
|
|
3
|
-
*
|
|
4
|
-
* Reference: gemini-cli skillLoader.ts (skills/skillLoader.ts L34-110)
|
|
5
|
-
* Parses YAML frontmatter from SKILL.md files to extract name, description,
|
|
6
|
-
* and allowed-tools. Uses the 'yaml' npm package for robust YAML parsing,
|
|
7
|
-
* with a fallback simple parser for malformed YAML (e.g. descriptions with colons).
|
|
8
|
-
*/
|
|
9
|
-
/**
|
|
10
|
-
* Regex for extracting frontmatter from markdown files.
|
|
11
|
-
* Matches ---\n<yaml content>\n--- at the start of the file.
|
|
12
|
-
*/
|
|
13
|
-
export declare const FRONTMATTER_REGEX: RegExp;
|
|
14
|
-
/**
|
|
15
|
-
* Parsed frontmatter result.
|
|
16
|
-
*/
|
|
17
|
-
export interface ParsedFrontmatter {
|
|
18
|
-
name: string;
|
|
19
|
-
description: string;
|
|
20
|
-
/** Allowed tools for this skill (from frontmatter 'allowed-tools' field). */
|
|
21
|
-
allowedTools?: string[];
|
|
22
|
-
/** Output artifact type for Pipeline routing (e.g. 'code_knowledge', 'case_list'). */
|
|
23
|
-
outputType?: string;
|
|
24
|
-
/** The body content after the closing ---. */
|
|
25
|
-
body: string;
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Parse frontmatter from a SKILL.md file string.
|
|
29
|
-
*
|
|
30
|
-
* Returns the name, description, allowedTools from the YAML frontmatter,
|
|
31
|
-
* and the body (content after the frontmatter).
|
|
32
|
-
*
|
|
33
|
-
* @param content The full SKILL.md file content
|
|
34
|
-
* @returns Parsed frontmatter and body, or null if no valid frontmatter found
|
|
35
|
-
*/
|
|
36
|
-
export declare function parseSkillFrontmatter(content: string): ParsedFrontmatter | null;
|
|
37
|
-
/**
|
|
38
|
-
* Parse YAML frontmatter content using the yaml library
|
|
39
|
-
* with a fallback to simple key-value parsing.
|
|
40
|
-
*
|
|
41
|
-
* Reference: gemini-cli skillLoader.ts parseFrontmatter (L41-61)
|
|
42
|
-
*
|
|
43
|
-
* Uses YAML.parse() (yaml v2 API) instead of the deprecated YAML.load().
|
|
44
|
-
*/
|
|
45
|
-
export declare function parseFrontmatterYaml(yamlContent: string): {
|
|
46
|
-
name: string;
|
|
47
|
-
description: string;
|
|
48
|
-
allowedTools?: string[];
|
|
49
|
-
outputType?: string;
|
|
50
|
-
} | null;
|