eff-u-code 2.0.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/LICENSE +21 -0
- package/README.md +256 -0
- package/bin/fuck-u-code-mcp.js +2 -0
- package/bin/fuck-u-code.js +2 -0
- package/bin/postinstall.js +53 -0
- package/dist/ai/index.d.ts +34 -0
- package/dist/ai/index.d.ts.map +1 -0
- package/dist/ai/index.js +227 -0
- package/dist/ai/index.js.map +1 -0
- package/dist/ai/prompts/code-review.d.ts +9 -0
- package/dist/ai/prompts/code-review.d.ts.map +1 -0
- package/dist/ai/prompts/code-review.js +61 -0
- package/dist/ai/prompts/code-review.js.map +1 -0
- package/dist/ai/providers/anthropic.d.ts +11 -0
- package/dist/ai/providers/anthropic.d.ts.map +1 -0
- package/dist/ai/providers/anthropic.js +60 -0
- package/dist/ai/providers/anthropic.js.map +1 -0
- package/dist/ai/providers/fetch.d.ts +10 -0
- package/dist/ai/providers/fetch.d.ts.map +1 -0
- package/dist/ai/providers/fetch.js +50 -0
- package/dist/ai/providers/fetch.js.map +1 -0
- package/dist/ai/providers/gemini.d.ts +12 -0
- package/dist/ai/providers/gemini.d.ts.map +1 -0
- package/dist/ai/providers/gemini.js +66 -0
- package/dist/ai/providers/gemini.js.map +1 -0
- package/dist/ai/providers/ollama.d.ts +11 -0
- package/dist/ai/providers/ollama.d.ts.map +1 -0
- package/dist/ai/providers/ollama.js +54 -0
- package/dist/ai/providers/ollama.js.map +1 -0
- package/dist/ai/providers/openai.d.ts +11 -0
- package/dist/ai/providers/openai.d.ts.map +1 -0
- package/dist/ai/providers/openai.js +52 -0
- package/dist/ai/providers/openai.js.map +1 -0
- package/dist/ai/selector.d.ts +19 -0
- package/dist/ai/selector.d.ts.map +1 -0
- package/dist/ai/selector.js +145 -0
- package/dist/ai/selector.js.map +1 -0
- package/dist/ai/types.d.ts +120 -0
- package/dist/ai/types.d.ts.map +1 -0
- package/dist/ai/types.js +6 -0
- package/dist/ai/types.js.map +1 -0
- package/dist/analyzer/concurrent-analyzer.d.ts +11 -0
- package/dist/analyzer/concurrent-analyzer.d.ts.map +1 -0
- package/dist/analyzer/concurrent-analyzer.js +67 -0
- package/dist/analyzer/concurrent-analyzer.js.map +1 -0
- package/dist/analyzer/file-discovery.d.ts +23 -0
- package/dist/analyzer/file-discovery.d.ts.map +1 -0
- package/dist/analyzer/file-discovery.js +64 -0
- package/dist/analyzer/file-discovery.js.map +1 -0
- package/dist/analyzer/index.d.ts +27 -0
- package/dist/analyzer/index.d.ts.map +1 -0
- package/dist/analyzer/index.js +64 -0
- package/dist/analyzer/index.js.map +1 -0
- package/dist/cli/commands/ai-review.d.ts +6 -0
- package/dist/cli/commands/ai-review.d.ts.map +1 -0
- package/dist/cli/commands/ai-review.js +213 -0
- package/dist/cli/commands/ai-review.js.map +1 -0
- package/dist/cli/commands/analyze.d.ts +6 -0
- package/dist/cli/commands/analyze.d.ts.map +1 -0
- package/dist/cli/commands/analyze.js +145 -0
- package/dist/cli/commands/analyze.js.map +1 -0
- package/dist/cli/commands/config.d.ts +6 -0
- package/dist/cli/commands/config.d.ts.map +1 -0
- package/dist/cli/commands/config.js +147 -0
- package/dist/cli/commands/config.js.map +1 -0
- package/dist/cli/commands/mcp-install.d.ts +9 -0
- package/dist/cli/commands/mcp-install.d.ts.map +1 -0
- package/dist/cli/commands/mcp-install.js +102 -0
- package/dist/cli/commands/mcp-install.js.map +1 -0
- package/dist/cli/index.d.ts +7 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +69 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/output/ai-review-output.d.ts +20 -0
- package/dist/cli/output/ai-review-output.d.ts.map +1 -0
- package/dist/cli/output/ai-review-output.js +324 -0
- package/dist/cli/output/ai-review-output.js.map +1 -0
- package/dist/cli/output/console.d.ts +31 -0
- package/dist/cli/output/console.d.ts.map +1 -0
- package/dist/cli/output/console.js +571 -0
- package/dist/cli/output/console.js.map +1 -0
- package/dist/cli/output/html.d.ts +20 -0
- package/dist/cli/output/html.d.ts.map +1 -0
- package/dist/cli/output/html.js +339 -0
- package/dist/cli/output/html.js.map +1 -0
- package/dist/cli/output/json.d.ts +8 -0
- package/dist/cli/output/json.d.ts.map +1 -0
- package/dist/cli/output/json.js +46 -0
- package/dist/cli/output/json.js.map +1 -0
- package/dist/cli/output/markdown.d.ts +17 -0
- package/dist/cli/output/markdown.d.ts.map +1 -0
- package/dist/cli/output/markdown.js +323 -0
- package/dist/cli/output/markdown.js.map +1 -0
- package/dist/cli/output/stats.d.ts +35 -0
- package/dist/cli/output/stats.d.ts.map +1 -0
- package/dist/cli/output/stats.js +63 -0
- package/dist/cli/output/stats.js.map +1 -0
- package/dist/cli/output/terminal-markdown.d.ts +23 -0
- package/dist/cli/output/terminal-markdown.d.ts.map +1 -0
- package/dist/cli/output/terminal-markdown.js +159 -0
- package/dist/cli/output/terminal-markdown.js.map +1 -0
- package/dist/config/index.d.ts +27 -0
- package/dist/config/index.d.ts.map +1 -0
- package/dist/config/index.js +266 -0
- package/dist/config/index.js.map +1 -0
- package/dist/config/schema.d.ts +179 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +85 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/gitignore/index.d.ts +5 -0
- package/dist/gitignore/index.d.ts.map +1 -0
- package/dist/gitignore/index.js +5 -0
- package/dist/gitignore/index.js.map +1 -0
- package/dist/gitignore/parser.d.ts +32 -0
- package/dist/gitignore/parser.d.ts.map +1 -0
- package/dist/gitignore/parser.js +110 -0
- package/dist/gitignore/parser.js.map +1 -0
- package/dist/gitignore/parser.test.d.ts +2 -0
- package/dist/gitignore/parser.test.d.ts.map +1 -0
- package/dist/gitignore/parser.test.js +217 -0
- package/dist/gitignore/parser.test.js.map +1 -0
- package/dist/i18n/index.d.ts +19 -0
- package/dist/i18n/index.d.ts.map +1 -0
- package/dist/i18n/index.js +43 -0
- package/dist/i18n/index.js.map +1 -0
- package/dist/i18n/locales/en.json +320 -0
- package/dist/i18n/locales/ru.json +320 -0
- package/dist/i18n/locales/zh.json +320 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp/server.d.ts +9 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +156 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/metrics/complexity/cognitive.d.ts +25 -0
- package/dist/metrics/complexity/cognitive.d.ts.map +1 -0
- package/dist/metrics/complexity/cognitive.js +109 -0
- package/dist/metrics/complexity/cognitive.js.map +1 -0
- package/dist/metrics/complexity/cyclomatic.d.ts +21 -0
- package/dist/metrics/complexity/cyclomatic.d.ts.map +1 -0
- package/dist/metrics/complexity/cyclomatic.js +111 -0
- package/dist/metrics/complexity/cyclomatic.js.map +1 -0
- package/dist/metrics/complexity/nesting-depth.d.ts +19 -0
- package/dist/metrics/complexity/nesting-depth.d.ts.map +1 -0
- package/dist/metrics/complexity/nesting-depth.js +97 -0
- package/dist/metrics/complexity/nesting-depth.js.map +1 -0
- package/dist/metrics/documentation/comment-ratio.d.ts +21 -0
- package/dist/metrics/documentation/comment-ratio.d.ts.map +1 -0
- package/dist/metrics/documentation/comment-ratio.js +91 -0
- package/dist/metrics/documentation/comment-ratio.js.map +1 -0
- package/dist/metrics/duplication/code-duplication.d.ts +24 -0
- package/dist/metrics/duplication/code-duplication.d.ts.map +1 -0
- package/dist/metrics/duplication/code-duplication.js +167 -0
- package/dist/metrics/duplication/code-duplication.js.map +1 -0
- package/dist/metrics/duplication/code-duplication.test.d.ts +2 -0
- package/dist/metrics/duplication/code-duplication.test.d.ts.map +1 -0
- package/dist/metrics/duplication/code-duplication.test.js +612 -0
- package/dist/metrics/duplication/code-duplication.test.js.map +1 -0
- package/dist/metrics/error/error-handling.d.ts +23 -0
- package/dist/metrics/error/error-handling.d.ts.map +1 -0
- package/dist/metrics/error/error-handling.js +164 -0
- package/dist/metrics/error/error-handling.js.map +1 -0
- package/dist/metrics/error/error-handling.test.d.ts +2 -0
- package/dist/metrics/error/error-handling.test.d.ts.map +1 -0
- package/dist/metrics/error/error-handling.test.js +349 -0
- package/dist/metrics/error/error-handling.test.js.map +1 -0
- package/dist/metrics/index.d.ts +21 -0
- package/dist/metrics/index.d.ts.map +1 -0
- package/dist/metrics/index.js +50 -0
- package/dist/metrics/index.js.map +1 -0
- package/dist/metrics/naming/convention.d.ts +22 -0
- package/dist/metrics/naming/convention.d.ts.map +1 -0
- package/dist/metrics/naming/convention.js +117 -0
- package/dist/metrics/naming/convention.js.map +1 -0
- package/dist/metrics/size/file-length.d.ts +19 -0
- package/dist/metrics/size/file-length.d.ts.map +1 -0
- package/dist/metrics/size/file-length.js +68 -0
- package/dist/metrics/size/file-length.js.map +1 -0
- package/dist/metrics/size/function-length.d.ts +20 -0
- package/dist/metrics/size/function-length.d.ts.map +1 -0
- package/dist/metrics/size/function-length.js +101 -0
- package/dist/metrics/size/function-length.js.map +1 -0
- package/dist/metrics/size/parameter-count.d.ts +19 -0
- package/dist/metrics/size/parameter-count.d.ts.map +1 -0
- package/dist/metrics/size/parameter-count.js +97 -0
- package/dist/metrics/size/parameter-count.js.map +1 -0
- package/dist/metrics/structure/structure-analysis.d.ts +24 -0
- package/dist/metrics/structure/structure-analysis.d.ts.map +1 -0
- package/dist/metrics/structure/structure-analysis.js +223 -0
- package/dist/metrics/structure/structure-analysis.js.map +1 -0
- package/dist/metrics/structure/structure-analysis.test.d.ts +2 -0
- package/dist/metrics/structure/structure-analysis.test.d.ts.map +1 -0
- package/dist/metrics/structure/structure-analysis.test.js +342 -0
- package/dist/metrics/structure/structure-analysis.test.js.map +1 -0
- package/dist/metrics/types.d.ts +71 -0
- package/dist/metrics/types.d.ts.map +1 -0
- package/dist/metrics/types.js +5 -0
- package/dist/metrics/types.js.map +1 -0
- package/dist/parser/generic-parser.d.ts +28 -0
- package/dist/parser/generic-parser.d.ts.map +1 -0
- package/dist/parser/generic-parser.js +218 -0
- package/dist/parser/generic-parser.js.map +1 -0
- package/dist/parser/index.d.ts +19 -0
- package/dist/parser/index.d.ts.map +1 -0
- package/dist/parser/index.js +52 -0
- package/dist/parser/index.js.map +1 -0
- package/dist/parser/regex-parser.d.ts +46 -0
- package/dist/parser/regex-parser.d.ts.map +1 -0
- package/dist/parser/regex-parser.js +560 -0
- package/dist/parser/regex-parser.js.map +1 -0
- package/dist/parser/tree-sitter-parser.d.ts +50 -0
- package/dist/parser/tree-sitter-parser.d.ts.map +1 -0
- package/dist/parser/tree-sitter-parser.js +707 -0
- package/dist/parser/tree-sitter-parser.js.map +1 -0
- package/dist/parser/types.d.ts +52 -0
- package/dist/parser/types.d.ts.map +1 -0
- package/dist/parser/types.js +49 -0
- package/dist/parser/types.js.map +1 -0
- package/dist/scoring/index.d.ts +14 -0
- package/dist/scoring/index.d.ts.map +1 -0
- package/dist/scoring/index.js +80 -0
- package/dist/scoring/index.js.map +1 -0
- package/dist/utils/fs.d.ts +24 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +61 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/logger.d.ts +13 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +43 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/markdown.d.ts +16 -0
- package/dist/utils/markdown.d.ts.map +1 -0
- package/dist/utils/markdown.js +303 -0
- package/dist/utils/markdown.js.map +1 -0
- package/dist/utils/progress.d.ts +24 -0
- package/dist/utils/progress.d.ts.map +1 -0
- package/dist/utils/progress.js +79 -0
- package/dist/utils/progress.js.map +1 -0
- package/dist/utils/terminal.d.ts +62 -0
- package/dist/utils/terminal.d.ts.map +1 -0
- package/dist/utils/terminal.js +207 -0
- package/dist/utils/terminal.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code review prompt templates
|
|
3
|
+
*
|
|
4
|
+
* Generates system prompts for AI code review. Uses XML-tagged structure
|
|
5
|
+
* for clear section boundaries. Output is pure Markdown.
|
|
6
|
+
*/
|
|
7
|
+
import { t } from '../../i18n/index.js';
|
|
8
|
+
/** Get localized code review system prompt */
|
|
9
|
+
export function getCodeReviewPrompt() {
|
|
10
|
+
return `<role>
|
|
11
|
+
${t('ai_prompt_role')}
|
|
12
|
+
</role>
|
|
13
|
+
|
|
14
|
+
<output-rules>
|
|
15
|
+
${t('ai_prompt_output_rules')}
|
|
16
|
+
</output-rules>
|
|
17
|
+
|
|
18
|
+
<metrics-definition>
|
|
19
|
+
- ${t('ai_prompt_metrics_complexity')}
|
|
20
|
+
- ${t('ai_prompt_metrics_nesting')}
|
|
21
|
+
- ${t('ai_prompt_metrics_params')}
|
|
22
|
+
- ${t('ai_prompt_metrics_lines')}
|
|
23
|
+
- ${t('ai_prompt_metrics_duplication')}
|
|
24
|
+
- ${t('ai_prompt_metrics_structure')}
|
|
25
|
+
- ${t('ai_prompt_metrics_error')}
|
|
26
|
+
|
|
27
|
+
${t('ai_prompt_metrics_note')}
|
|
28
|
+
</metrics-definition>
|
|
29
|
+
|
|
30
|
+
<constraints>
|
|
31
|
+
- ${t('ai_prompt_constraint_no_repeat')}
|
|
32
|
+
- ${t('ai_prompt_constraint_location')}
|
|
33
|
+
- ${t('ai_prompt_constraint_executable')}
|
|
34
|
+
- ${t('ai_prompt_constraint_priority')}
|
|
35
|
+
- ${t('ai_prompt_constraint_lang_aware')}
|
|
36
|
+
</constraints>
|
|
37
|
+
|
|
38
|
+
<output-format>
|
|
39
|
+
${t('ai_prompt_output_instruction')}
|
|
40
|
+
|
|
41
|
+
## 🔍 ${t('ai_prompt_summary')}
|
|
42
|
+
${t('ai_prompt_output_assessment')}
|
|
43
|
+
|
|
44
|
+
## 💩 ${t('ai_prompt_key_issues')}
|
|
45
|
+
${t('ai_prompt_output_critical_item')}
|
|
46
|
+
|
|
47
|
+
## 🔧 ${t('ai_prompt_refactoring')}
|
|
48
|
+
${t('ai_prompt_output_refactor_item')}
|
|
49
|
+
|
|
50
|
+
## 🔒 ${t('ai_prompt_security')}
|
|
51
|
+
${t('ai_prompt_output_security_item')}
|
|
52
|
+
</output-format>
|
|
53
|
+
|
|
54
|
+
<quality-rules>
|
|
55
|
+
- ${t('ai_prompt_quality_specific')}
|
|
56
|
+
- ${t('ai_prompt_quality_evidence')}
|
|
57
|
+
- ${t('ai_prompt_quality_concise')}
|
|
58
|
+
- ${t('ai_prompt_quality_syntax')}
|
|
59
|
+
</quality-rules>`;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=code-review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-review.js","sourceRoot":"","sources":["../../../src/ai/prompts/code-review.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,qBAAqB,CAAC;AAExC,8CAA8C;AAC9C,MAAM,UAAU,mBAAmB;IACjC,OAAO;EACP,CAAC,CAAC,gBAAgB,CAAC;;;;EAInB,CAAC,CAAC,wBAAwB,CAAC;;;;IAIzB,CAAC,CAAC,8BAA8B,CAAC;IACjC,CAAC,CAAC,2BAA2B,CAAC;IAC9B,CAAC,CAAC,0BAA0B,CAAC;IAC7B,CAAC,CAAC,yBAAyB,CAAC;IAC5B,CAAC,CAAC,+BAA+B,CAAC;IAClC,CAAC,CAAC,6BAA6B,CAAC;IAChC,CAAC,CAAC,yBAAyB,CAAC;;EAE9B,CAAC,CAAC,wBAAwB,CAAC;;;;IAIzB,CAAC,CAAC,gCAAgC,CAAC;IACnC,CAAC,CAAC,+BAA+B,CAAC;IAClC,CAAC,CAAC,iCAAiC,CAAC;IACpC,CAAC,CAAC,+BAA+B,CAAC;IAClC,CAAC,CAAC,iCAAiC,CAAC;;;;EAItC,CAAC,CAAC,8BAA8B,CAAC;;QAE3B,CAAC,CAAC,mBAAmB,CAAC;EAC5B,CAAC,CAAC,6BAA6B,CAAC;;QAE1B,CAAC,CAAC,sBAAsB,CAAC;EAC/B,CAAC,CAAC,gCAAgC,CAAC;;QAE7B,CAAC,CAAC,uBAAuB,CAAC;EAChC,CAAC,CAAC,gCAAgC,CAAC;;QAE7B,CAAC,CAAC,oBAAoB,CAAC;EAC7B,CAAC,CAAC,gCAAgC,CAAC;;;;IAIjC,CAAC,CAAC,4BAA4B,CAAC;IAC/B,CAAC,CAAC,4BAA4B,CAAC;IAC/B,CAAC,CAAC,2BAA2B,CAAC;IAC9B,CAAC,CAAC,0BAA0B,CAAC;iBAChB,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic provider
|
|
3
|
+
*/
|
|
4
|
+
import type { Provider, ProviderContext, ChatRequest, ChatResponse, ChatStreamResponse } from '../types.js';
|
|
5
|
+
export declare class AnthropicProvider implements Provider {
|
|
6
|
+
private ctx;
|
|
7
|
+
constructor(ctx: ProviderContext);
|
|
8
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
9
|
+
chatStream(_request: ChatRequest): Promise<ReadableStream<ChatStreamResponse>>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../src/ai/providers/anthropic.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EACf,WAAW,EACX,YAAY,EACZ,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAGrB,qBAAa,iBAAkB,YAAW,QAAQ;IAChD,OAAO,CAAC,GAAG,CAAkB;gBAEjB,GAAG,EAAE,eAAe;IAI1B,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IA6DvD,UAAU,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;CAG/E"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic provider
|
|
3
|
+
*/
|
|
4
|
+
import { fetchWithRetry } from './fetch.js';
|
|
5
|
+
export class AnthropicProvider {
|
|
6
|
+
ctx;
|
|
7
|
+
constructor(ctx) {
|
|
8
|
+
this.ctx = ctx;
|
|
9
|
+
}
|
|
10
|
+
async chat(request) {
|
|
11
|
+
const model = request.model ?? this.ctx.model;
|
|
12
|
+
const maxTokens = request.maxTokens ?? this.ctx.maxTokens;
|
|
13
|
+
const temperature = request.temperature ?? this.ctx.temperature;
|
|
14
|
+
// Anthropic API requires system message as separate field
|
|
15
|
+
const systemMessage = request.messages.find((m) => m.role === 'system');
|
|
16
|
+
const otherMessages = request.messages.filter((m) => m.role !== 'system');
|
|
17
|
+
const response = await fetchWithRetry(this.ctx, `${this.ctx.baseUrl}/v1/messages`, {
|
|
18
|
+
method: 'POST',
|
|
19
|
+
headers: {
|
|
20
|
+
'x-api-key': this.ctx.apiKey,
|
|
21
|
+
'Content-Type': 'application/json',
|
|
22
|
+
'anthropic-version': '2023-06-01',
|
|
23
|
+
},
|
|
24
|
+
body: JSON.stringify({
|
|
25
|
+
model,
|
|
26
|
+
max_tokens: maxTokens,
|
|
27
|
+
temperature,
|
|
28
|
+
top_p: this.ctx.topP,
|
|
29
|
+
system: systemMessage?.content,
|
|
30
|
+
messages: otherMessages.map((m) => ({
|
|
31
|
+
role: m.role,
|
|
32
|
+
content: m.content,
|
|
33
|
+
})),
|
|
34
|
+
}),
|
|
35
|
+
});
|
|
36
|
+
const data = (await response.json());
|
|
37
|
+
const content = data.content?.find((c) => c.type === 'text')?.text ?? '';
|
|
38
|
+
return {
|
|
39
|
+
id: data.id ?? `msg-${Date.now().toString(36)}`,
|
|
40
|
+
model: data.model ?? model,
|
|
41
|
+
choices: [
|
|
42
|
+
{
|
|
43
|
+
index: 0,
|
|
44
|
+
message: { role: 'assistant', content },
|
|
45
|
+
finishReason: data.stop_reason ?? 'stop',
|
|
46
|
+
},
|
|
47
|
+
],
|
|
48
|
+
usage: {
|
|
49
|
+
promptTokens: data.usage?.input_tokens ?? 0,
|
|
50
|
+
completionTokens: data.usage?.output_tokens ?? 0,
|
|
51
|
+
totalTokens: (data.usage?.input_tokens ?? 0) + (data.usage?.output_tokens ?? 0),
|
|
52
|
+
},
|
|
53
|
+
provider: this.ctx.providerName,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
chatStream(_request) {
|
|
57
|
+
return Promise.reject(new Error('Streaming not implemented for CLI'));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=anthropic.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"anthropic.js","sourceRoot":"","sources":["../../../src/ai/providers/anthropic.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared HTTP fetch with retry and exponential backoff
|
|
3
|
+
*/
|
|
4
|
+
import type { ProviderContext } from '../types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Fetch with retry, timeout, and exponential backoff
|
|
7
|
+
* Reads error response body for detailed error messages
|
|
8
|
+
*/
|
|
9
|
+
export declare function fetchWithRetry(ctx: Pick<ProviderContext, 'timeout' | 'maxRetries'>, url: string, options: RequestInit): Promise<Response>;
|
|
10
|
+
//# sourceMappingURL=fetch.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.d.ts","sourceRoot":"","sources":["../../../src/ai/providers/fetch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAEnD;;;GAGG;AACH,wBAAsB,cAAc,CAClC,GAAG,EAAE,IAAI,CAAC,eAAe,EAAE,SAAS,GAAG,YAAY,CAAC,EACpD,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,WAAW,GACnB,OAAO,CAAC,QAAQ,CAAC,CAgDnB"}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared HTTP fetch with retry and exponential backoff
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Fetch with retry, timeout, and exponential backoff
|
|
6
|
+
* Reads error response body for detailed error messages
|
|
7
|
+
*/
|
|
8
|
+
export async function fetchWithRetry(ctx, url, options) {
|
|
9
|
+
let lastError = null;
|
|
10
|
+
for (let attempt = 0; attempt <= ctx.maxRetries; attempt++) {
|
|
11
|
+
try {
|
|
12
|
+
const controller = new AbortController();
|
|
13
|
+
const timeoutId = setTimeout(() => controller.abort(), ctx.timeout * 1000);
|
|
14
|
+
const response = await fetch(url, {
|
|
15
|
+
...options,
|
|
16
|
+
signal: controller.signal,
|
|
17
|
+
});
|
|
18
|
+
clearTimeout(timeoutId);
|
|
19
|
+
if (response.ok) {
|
|
20
|
+
return response;
|
|
21
|
+
}
|
|
22
|
+
// Read error body for detailed error message
|
|
23
|
+
let errorDetail = '';
|
|
24
|
+
try {
|
|
25
|
+
const body = await response.text();
|
|
26
|
+
const parsed = JSON.parse(body);
|
|
27
|
+
errorDetail = parsed.error?.message || parsed.message || body.slice(0, 200);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
errorDetail = response.statusText;
|
|
31
|
+
}
|
|
32
|
+
lastError = new Error(`HTTP ${response.status}: ${errorDetail}`);
|
|
33
|
+
// Don't retry on client errors (4xx) except 429 (rate limit)
|
|
34
|
+
if (response.status >= 400 && response.status < 500 && response.status !== 429) {
|
|
35
|
+
throw lastError;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
if (error instanceof Error && error.message.startsWith('HTTP 4')) {
|
|
40
|
+
throw error;
|
|
41
|
+
}
|
|
42
|
+
lastError = error;
|
|
43
|
+
}
|
|
44
|
+
if (attempt < ctx.maxRetries) {
|
|
45
|
+
await new Promise((resolve) => setTimeout(resolve, (attempt + 1) * 1000));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
throw lastError ?? new Error('Request failed');
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=fetch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fetch.js","sourceRoot":"","sources":["../../../src/ai/providers/fetch.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAoD,EACpD,GAAW,EACX,OAAoB;IAEpB,IAAI,SAAS,GAAiB,IAAI,CAAC;IAEnC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,GAAG,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;QAC3D,IAAI,CAAC;YACH,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;YACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;YAE3E,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,GAAG,OAAO;gBACV,MAAM,EAAE,UAAU,CAAC,MAAM;aAC1B,CAAC,CAAC;YAEH,YAAY,CAAC,SAAS,CAAC,CAAC;YAExB,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAChB,OAAO,QAAQ,CAAC;YAClB,CAAC;YAED,6CAA6C;YAC7C,IAAI,WAAW,GAAG,EAAE,CAAC;YACrB,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACnC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAuD,CAAC;gBACtF,WAAW,GAAG,MAAM,CAAC,KAAK,EAAE,OAAO,IAAI,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;YAC9E,CAAC;YAAC,MAAM,CAAC;gBACP,WAAW,GAAG,QAAQ,CAAC,UAAU,CAAC;YACpC,CAAC;YAED,SAAS,GAAG,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,WAAW,EAAE,CAAC,CAAC;YAEjE,6DAA6D;YAC7D,IAAI,QAAQ,CAAC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,GAAG,GAAG,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAC/E,MAAM,SAAS,CAAC;YAClB,CAAC;QACH,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjE,MAAM,KAAK,CAAC;YACd,CAAC;YACD,SAAS,GAAG,KAAc,CAAC;QAC7B,CAAC;QAED,IAAI,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;YAC7B,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,OAAO,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;IAED,MAAM,SAAS,IAAI,IAAI,KAAK,CAAC,gBAAgB,CAAC,CAAC;AACjD,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google Gemini provider
|
|
3
|
+
* Uses the Gemini REST API (generativelanguage.googleapis.com)
|
|
4
|
+
*/
|
|
5
|
+
import type { Provider, ProviderContext, ChatRequest, ChatResponse, ChatStreamResponse } from '../types.js';
|
|
6
|
+
export declare class GeminiProvider implements Provider {
|
|
7
|
+
private ctx;
|
|
8
|
+
constructor(ctx: ProviderContext);
|
|
9
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
10
|
+
chatStream(_request: ChatRequest): Promise<ReadableStream<ChatStreamResponse>>;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=gemini.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.d.ts","sourceRoot":"","sources":["../../../src/ai/providers/gemini.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EACf,WAAW,EACX,YAAY,EACZ,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAGrB,qBAAa,cAAe,YAAW,QAAQ;IAC7C,OAAO,CAAC,GAAG,CAAkB;gBAEjB,GAAG,EAAE,eAAe;IAI1B,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAuEvD,UAAU,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;CAG/E"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Google Gemini provider
|
|
3
|
+
* Uses the Gemini REST API (generativelanguage.googleapis.com)
|
|
4
|
+
*/
|
|
5
|
+
import { fetchWithRetry } from './fetch.js';
|
|
6
|
+
export class GeminiProvider {
|
|
7
|
+
ctx;
|
|
8
|
+
constructor(ctx) {
|
|
9
|
+
this.ctx = ctx;
|
|
10
|
+
}
|
|
11
|
+
async chat(request) {
|
|
12
|
+
const model = request.model ?? this.ctx.model;
|
|
13
|
+
const temperature = request.temperature ?? this.ctx.temperature;
|
|
14
|
+
// Convert messages to Gemini format
|
|
15
|
+
const systemMessage = request.messages.find((m) => m.role === 'system');
|
|
16
|
+
const otherMessages = request.messages.filter((m) => m.role !== 'system');
|
|
17
|
+
const contents = otherMessages.map((m) => ({
|
|
18
|
+
role: m.role === 'assistant' ? 'model' : 'user',
|
|
19
|
+
parts: [{ text: m.content }],
|
|
20
|
+
}));
|
|
21
|
+
const body = {
|
|
22
|
+
contents,
|
|
23
|
+
generationConfig: {
|
|
24
|
+
temperature,
|
|
25
|
+
topP: this.ctx.topP,
|
|
26
|
+
topK: this.ctx.topK ?? 40,
|
|
27
|
+
maxOutputTokens: request.maxTokens ?? this.ctx.maxTokens,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
if (systemMessage) {
|
|
31
|
+
body.systemInstruction = {
|
|
32
|
+
parts: [{ text: systemMessage.content }],
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
const url = `${this.ctx.baseUrl}/v1beta/models/${model}:generateContent?key=${this.ctx.apiKey}`;
|
|
36
|
+
const response = await fetchWithRetry(this.ctx, url, {
|
|
37
|
+
method: 'POST',
|
|
38
|
+
headers: { 'Content-Type': 'application/json' },
|
|
39
|
+
body: JSON.stringify(body),
|
|
40
|
+
});
|
|
41
|
+
const data = (await response.json());
|
|
42
|
+
const candidate = data.candidates?.[0];
|
|
43
|
+
const content = candidate?.content?.parts?.map((p) => p.text ?? '').join('') ?? '';
|
|
44
|
+
return {
|
|
45
|
+
id: `gemini-${Date.now().toString(36)}`,
|
|
46
|
+
model,
|
|
47
|
+
choices: [
|
|
48
|
+
{
|
|
49
|
+
index: 0,
|
|
50
|
+
message: { role: 'assistant', content },
|
|
51
|
+
finishReason: candidate?.finishReason ?? 'STOP',
|
|
52
|
+
},
|
|
53
|
+
],
|
|
54
|
+
usage: {
|
|
55
|
+
promptTokens: data.usageMetadata?.promptTokenCount ?? 0,
|
|
56
|
+
completionTokens: data.usageMetadata?.candidatesTokenCount ?? 0,
|
|
57
|
+
totalTokens: data.usageMetadata?.totalTokenCount ?? 0,
|
|
58
|
+
},
|
|
59
|
+
provider: this.ctx.providerName,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
chatStream(_request) {
|
|
63
|
+
return Promise.reject(new Error('Streaming not implemented for CLI'));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=gemini.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gemini.js","sourceRoot":"","sources":["../../../src/ai/providers/gemini.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama provider (local models)
|
|
3
|
+
*/
|
|
4
|
+
import type { Provider, ProviderContext, ChatRequest, ChatResponse, ChatStreamResponse } from '../types.js';
|
|
5
|
+
export declare class OllamaProvider implements Provider {
|
|
6
|
+
private ctx;
|
|
7
|
+
constructor(ctx: ProviderContext);
|
|
8
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
9
|
+
chatStream(_request: ChatRequest): Promise<ReadableStream<ChatStreamResponse>>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=ollama.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama.d.ts","sourceRoot":"","sources":["../../../src/ai/providers/ollama.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EACf,WAAW,EACX,YAAY,EACZ,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAGrB,qBAAa,cAAe,YAAW,QAAQ;IAC7C,OAAO,CAAC,GAAG,CAAkB;gBAEjB,GAAG,EAAE,eAAe;IAI1B,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAkDvD,UAAU,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;CAG/E"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ollama provider (local models)
|
|
3
|
+
*/
|
|
4
|
+
import { fetchWithRetry } from './fetch.js';
|
|
5
|
+
export class OllamaProvider {
|
|
6
|
+
ctx;
|
|
7
|
+
constructor(ctx) {
|
|
8
|
+
this.ctx = ctx;
|
|
9
|
+
}
|
|
10
|
+
async chat(request) {
|
|
11
|
+
const model = request.model ?? this.ctx.model;
|
|
12
|
+
const response = await fetchWithRetry(this.ctx, `${this.ctx.baseUrl}/api/chat`, {
|
|
13
|
+
method: 'POST',
|
|
14
|
+
headers: {
|
|
15
|
+
'Content-Type': 'application/json',
|
|
16
|
+
},
|
|
17
|
+
body: JSON.stringify({
|
|
18
|
+
model,
|
|
19
|
+
messages: request.messages,
|
|
20
|
+
stream: false,
|
|
21
|
+
options: {
|
|
22
|
+
temperature: request.temperature ?? this.ctx.temperature,
|
|
23
|
+
top_p: this.ctx.topP,
|
|
24
|
+
top_k: this.ctx.topK,
|
|
25
|
+
},
|
|
26
|
+
}),
|
|
27
|
+
});
|
|
28
|
+
const data = (await response.json());
|
|
29
|
+
return {
|
|
30
|
+
id: `ollama-${Date.now().toString(36)}`,
|
|
31
|
+
model: data.model ?? model,
|
|
32
|
+
choices: [
|
|
33
|
+
{
|
|
34
|
+
index: 0,
|
|
35
|
+
message: {
|
|
36
|
+
role: 'assistant',
|
|
37
|
+
content: data.message?.content ?? '',
|
|
38
|
+
},
|
|
39
|
+
finishReason: data.done_reason ?? 'stop',
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
usage: {
|
|
43
|
+
promptTokens: data.prompt_eval_count ?? 0,
|
|
44
|
+
completionTokens: data.eval_count ?? 0,
|
|
45
|
+
totalTokens: (data.prompt_eval_count ?? 0) + (data.eval_count ?? 0),
|
|
46
|
+
},
|
|
47
|
+
provider: this.ctx.providerName,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
chatStream(_request) {
|
|
51
|
+
return Promise.reject(new Error('Streaming not implemented for CLI'));
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=ollama.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ollama.js","sourceRoot":"","sources":["../../../src/ai/providers/ollama.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,OAAO,cAAc;IACjB,GAAG,CAAkB;IAE7B,YAAY,GAAoB;QAC9B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAoB;QAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;QAE9C,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,WAAW,EAAE;YAC9E,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK;gBACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,MAAM,EAAE,KAAK;gBACb,OAAO,EAAE;oBACP,WAAW,EAAE,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW;oBACxD,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI;oBACpB,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI;iBACrB;aACF,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAMlC,CAAC;QAEF,OAAO;YACL,EAAE,EAAE,UAAU,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;YACvC,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK;YAC1B,OAAO,EAAE;gBACP;oBACE,KAAK,EAAE,CAAC;oBACR,OAAO,EAAE;wBACP,IAAI,EAAE,WAAW;wBACjB,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,OAAO,IAAI,EAAE;qBACrC;oBACD,YAAY,EAAE,IAAI,CAAC,WAAW,IAAI,MAAM;iBACzC;aACF;YACD,KAAK,EAAE;gBACL,YAAY,EAAE,IAAI,CAAC,iBAAiB,IAAI,CAAC;gBACzC,gBAAgB,EAAE,IAAI,CAAC,UAAU,IAAI,CAAC;gBACtC,WAAW,EAAE,CAAC,IAAI,CAAC,iBAAiB,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;aACpE;YACD,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY;SAChC,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,QAAqB;QAC9B,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;IACxE,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI provider (also used for OpenAI-compatible APIs like DeepSeek)
|
|
3
|
+
*/
|
|
4
|
+
import type { Provider, ProviderContext, ChatRequest, ChatResponse, ChatStreamResponse } from '../types.js';
|
|
5
|
+
export declare class OpenAIProvider implements Provider {
|
|
6
|
+
private ctx;
|
|
7
|
+
constructor(ctx: ProviderContext);
|
|
8
|
+
chat(request: ChatRequest): Promise<ChatResponse>;
|
|
9
|
+
chatStream(_request: ChatRequest): Promise<ReadableStream<ChatStreamResponse>>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=openai.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../../src/ai/providers/openai.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EACV,QAAQ,EACR,eAAe,EACf,WAAW,EACX,YAAY,EACZ,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAGrB,qBAAa,cAAe,YAAW,QAAQ;IAC7C,OAAO,CAAC,GAAG,CAAkB;gBAEjB,GAAG,EAAE,eAAe;IAI1B,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC;IAuDvD,UAAU,CAAC,QAAQ,EAAE,WAAW,GAAG,OAAO,CAAC,cAAc,CAAC,kBAAkB,CAAC,CAAC;CAG/E"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenAI provider (also used for OpenAI-compatible APIs like DeepSeek)
|
|
3
|
+
*/
|
|
4
|
+
import { fetchWithRetry } from './fetch.js';
|
|
5
|
+
export class OpenAIProvider {
|
|
6
|
+
ctx;
|
|
7
|
+
constructor(ctx) {
|
|
8
|
+
this.ctx = ctx;
|
|
9
|
+
}
|
|
10
|
+
async chat(request) {
|
|
11
|
+
const model = request.model ?? this.ctx.model;
|
|
12
|
+
const maxTokens = request.maxTokens ?? this.ctx.maxTokens;
|
|
13
|
+
const temperature = request.temperature ?? this.ctx.temperature;
|
|
14
|
+
const response = await fetchWithRetry(this.ctx, `${this.ctx.baseUrl}/chat/completions`, {
|
|
15
|
+
method: 'POST',
|
|
16
|
+
headers: {
|
|
17
|
+
Authorization: `Bearer ${this.ctx.apiKey}`,
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
},
|
|
20
|
+
body: JSON.stringify({
|
|
21
|
+
model,
|
|
22
|
+
messages: request.messages,
|
|
23
|
+
max_tokens: maxTokens,
|
|
24
|
+
temperature,
|
|
25
|
+
top_p: this.ctx.topP,
|
|
26
|
+
}),
|
|
27
|
+
});
|
|
28
|
+
const data = (await response.json());
|
|
29
|
+
return {
|
|
30
|
+
id: data.id ?? `chatcmpl-${Date.now().toString(36)}`,
|
|
31
|
+
model: data.model ?? model,
|
|
32
|
+
choices: (data.choices ?? []).map((choice) => ({
|
|
33
|
+
index: choice.index,
|
|
34
|
+
message: {
|
|
35
|
+
role: choice.message.role,
|
|
36
|
+
content: choice.message.content,
|
|
37
|
+
},
|
|
38
|
+
finishReason: choice.finish_reason,
|
|
39
|
+
})),
|
|
40
|
+
usage: {
|
|
41
|
+
promptTokens: data.usage?.prompt_tokens ?? 0,
|
|
42
|
+
completionTokens: data.usage?.completion_tokens ?? 0,
|
|
43
|
+
totalTokens: data.usage?.total_tokens ?? 0,
|
|
44
|
+
},
|
|
45
|
+
provider: this.ctx.providerName,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
chatStream(_request) {
|
|
49
|
+
return Promise.reject(new Error('Streaming not implemented for CLI'));
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=openai.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openai.js","sourceRoot":"","sources":["../../../src/ai/providers/openai.ts"],"names":[],"mappings":"AAAA;;GAEG;AASH,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE5C,MAAM,OAAO,cAAc;IACjB,GAAG,CAAkB;IAE7B,YAAY,GAAoB;QAC9B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAoB;QAC7B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC;QAC9C,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC;QAC1D,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC;QAEhE,MAAM,QAAQ,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,mBAAmB,EAAE;YACtF,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE;gBAC1C,cAAc,EAAE,kBAAkB;aACnC;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,KAAK;gBACL,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,UAAU,EAAE,SAAS;gBACrB,WAAW;gBACX,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI;aACrB,CAAC;SACH,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAalC,CAAC;QAEF,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAE,IAAI,YAAY,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE;YACpD,KAAK,EAAE,IAAI,CAAC,KAAK,IAAI,KAAK;YAC1B,OAAO,EAAE,CAAC,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBAC7C,KAAK,EAAE,MAAM,CAAC,KAAK;gBACnB,OAAO,EAAE;oBACP,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,IAAuC;oBAC5D,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,OAAO;iBAChC;gBACD,YAAY,EAAE,MAAM,CAAC,aAAa;aACnC,CAAC,CAAC;YACH,KAAK,EAAE;gBACL,YAAY,EAAE,IAAI,CAAC,KAAK,EAAE,aAAa,IAAI,CAAC;gBAC5C,gBAAgB,EAAE,IAAI,CAAC,KAAK,EAAE,iBAAiB,IAAI,CAAC;gBACpD,WAAW,EAAE,IAAI,CAAC,KAAK,EAAE,YAAY,IAAI,CAAC;aAC3C;YACD,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,YAAY;SAChC,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,QAAqB;QAC9B,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC,CAAC;IACxE,CAAC;CACF"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Round-robin selector with rate limiting
|
|
3
|
+
*/
|
|
4
|
+
import type { AIConfig, ProviderContext } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Round-robin selector for AI providers
|
|
7
|
+
*/
|
|
8
|
+
export declare class RoundRobinSelector {
|
|
9
|
+
private instanceCounter;
|
|
10
|
+
private keyCounters;
|
|
11
|
+
private modelCounters;
|
|
12
|
+
private rateLimiters;
|
|
13
|
+
select(config: AIConfig, requestModel?: string): ProviderContext | null;
|
|
14
|
+
private getOrCreateLimiter;
|
|
15
|
+
private parseRateLimit;
|
|
16
|
+
private getEnabledInstances;
|
|
17
|
+
reset(): void;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=selector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector.d.ts","sourceRoot":"","sources":["../../src/ai/selector.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAA0B,MAAM,YAAY,CAAC;AAoCpF;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,eAAe,CAAK;IAC5B,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,aAAa,CAA6B;IAClD,OAAO,CAAC,YAAY,CAAkC;IAEtD,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI;IAqDvE,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,cAAc;IA2BtB,OAAO,CAAC,mBAAmB;IAqB3B,KAAK,IAAI,IAAI;CAMd"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Round-robin selector with rate limiting
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Token bucket rate limiter
|
|
6
|
+
*/
|
|
7
|
+
class TokenBucket {
|
|
8
|
+
tokens;
|
|
9
|
+
lastRefill;
|
|
10
|
+
rate;
|
|
11
|
+
burst;
|
|
12
|
+
constructor(rate, burst) {
|
|
13
|
+
this.rate = rate;
|
|
14
|
+
this.burst = burst;
|
|
15
|
+
this.tokens = burst;
|
|
16
|
+
this.lastRefill = Date.now();
|
|
17
|
+
}
|
|
18
|
+
allow() {
|
|
19
|
+
this.refill();
|
|
20
|
+
if (this.tokens >= 1) {
|
|
21
|
+
this.tokens -= 1;
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
refill() {
|
|
27
|
+
const now = Date.now();
|
|
28
|
+
const elapsed = now - this.lastRefill;
|
|
29
|
+
const newTokens = elapsed * this.rate;
|
|
30
|
+
this.tokens = Math.min(this.burst, this.tokens + newTokens);
|
|
31
|
+
this.lastRefill = now;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Round-robin selector for AI providers
|
|
36
|
+
*/
|
|
37
|
+
export class RoundRobinSelector {
|
|
38
|
+
instanceCounter = 0;
|
|
39
|
+
keyCounters = new Map();
|
|
40
|
+
modelCounters = new Map();
|
|
41
|
+
rateLimiters = new Map();
|
|
42
|
+
select(config, requestModel) {
|
|
43
|
+
const instances = this.getEnabledInstances(config);
|
|
44
|
+
if (instances.length === 0) {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
const startCounter = this.instanceCounter;
|
|
48
|
+
for (let i = 0; i < instances.length; i++) {
|
|
49
|
+
const index = (startCounter + i) % instances.length;
|
|
50
|
+
const selected = instances[index];
|
|
51
|
+
if (!selected)
|
|
52
|
+
continue;
|
|
53
|
+
const counterKey = `${selected.providerName}:${selected.instance.name}`;
|
|
54
|
+
const limiter = this.getOrCreateLimiter(counterKey, selected.instance);
|
|
55
|
+
if (limiter && !limiter.allow()) {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
this.instanceCounter = index + 1;
|
|
59
|
+
const keyCounter = this.keyCounters.get(counterKey) ?? 0;
|
|
60
|
+
const apiKey = selected.instance.apiKey;
|
|
61
|
+
this.keyCounters.set(counterKey, keyCounter + 1);
|
|
62
|
+
let model;
|
|
63
|
+
if (requestModel) {
|
|
64
|
+
model = requestModel;
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
const modelCounter = this.modelCounters.get(counterKey) ?? 0;
|
|
68
|
+
model = selected.instance.models[modelCounter % selected.instance.models.length] ?? '';
|
|
69
|
+
this.modelCounters.set(counterKey, modelCounter + 1);
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
providerName: selected.providerName,
|
|
73
|
+
instanceName: selected.instance.name,
|
|
74
|
+
baseUrl: selected.instance.baseUrl,
|
|
75
|
+
apiKey,
|
|
76
|
+
model,
|
|
77
|
+
maxTokens: selected.instance.maxTokens,
|
|
78
|
+
temperature: selected.instance.temperature,
|
|
79
|
+
topP: selected.instance.topP,
|
|
80
|
+
topK: selected.instance.topK,
|
|
81
|
+
timeout: selected.instance.timeout,
|
|
82
|
+
maxRetries: selected.instance.maxRetries,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
getOrCreateLimiter(key, instance) {
|
|
88
|
+
if (!instance.rateLimit) {
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
let limiter = this.rateLimiters.get(key);
|
|
92
|
+
if (!limiter) {
|
|
93
|
+
const { interval, limit } = this.parseRateLimit(instance.rateLimit);
|
|
94
|
+
const rate = 1 / interval;
|
|
95
|
+
limiter = new TokenBucket(rate, limit);
|
|
96
|
+
this.rateLimiters.set(key, limiter);
|
|
97
|
+
}
|
|
98
|
+
return limiter;
|
|
99
|
+
}
|
|
100
|
+
parseRateLimit(rateLimit) {
|
|
101
|
+
const match = rateLimit.match(/^(\d+)\/(\w+)$/);
|
|
102
|
+
if (!match) {
|
|
103
|
+
return { interval: 1000, limit: 10 };
|
|
104
|
+
}
|
|
105
|
+
const limit = parseInt(match[1] ?? '10', 10);
|
|
106
|
+
const unit = match[2] ?? 's';
|
|
107
|
+
let interval;
|
|
108
|
+
switch (unit) {
|
|
109
|
+
case 's':
|
|
110
|
+
interval = 1000;
|
|
111
|
+
break;
|
|
112
|
+
case 'm':
|
|
113
|
+
interval = 60000;
|
|
114
|
+
break;
|
|
115
|
+
case 'h':
|
|
116
|
+
interval = 3600000;
|
|
117
|
+
break;
|
|
118
|
+
default:
|
|
119
|
+
interval = 1000;
|
|
120
|
+
}
|
|
121
|
+
return { interval: interval / limit, limit };
|
|
122
|
+
}
|
|
123
|
+
getEnabledInstances(config) {
|
|
124
|
+
const instances = [];
|
|
125
|
+
for (const [providerName, provider] of Object.entries(config.providers)) {
|
|
126
|
+
if (!provider.enabled) {
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
for (const instance of provider.instances) {
|
|
130
|
+
const needsApiKey = providerName !== 'ollama';
|
|
131
|
+
if (instance.enabled && (!needsApiKey || instance.apiKey) && instance.models.length > 0) {
|
|
132
|
+
instances.push({ providerName, instance });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
return instances;
|
|
137
|
+
}
|
|
138
|
+
reset() {
|
|
139
|
+
this.instanceCounter = 0;
|
|
140
|
+
this.keyCounters.clear();
|
|
141
|
+
this.modelCounters.clear();
|
|
142
|
+
this.rateLimiters.clear();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=selector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"selector.js","sourceRoot":"","sources":["../../src/ai/selector.ts"],"names":[],"mappings":"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"}
|