@anastops/adapters 0.1.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/aider/aider-adapter.d.ts +25 -0
- package/dist/aider/aider-adapter.d.ts.map +1 -0
- package/dist/aider/aider-adapter.js +99 -0
- package/dist/aider/aider-adapter.js.map +1 -0
- package/dist/base/base-adapter.d.ts +113 -0
- package/dist/base/base-adapter.d.ts.map +1 -0
- package/dist/base/base-adapter.js +227 -0
- package/dist/base/base-adapter.js.map +1 -0
- package/dist/base/detached-exec.d.ts +38 -0
- package/dist/base/detached-exec.d.ts.map +1 -0
- package/dist/base/detached-exec.js +146 -0
- package/dist/base/detached-exec.js.map +1 -0
- package/dist/claude/claude-adapter.d.ts +65 -0
- package/dist/claude/claude-adapter.d.ts.map +1 -0
- package/dist/claude/claude-adapter.js +364 -0
- package/dist/claude/claude-adapter.js.map +1 -0
- package/dist/codex/codex-adapter.d.ts +33 -0
- package/dist/codex/codex-adapter.d.ts.map +1 -0
- package/dist/codex/codex-adapter.js +108 -0
- package/dist/codex/codex-adapter.js.map +1 -0
- package/dist/copilot/copilot-adapter.d.ts +26 -0
- package/dist/copilot/copilot-adapter.d.ts.map +1 -0
- package/dist/copilot/copilot-adapter.js +92 -0
- package/dist/copilot/copilot-adapter.js.map +1 -0
- package/dist/cursor/cursor-adapter.d.ts +33 -0
- package/dist/cursor/cursor-adapter.d.ts.map +1 -0
- package/dist/cursor/cursor-adapter.js +120 -0
- package/dist/cursor/cursor-adapter.js.map +1 -0
- package/dist/gemini/gemini-adapter.d.ts +33 -0
- package/dist/gemini/gemini-adapter.d.ts.map +1 -0
- package/dist/gemini/gemini-adapter.js +111 -0
- package/dist/gemini/gemini-adapter.js.map +1 -0
- package/dist/grok/grok-adapter.d.ts +32 -0
- package/dist/grok/grok-adapter.d.ts.map +1 -0
- package/dist/grok/grok-adapter.js +101 -0
- package/dist/grok/grok-adapter.js.map +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/local/local-adapter.d.ts +91 -0
- package/dist/local/local-adapter.d.ts.map +1 -0
- package/dist/local/local-adapter.js +165 -0
- package/dist/local/local-adapter.js.map +1 -0
- package/dist/registry.d.ts +57 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +152 -0
- package/dist/registry.js.map +1 -0
- package/package.json +65 -0
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AiderAdapter - Aider CLI adapter
|
|
3
|
+
*
|
|
4
|
+
* Integrates with Aider for AI pair programming.
|
|
5
|
+
*/
|
|
6
|
+
import type { AIRequest, ProviderType } from '@anastops/core';
|
|
7
|
+
import { BaseAdapter, type AdapterConfig } from '../base/base-adapter.js';
|
|
8
|
+
export declare class AiderAdapter extends BaseAdapter {
|
|
9
|
+
readonly type: ProviderType;
|
|
10
|
+
readonly name = "Aider";
|
|
11
|
+
constructor(config?: Partial<AdapterConfig>);
|
|
12
|
+
isAuthenticated(): Promise<boolean>;
|
|
13
|
+
protected buildArgs(request: AIRequest): string[];
|
|
14
|
+
protected parseOutput(output: string): string;
|
|
15
|
+
protected getDefaultModel(): string;
|
|
16
|
+
protected parseVersion(output: string): string;
|
|
17
|
+
protected getAvailableModels(): string[];
|
|
18
|
+
protected getAvailableTools(): string[];
|
|
19
|
+
protected getAvailableModes(): string[];
|
|
20
|
+
protected supportsStreaming(): boolean;
|
|
21
|
+
protected getContextWindow(): number;
|
|
22
|
+
protected getCostPer1kInput(): number;
|
|
23
|
+
protected getCostPer1kOutput(): number;
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=aider-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aider-adapter.d.ts","sourceRoot":"","sources":["../../src/aider/aider-adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAE9D,OAAO,EAAE,WAAW,EAAE,KAAK,aAAa,EAAE,MAAM,yBAAyB,CAAC;AAE1E,qBAAa,YAAa,SAAQ,WAAW;IAC3C,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAW;IACtC,QAAQ,CAAC,IAAI,WAAW;gBAEZ,MAAM,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC;IAS3C,eAAe,IAAI,OAAO,CAAC,OAAO,CAAC;IASnC,SAAS,CAAC,SAAS,CAAC,OAAO,EAAE,SAAS,GAAG,MAAM,EAAE;IA6BjD,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAc7C,SAAS,CAAC,eAAe,IAAI,MAAM;IAInC,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAK9C,SAAS,CAAC,kBAAkB,IAAI,MAAM,EAAE;IAcxC,SAAS,CAAC,iBAAiB,IAAI,MAAM,EAAE;IAIvC,SAAS,CAAC,iBAAiB,IAAI,MAAM,EAAE;IAIvC,SAAS,CAAC,iBAAiB,IAAI,OAAO;IAItC,SAAS,CAAC,gBAAgB,IAAI,MAAM;IAIpC,SAAS,CAAC,iBAAiB,IAAI,MAAM;IAIrC,SAAS,CAAC,kBAAkB,IAAI,MAAM;CAGvC"}
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AiderAdapter - Aider CLI adapter
|
|
3
|
+
*
|
|
4
|
+
* Integrates with Aider for AI pair programming.
|
|
5
|
+
*/
|
|
6
|
+
import { BaseAdapter } from '../base/base-adapter.js';
|
|
7
|
+
export class AiderAdapter extends BaseAdapter {
|
|
8
|
+
type = 'aider';
|
|
9
|
+
name = 'Aider';
|
|
10
|
+
constructor(config) {
|
|
11
|
+
super({
|
|
12
|
+
command: 'aider',
|
|
13
|
+
defaultArgs: ['--no-auto-commits', '--yes'],
|
|
14
|
+
defaultTimeout: 600000, // 10 minutes
|
|
15
|
+
...config,
|
|
16
|
+
});
|
|
17
|
+
}
|
|
18
|
+
isAuthenticated() {
|
|
19
|
+
// Aider uses various API keys based on model
|
|
20
|
+
return Promise.resolve(process.env['OPENAI_API_KEY'] !== undefined ||
|
|
21
|
+
process.env['ANTHROPIC_API_KEY'] !== undefined ||
|
|
22
|
+
process.env['GEMINI_API_KEY'] !== undefined);
|
|
23
|
+
}
|
|
24
|
+
buildArgs(request) {
|
|
25
|
+
const args = [...(this.config.defaultArgs ?? [])];
|
|
26
|
+
// Model selection
|
|
27
|
+
if (request.model !== undefined) {
|
|
28
|
+
if (request.model.includes('claude')) {
|
|
29
|
+
args.push('--model', request.model);
|
|
30
|
+
}
|
|
31
|
+
else if (request.model.includes('gpt')) {
|
|
32
|
+
args.push('--model', request.model);
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
args.push('--model', request.model);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Add files if specified
|
|
39
|
+
if (request.allowed_tools !== undefined) {
|
|
40
|
+
for (const file of request.allowed_tools) {
|
|
41
|
+
if (file.startsWith('/') || file.endsWith('.ts') || file.endsWith('.js')) {
|
|
42
|
+
args.push(file);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
// Message mode (non-interactive)
|
|
47
|
+
args.push('--message', request.prompt);
|
|
48
|
+
return args;
|
|
49
|
+
}
|
|
50
|
+
parseOutput(output) {
|
|
51
|
+
// Aider outputs various metadata, extract the relevant response
|
|
52
|
+
const lines = output.split('\n');
|
|
53
|
+
const relevantLines = lines.filter((line) => !line.startsWith('Aider') &&
|
|
54
|
+
!line.startsWith('Model:') &&
|
|
55
|
+
!line.startsWith('Git repo:') &&
|
|
56
|
+
!line.startsWith('Repo-map:') &&
|
|
57
|
+
!line.startsWith('Use /help'));
|
|
58
|
+
return relevantLines.join('\n').trim();
|
|
59
|
+
}
|
|
60
|
+
getDefaultModel() {
|
|
61
|
+
return 'claude-sonnet-4-5-20250929';
|
|
62
|
+
}
|
|
63
|
+
parseVersion(output) {
|
|
64
|
+
const match = /aider\s+(\d+\.\d+\.\d+)/i.exec(output);
|
|
65
|
+
return match?.[1] ?? output.trim();
|
|
66
|
+
}
|
|
67
|
+
getAvailableModels() {
|
|
68
|
+
return [
|
|
69
|
+
'claude-sonnet-4-5-20250929',
|
|
70
|
+
'claude-opus-4-5-20251101',
|
|
71
|
+
'o3',
|
|
72
|
+
'o4-mini',
|
|
73
|
+
'gpt-4o',
|
|
74
|
+
'gpt-5.1',
|
|
75
|
+
'gemini-2.5-flash',
|
|
76
|
+
'gemini-3-flash',
|
|
77
|
+
'deepseek-coder',
|
|
78
|
+
];
|
|
79
|
+
}
|
|
80
|
+
getAvailableTools() {
|
|
81
|
+
return ['edit', 'ask', 'architect', 'diff'];
|
|
82
|
+
}
|
|
83
|
+
getAvailableModes() {
|
|
84
|
+
return ['code', 'ask', 'architect'];
|
|
85
|
+
}
|
|
86
|
+
supportsStreaming() {
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
getContextWindow() {
|
|
90
|
+
return 200000; // Depends on model
|
|
91
|
+
}
|
|
92
|
+
getCostPer1kInput() {
|
|
93
|
+
return 0.003; // Claude Sonnet default
|
|
94
|
+
}
|
|
95
|
+
getCostPer1kOutput() {
|
|
96
|
+
return 0.015; // Claude Sonnet default
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=aider-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"aider-adapter.js","sourceRoot":"","sources":["../../src/aider/aider-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaseAdapter - Abstract base class for AI provider adapters
|
|
3
|
+
*
|
|
4
|
+
* All provider adapters (Claude, Cursor, Codex, etc.) extend this class.
|
|
5
|
+
*/
|
|
6
|
+
import type { AIRequest, AIResponse, AIChunk, ProviderCapabilities, HealthStatus, ProviderType } from '@anastops/core';
|
|
7
|
+
export interface AdapterConfig {
|
|
8
|
+
/** CLI command to execute */
|
|
9
|
+
command: string;
|
|
10
|
+
/** Default arguments */
|
|
11
|
+
defaultArgs?: string[];
|
|
12
|
+
/** Default timeout in ms */
|
|
13
|
+
defaultTimeout?: number;
|
|
14
|
+
/** Working directory */
|
|
15
|
+
workingDir?: string;
|
|
16
|
+
/** Environment variables */
|
|
17
|
+
env?: Record<string, string>;
|
|
18
|
+
/**
|
|
19
|
+
* Use detached process execution to avoid SIGTERM from parent process.
|
|
20
|
+
* Required when running from within Cursor or similar IDEs that kill
|
|
21
|
+
* nested AI CLI instances.
|
|
22
|
+
* @default true
|
|
23
|
+
*/
|
|
24
|
+
useDetachedExec?: boolean;
|
|
25
|
+
}
|
|
26
|
+
export interface ExecuteOptions {
|
|
27
|
+
/** Working directory override */
|
|
28
|
+
workingDir?: string;
|
|
29
|
+
/** Timeout override */
|
|
30
|
+
timeout?: number;
|
|
31
|
+
/** Stream responses */
|
|
32
|
+
stream?: boolean;
|
|
33
|
+
/** Signal for cancellation */
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
}
|
|
36
|
+
export interface AIProviderAdapter {
|
|
37
|
+
/** Provider type identifier */
|
|
38
|
+
readonly type: ProviderType;
|
|
39
|
+
/** Provider display name */
|
|
40
|
+
readonly name: string;
|
|
41
|
+
/** Execute a request */
|
|
42
|
+
execute(request: AIRequest, options?: ExecuteOptions): Promise<AIResponse>;
|
|
43
|
+
/** Stream a request */
|
|
44
|
+
stream(request: AIRequest, options?: ExecuteOptions): AsyncIterable<AIChunk>;
|
|
45
|
+
/** Check provider health */
|
|
46
|
+
healthCheck(): Promise<HealthStatus>;
|
|
47
|
+
/** Get provider capabilities */
|
|
48
|
+
getCapabilities(): Promise<ProviderCapabilities>;
|
|
49
|
+
/** Check if CLI is installed */
|
|
50
|
+
isInstalled(): Promise<boolean>;
|
|
51
|
+
/** Check if authenticated */
|
|
52
|
+
isAuthenticated(): Promise<boolean>;
|
|
53
|
+
/** Get CLI version */
|
|
54
|
+
getVersion(): Promise<string | null>;
|
|
55
|
+
}
|
|
56
|
+
export declare abstract class BaseAdapter implements AIProviderAdapter {
|
|
57
|
+
abstract readonly type: ProviderType;
|
|
58
|
+
abstract readonly name: string;
|
|
59
|
+
protected config: AdapterConfig;
|
|
60
|
+
protected cachedCapabilities: ProviderCapabilities | null;
|
|
61
|
+
protected lastHealthCheck: HealthStatus | null;
|
|
62
|
+
constructor(config: AdapterConfig);
|
|
63
|
+
/**
|
|
64
|
+
* Execute a request and return the response
|
|
65
|
+
*/
|
|
66
|
+
execute(request: AIRequest, options?: ExecuteOptions): Promise<AIResponse>;
|
|
67
|
+
/**
|
|
68
|
+
* Stream responses (default implementation collects and yields once)
|
|
69
|
+
*/
|
|
70
|
+
stream(request: AIRequest, options?: ExecuteOptions): AsyncIterable<AIChunk>;
|
|
71
|
+
/**
|
|
72
|
+
* Check provider health
|
|
73
|
+
*/
|
|
74
|
+
healthCheck(): Promise<HealthStatus>;
|
|
75
|
+
/**
|
|
76
|
+
* Get provider capabilities
|
|
77
|
+
*/
|
|
78
|
+
getCapabilities(): Promise<ProviderCapabilities>;
|
|
79
|
+
/**
|
|
80
|
+
* Check if CLI is installed
|
|
81
|
+
*/
|
|
82
|
+
isInstalled(): Promise<boolean>;
|
|
83
|
+
/**
|
|
84
|
+
* Check if authenticated (override in subclasses)
|
|
85
|
+
*/
|
|
86
|
+
abstract isAuthenticated(): Promise<boolean>;
|
|
87
|
+
/**
|
|
88
|
+
* Get CLI version
|
|
89
|
+
*/
|
|
90
|
+
getVersion(): Promise<string | null>;
|
|
91
|
+
protected abstract buildArgs(request: AIRequest): string[];
|
|
92
|
+
protected abstract parseOutput(output: string): string;
|
|
93
|
+
protected abstract getDefaultModel(): string;
|
|
94
|
+
protected abstract parseVersion(output: string): string;
|
|
95
|
+
protected getAvailableModels(): string[];
|
|
96
|
+
protected getAvailableTools(): string[];
|
|
97
|
+
protected supportsPermissions(): boolean;
|
|
98
|
+
protected getAvailableModes(): string[];
|
|
99
|
+
protected supportsStreaming(): boolean;
|
|
100
|
+
protected getContextWindow(): number;
|
|
101
|
+
protected getCostPer1kInput(): number;
|
|
102
|
+
protected getCostPer1kOutput(): number;
|
|
103
|
+
/**
|
|
104
|
+
* Estimate token usage (rough approximation)
|
|
105
|
+
*/
|
|
106
|
+
protected estimateUsage(prompt: string, response: string): {
|
|
107
|
+
prompt_tokens: number;
|
|
108
|
+
completion_tokens: number;
|
|
109
|
+
total_tokens: number;
|
|
110
|
+
cost: number;
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=base-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-adapter.d.ts","sourceRoot":"","sources":["../../src/base/base-adapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaseAdapter - Abstract base class for AI provider adapters
|
|
3
|
+
*
|
|
4
|
+
* All provider adapters (Claude, Cursor, Codex, etc.) extend this class.
|
|
5
|
+
*/
|
|
6
|
+
import { execa } from 'execa';
|
|
7
|
+
import { detachedExec } from './detached-exec.js';
|
|
8
|
+
export class BaseAdapter {
|
|
9
|
+
config;
|
|
10
|
+
cachedCapabilities = null;
|
|
11
|
+
lastHealthCheck = null;
|
|
12
|
+
constructor(config) {
|
|
13
|
+
this.config = {
|
|
14
|
+
defaultTimeout: 600000, // 10 minutes
|
|
15
|
+
defaultArgs: [],
|
|
16
|
+
useDetachedExec: true, // Default to detached to avoid SIGTERM from Cursor
|
|
17
|
+
...config,
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Execute a request and return the response
|
|
22
|
+
*/
|
|
23
|
+
async execute(request, options) {
|
|
24
|
+
const args = this.buildArgs(request);
|
|
25
|
+
const startTime = Date.now();
|
|
26
|
+
const cwd = options?.workingDir ?? request.working_dir ?? this.config.workingDir ?? process.cwd();
|
|
27
|
+
const timeout = options?.timeout ?? request.timeout ?? this.config.defaultTimeout ?? 600000;
|
|
28
|
+
let stdout;
|
|
29
|
+
let stderr;
|
|
30
|
+
let exitCode;
|
|
31
|
+
let failed;
|
|
32
|
+
if (this.config.useDetachedExec) {
|
|
33
|
+
// Use detached process execution to avoid SIGTERM from Cursor
|
|
34
|
+
const result = await detachedExec(this.config.command, args, {
|
|
35
|
+
cwd,
|
|
36
|
+
timeout,
|
|
37
|
+
env: { ...process.env, ...this.config.env },
|
|
38
|
+
input: request.prompt,
|
|
39
|
+
signal: options?.signal,
|
|
40
|
+
});
|
|
41
|
+
stdout = result.stdout;
|
|
42
|
+
stderr = result.stderr;
|
|
43
|
+
exitCode = result.exitCode;
|
|
44
|
+
failed = result.failed;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// Use direct execa (faster but may fail in Cursor/IDE context)
|
|
48
|
+
const result = await execa(this.config.command, args, {
|
|
49
|
+
timeout,
|
|
50
|
+
cwd,
|
|
51
|
+
env: { ...process.env, ...this.config.env },
|
|
52
|
+
input: request.prompt,
|
|
53
|
+
reject: false,
|
|
54
|
+
signal: options?.signal,
|
|
55
|
+
});
|
|
56
|
+
stdout = result.stdout;
|
|
57
|
+
stderr = result.stderr;
|
|
58
|
+
exitCode = result.exitCode ?? -1;
|
|
59
|
+
failed = result.failed;
|
|
60
|
+
}
|
|
61
|
+
if (failed) {
|
|
62
|
+
throw new Error(`Provider execution failed: ${stderr || `Exit code ${exitCode}`}`);
|
|
63
|
+
}
|
|
64
|
+
const latencyMs = Date.now() - startTime;
|
|
65
|
+
const content = this.parseOutput(stdout);
|
|
66
|
+
const usage = this.estimateUsage(request.prompt, content);
|
|
67
|
+
return {
|
|
68
|
+
content,
|
|
69
|
+
model: request.model ?? this.getDefaultModel(),
|
|
70
|
+
usage,
|
|
71
|
+
finish_reason: 'stop',
|
|
72
|
+
metadata: {
|
|
73
|
+
latency_ms: latencyMs,
|
|
74
|
+
provider: this.type,
|
|
75
|
+
exit_code: exitCode,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Stream responses (default implementation collects and yields once)
|
|
81
|
+
*/
|
|
82
|
+
async *stream(request, options) {
|
|
83
|
+
// Default: non-streaming execution, yield final result
|
|
84
|
+
const response = await this.execute(request, options);
|
|
85
|
+
yield {
|
|
86
|
+
content: response.content,
|
|
87
|
+
done: true,
|
|
88
|
+
usage: response.usage,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Check provider health
|
|
93
|
+
*/
|
|
94
|
+
async healthCheck() {
|
|
95
|
+
const startTime = Date.now();
|
|
96
|
+
try {
|
|
97
|
+
const installed = await this.isInstalled();
|
|
98
|
+
if (!installed) {
|
|
99
|
+
return {
|
|
100
|
+
healthy: false,
|
|
101
|
+
error: 'CLI not installed',
|
|
102
|
+
checked_at: new Date(),
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
const authenticated = await this.isAuthenticated();
|
|
106
|
+
if (!authenticated) {
|
|
107
|
+
return {
|
|
108
|
+
healthy: false,
|
|
109
|
+
error: 'Not authenticated',
|
|
110
|
+
checked_at: new Date(),
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
const latencyMs = Date.now() - startTime;
|
|
114
|
+
this.lastHealthCheck = {
|
|
115
|
+
healthy: true,
|
|
116
|
+
latency_ms: latencyMs,
|
|
117
|
+
checked_at: new Date(),
|
|
118
|
+
};
|
|
119
|
+
return this.lastHealthCheck;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
123
|
+
return {
|
|
124
|
+
healthy: false,
|
|
125
|
+
error: errorMsg,
|
|
126
|
+
checked_at: new Date(),
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Get provider capabilities
|
|
132
|
+
*/
|
|
133
|
+
async getCapabilities() {
|
|
134
|
+
if (this.cachedCapabilities !== null) {
|
|
135
|
+
return this.cachedCapabilities;
|
|
136
|
+
}
|
|
137
|
+
const [installed, authenticated, version] = await Promise.all([
|
|
138
|
+
this.isInstalled(),
|
|
139
|
+
this.isAuthenticated().catch(() => false),
|
|
140
|
+
this.getVersion(),
|
|
141
|
+
]);
|
|
142
|
+
this.cachedCapabilities = {
|
|
143
|
+
installed,
|
|
144
|
+
authenticated,
|
|
145
|
+
version,
|
|
146
|
+
models: this.getAvailableModels(),
|
|
147
|
+
tools: this.getAvailableTools(),
|
|
148
|
+
permissions: this.supportsPermissions(),
|
|
149
|
+
modes: this.getAvailableModes(),
|
|
150
|
+
streaming: this.supportsStreaming(),
|
|
151
|
+
context_window: this.getContextWindow(),
|
|
152
|
+
cost_per_1k_input: this.getCostPer1kInput(),
|
|
153
|
+
cost_per_1k_output: this.getCostPer1kOutput(),
|
|
154
|
+
};
|
|
155
|
+
return this.cachedCapabilities;
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Check if CLI is installed
|
|
159
|
+
*/
|
|
160
|
+
async isInstalled() {
|
|
161
|
+
try {
|
|
162
|
+
const result = await execa('which', [this.config.command], { reject: false });
|
|
163
|
+
return result.exitCode === 0;
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
console.error(`Failed to check if ${this.config.command} is installed:`, error);
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Get CLI version
|
|
172
|
+
*/
|
|
173
|
+
async getVersion() {
|
|
174
|
+
try {
|
|
175
|
+
const result = await execa(this.config.command, ['--version'], { reject: false });
|
|
176
|
+
if (result.exitCode === 0) {
|
|
177
|
+
return this.parseVersion(result.stdout);
|
|
178
|
+
}
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
catch {
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
// Methods with defaults that can be overridden
|
|
186
|
+
getAvailableModels() {
|
|
187
|
+
return [];
|
|
188
|
+
}
|
|
189
|
+
getAvailableTools() {
|
|
190
|
+
return [];
|
|
191
|
+
}
|
|
192
|
+
supportsPermissions() {
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
getAvailableModes() {
|
|
196
|
+
return [];
|
|
197
|
+
}
|
|
198
|
+
supportsStreaming() {
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
getContextWindow() {
|
|
202
|
+
return 100000;
|
|
203
|
+
}
|
|
204
|
+
getCostPer1kInput() {
|
|
205
|
+
return 0;
|
|
206
|
+
}
|
|
207
|
+
getCostPer1kOutput() {
|
|
208
|
+
return 0;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Estimate token usage (rough approximation)
|
|
212
|
+
*/
|
|
213
|
+
estimateUsage(prompt, response) {
|
|
214
|
+
const promptTokens = Math.ceil(prompt.length / 4);
|
|
215
|
+
const completionTokens = Math.ceil(response.length / 4);
|
|
216
|
+
const totalTokens = promptTokens + completionTokens;
|
|
217
|
+
const cost = (promptTokens / 1000) * this.getCostPer1kInput() +
|
|
218
|
+
(completionTokens / 1000) * this.getCostPer1kOutput();
|
|
219
|
+
return {
|
|
220
|
+
prompt_tokens: promptTokens,
|
|
221
|
+
completion_tokens: completionTokens,
|
|
222
|
+
total_tokens: totalTokens,
|
|
223
|
+
cost,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=base-adapter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"base-adapter.js","sourceRoot":"","sources":["../../src/base/base-adapter.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH,OAAO,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAE9B,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAyElD,MAAM,OAAgB,WAAW;IAIrB,MAAM,CAAgB;IACtB,kBAAkB,GAAgC,IAAI,CAAC;IACvD,eAAe,GAAwB,IAAI,CAAC;IAEtD,YAAY,MAAqB;QAC/B,IAAI,CAAC,MAAM,GAAG;YACZ,cAAc,EAAE,MAAM,EAAE,aAAa;YACrC,WAAW,EAAE,EAAE;YACf,eAAe,EAAE,IAAI,EAAE,mDAAmD;YAC1E,GAAG,MAAM;SACV,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO,CAAC,OAAkB,EAAE,OAAwB;QACxD,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;QACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,MAAM,GAAG,GAAG,OAAO,EAAE,UAAU,IAAI,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC;QAClG,MAAM,OAAO,GAAG,OAAO,EAAE,OAAO,IAAI,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,MAAM,CAAC;QAE5F,IAAI,MAAc,CAAC;QACnB,IAAI,MAAc,CAAC;QACnB,IAAI,QAAgB,CAAC;QACrB,IAAI,MAAe,CAAC;QAEpB,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,EAAE,CAAC;YAChC,8DAA8D;YAC9D,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE;gBAC3D,GAAG;gBACH,OAAO;gBACP,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE;gBAC3C,KAAK,EAAE,OAAO,CAAC,MAAM;gBACrB,MAAM,EAAE,OAAO,EAAE,MAAM;aACxB,CAAC,CAAC;YACH,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YACvB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YACvB,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;YAC3B,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QACzB,CAAC;aAAM,CAAC;YACN,+DAA+D;YAC/D,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE;gBACpD,OAAO;gBACP,GAAG;gBACH,GAAG,EAAE,EAAE,GAAG,OAAO,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,EAA4B;gBACrE,KAAK,EAAE,OAAO,CAAC,MAAM;gBACrB,MAAM,EAAE,KAAK;gBACb,MAAM,EAAE,OAAO,EAAE,MAAM;aACxB,CAAC,CAAC;YACH,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YACvB,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;YACvB,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC;YACjC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QACzB,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,8BAA8B,MAAM,IAAI,aAAa,QAAQ,EAAE,EAAE,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;QACzC,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;QACzC,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAE1D,OAAO;YACL,OAAO;YACP,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,IAAI,CAAC,eAAe,EAAE;YAC9C,KAAK;YACL,aAAa,EAAE,MAAM;YACrB,QAAQ,EAAE;gBACR,UAAU,EAAE,SAAS;gBACrB,QAAQ,EAAE,IAAI,CAAC,IAAI;gBACnB,SAAS,EAAE,QAAQ;aACpB;SACF,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,CAAC,MAAM,CACX,OAAkB,EAClB,OAAwB;QAExB,uDAAuD;QACvD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QACtD,MAAM;YACJ,OAAO,EAAE,QAAQ,CAAC,OAAO;YACzB,IAAI,EAAE,IAAI;YACV,KAAK,EAAE,QAAQ,CAAC,KAAK;SACtB,CAAC;IACJ,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAE7B,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC;YAC3C,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,mBAAmB;oBAC1B,UAAU,EAAE,IAAI,IAAI,EAAE;iBACvB,CAAC;YACJ,CAAC;YAED,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;YACnD,IAAI,CAAC,aAAa,EAAE,CAAC;gBACnB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,KAAK,EAAE,mBAAmB;oBAC1B,UAAU,EAAE,IAAI,IAAI,EAAE;iBACvB,CAAC;YACJ,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;YAEzC,IAAI,CAAC,eAAe,GAAG;gBACrB,OAAO,EAAE,IAAI;gBACb,UAAU,EAAE,SAAS;gBACrB,UAAU,EAAE,IAAI,IAAI,EAAE;aACvB,CAAC;YAEF,OAAO,IAAI,CAAC,eAAe,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,QAAQ,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACxE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,QAAQ;gBACf,UAAU,EAAE,IAAI,IAAI,EAAE;aACvB,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,IAAI,IAAI,CAAC,kBAAkB,KAAK,IAAI,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC,kBAAkB,CAAC;QACjC,CAAC;QAED,MAAM,CAAC,SAAS,EAAE,aAAa,EAAE,OAAO,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC5D,IAAI,CAAC,WAAW,EAAE;YAClB,IAAI,CAAC,eAAe,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,KAAK,CAAC;YACzC,IAAI,CAAC,UAAU,EAAE;SAClB,CAAC,CAAC;QAEH,IAAI,CAAC,kBAAkB,GAAG;YACxB,SAAS;YACT,aAAa;YACb,OAAO;YACP,MAAM,EAAE,IAAI,CAAC,kBAAkB,EAAE;YACjC,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE;YAC/B,WAAW,EAAE,IAAI,CAAC,mBAAmB,EAAE;YACvC,KAAK,EAAE,IAAI,CAAC,iBAAiB,EAAE;YAC/B,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE;YACnC,cAAc,EAAE,IAAI,CAAC,gBAAgB,EAAE;YACvC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB,EAAE;YAC3C,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,EAAE;SAC9C,CAAC;QAEF,OAAO,IAAI,CAAC,kBAAkB,CAAC;IACjC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,WAAW;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAC9E,OAAO,MAAM,CAAC,QAAQ,KAAK,CAAC,CAAC;QAC/B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,sBAAsB,IAAI,CAAC,MAAM,CAAC,OAAO,gBAAgB,EAAE,KAAK,CAAC,CAAC;YAChF,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IAOD;;OAEG;IACH,KAAK,CAAC,UAAU;QACd,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC;YAClF,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBAC1B,OAAO,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAQD,+CAA+C;IACrC,kBAAkB;QAC1B,OAAO,EAAE,CAAC;IACZ,CAAC;IAES,iBAAiB;QACzB,OAAO,EAAE,CAAC;IACZ,CAAC;IAES,mBAAmB;QAC3B,OAAO,KAAK,CAAC;IACf,CAAC;IAES,iBAAiB;QACzB,OAAO,EAAE,CAAC;IACZ,CAAC;IAES,iBAAiB;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAES,gBAAgB;QACxB,OAAO,MAAM,CAAC;IAChB,CAAC;IAES,iBAAiB;QACzB,OAAO,CAAC,CAAC;IACX,CAAC;IAES,kBAAkB;QAC1B,OAAO,CAAC,CAAC;IACX,CAAC;IAED;;OAEG;IACO,aAAa,CACrB,MAAc,EACd,QAAgB;QAEhB,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAClD,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACxD,MAAM,WAAW,GAAG,YAAY,GAAG,gBAAgB,CAAC;QAEpD,MAAM,IAAI,GACR,CAAC,YAAY,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,iBAAiB,EAAE;YAChD,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,kBAAkB,EAAE,CAAC;QAExD,OAAO;YACL,aAAa,EAAE,YAAY;YAC3B,iBAAiB,EAAE,gBAAgB;YACnC,YAAY,EAAE,WAAW;YACzB,IAAI;SACL,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Detached process execution utility
|
|
3
|
+
*
|
|
4
|
+
* Spawns CLI processes as fully detached processes to avoid SIGTERM
|
|
5
|
+
* from parent process (e.g., Cursor) killing nested AI CLI instances.
|
|
6
|
+
*/
|
|
7
|
+
export interface DetachedExecOptions {
|
|
8
|
+
/** Working directory */
|
|
9
|
+
cwd?: string;
|
|
10
|
+
/** Timeout in milliseconds */
|
|
11
|
+
timeout?: number;
|
|
12
|
+
/** Environment variables */
|
|
13
|
+
env?: Record<string, string | undefined>;
|
|
14
|
+
/** Input to pass via stdin */
|
|
15
|
+
input?: string;
|
|
16
|
+
/** Abort signal */
|
|
17
|
+
signal?: AbortSignal | undefined;
|
|
18
|
+
/** Long arguments that should be read from files (map: argName -> value) */
|
|
19
|
+
longArgs?: Map<string, string>;
|
|
20
|
+
}
|
|
21
|
+
export interface DetachedExecResult {
|
|
22
|
+
/** Exit code */
|
|
23
|
+
exitCode: number;
|
|
24
|
+
/** Standard output */
|
|
25
|
+
stdout: string;
|
|
26
|
+
/** Standard error */
|
|
27
|
+
stderr: string;
|
|
28
|
+
/** Whether execution failed */
|
|
29
|
+
failed: boolean;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Execute a command as a detached process.
|
|
33
|
+
*
|
|
34
|
+
* This spawns the command in a fully detached process that won't be
|
|
35
|
+
* killed when the parent process receives SIGTERM (e.g., from Cursor).
|
|
36
|
+
*/
|
|
37
|
+
export declare function detachedExec(command: string, args: string[], options?: DetachedExecOptions): Promise<DetachedExecResult>;
|
|
38
|
+
//# sourceMappingURL=detached-exec.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"detached-exec.d.ts","sourceRoot":"","sources":["../../src/base/detached-exec.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,mBAAmB;IAClC,wBAAwB;IACxB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4BAA4B;IAC5B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC;IACzC,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mBAAmB;IACnB,MAAM,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACjC,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IACjC,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,qBAAqB;IACrB,MAAM,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,MAAM,EAAE,OAAO,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAChC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EAAE,EACd,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CA4I7B"}
|