de-agent 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/README.md +88 -0
- package/dist/config.d.ts +12 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +26 -0
- package/dist/config.js.map +1 -0
- package/dist/engine/permissions.d.ts +9 -0
- package/dist/engine/permissions.d.ts.map +1 -0
- package/dist/engine/permissions.js +40 -0
- package/dist/engine/permissions.js.map +1 -0
- package/dist/engine/queryEngine.d.ts +16 -0
- package/dist/engine/queryEngine.d.ts.map +1 -0
- package/dist/engine/queryEngine.js +154 -0
- package/dist/engine/queryEngine.js.map +1 -0
- package/dist/engine/systemPrompt.d.ts +2 -0
- package/dist/engine/systemPrompt.d.ts.map +1 -0
- package/dist/engine/systemPrompt.js +53 -0
- package/dist/engine/systemPrompt.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +108 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/openaiClient.d.ts +26 -0
- package/dist/llm/openaiClient.d.ts.map +1 -0
- package/dist/llm/openaiClient.js +69 -0
- package/dist/llm/openaiClient.js.map +1 -0
- package/dist/tools/bashTool.d.ts +2 -0
- package/dist/tools/bashTool.d.ts.map +1 -0
- package/dist/tools/bashTool.js +31 -0
- package/dist/tools/bashTool.js.map +1 -0
- package/dist/tools/fileEditTool.d.ts +2 -0
- package/dist/tools/fileEditTool.d.ts.map +1 -0
- package/dist/tools/fileEditTool.js +33 -0
- package/dist/tools/fileEditTool.js.map +1 -0
- package/dist/tools/fileReadTool.d.ts +2 -0
- package/dist/tools/fileReadTool.d.ts.map +1 -0
- package/dist/tools/fileReadTool.js +32 -0
- package/dist/tools/fileReadTool.js.map +1 -0
- package/dist/tools/fileWriteTool.d.ts +2 -0
- package/dist/tools/fileWriteTool.d.ts.map +1 -0
- package/dist/tools/fileWriteTool.js +26 -0
- package/dist/tools/fileWriteTool.js.map +1 -0
- package/dist/tools/globTool.d.ts +2 -0
- package/dist/tools/globTool.d.ts.map +1 -0
- package/dist/tools/globTool.js +65 -0
- package/dist/tools/globTool.js.map +1 -0
- package/dist/tools/grepTool.d.ts +2 -0
- package/dist/tools/grepTool.d.ts.map +1 -0
- package/dist/tools/grepTool.js +92 -0
- package/dist/tools/grepTool.js.map +1 -0
- package/dist/tools/listDirTool.d.ts +2 -0
- package/dist/tools/listDirTool.d.ts.map +1 -0
- package/dist/tools/listDirTool.js +57 -0
- package/dist/tools/listDirTool.js.map +1 -0
- package/dist/tools/tool.d.ts +28 -0
- package/dist/tools/tool.d.ts.map +1 -0
- package/dist/tools/tool.js +101 -0
- package/dist/tools/tool.js.map +1 -0
- package/dist/types.d.ts +27 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +27 -0
- package/dist/types.js.map +1 -0
- package/dist/ui/display.d.ts +13 -0
- package/dist/ui/display.d.ts.map +1 -0
- package/dist/ui/display.js +79 -0
- package/dist/ui/display.js.map +1 -0
- package/dist/ui/input.d.ts +7 -0
- package/dist/ui/input.d.ts.map +1 -0
- package/dist/ui/input.js +39 -0
- package/dist/ui/input.js.map +1 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# de-agent
|
|
2
|
+
|
|
3
|
+
A terminal-based AI Coding Agent inspired by Claude Code. Built with TypeScript, designed to assist you in your local development environment.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- **ReAct Agent Loop**: Automatically reasons, calls tools, observes results, and iterates until the task is complete.
|
|
8
|
+
- **7 Built-in Tools**: Read/write/edit files, run shell commands, grep regex, glob search, and list directories.
|
|
9
|
+
- **Multi-Model Support**: Compatible with OpenAI-style APIs, allowing you to use Claude, DeepSeek, GPT-4o, or local Ollama models.
|
|
10
|
+
- **Secure Execution**: Safe read-only commands run automatically, while dangerous operations (like `rm -rf`) require explicit user confirmation.
|
|
11
|
+
- **Streaming Output**: Real-time markdown rendering and tool execution UI directly in your terminal.
|
|
12
|
+
- **Dynamic System Prompt**: Automatically injects Git status, current working directory, OS info, and project memory (`.de-agent.md`).
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
You can install `de-agent` globally via npm:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npm install -g de-agent
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Or run it directly using `npx`:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx de-agent
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Setup
|
|
29
|
+
|
|
30
|
+
Before using `de-agent`, you need to provide an API key. By default, it expects an OpenAI-compatible API.
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
export DE_AGENT_API_KEY="your-api-key"
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Custom Model & Base URL (Optional)
|
|
37
|
+
|
|
38
|
+
If you want to use a different model or provider (e.g., DeepSeek, Claude via proxy, or Ollama):
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
export DE_AGENT_MODEL_NAME="deepseek-chat"
|
|
42
|
+
export DE_AGENT_BASE_URL="https://api.deepseek.com/v1"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
You can also create a config file at `~/.de-agent/config.json`:
|
|
46
|
+
|
|
47
|
+
```json
|
|
48
|
+
{
|
|
49
|
+
"apiKey": "your-api-key",
|
|
50
|
+
"baseUrl": "https://api.deepseek.com/v1",
|
|
51
|
+
"modelName": "deepseek-chat",
|
|
52
|
+
"permissionMode": "ask"
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Usage
|
|
57
|
+
|
|
58
|
+
### Interactive REPL Mode
|
|
59
|
+
|
|
60
|
+
Launch the interactive prompt to chat and collaborate with the agent:
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
de-agent
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### One-Shot Task Mode
|
|
67
|
+
|
|
68
|
+
Pass a prompt directly to execute a specific task and exit:
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
de-agent "Create a new Express.js hello world server in the current directory"
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### CLI Options
|
|
75
|
+
|
|
76
|
+
- `--api-key <key>`: Override the API key.
|
|
77
|
+
- `--base-url <url>`: Override the API base URL.
|
|
78
|
+
- `--model, -m <model>`: Specify the model name to use.
|
|
79
|
+
- `--auto-approve`: Automatically approve all tool calls (use with caution!).
|
|
80
|
+
- `--help`: Show help information.
|
|
81
|
+
|
|
82
|
+
## Project Memory
|
|
83
|
+
|
|
84
|
+
If you create a `.de-agent.md` file in the root of your project, the agent will automatically read it and include its contents in its system prompt. This is useful for providing project-specific instructions, coding guidelines, or architectural context.
|
|
85
|
+
|
|
86
|
+
## License
|
|
87
|
+
|
|
88
|
+
MIT
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface AgentConfig {
|
|
2
|
+
apiKey: string;
|
|
3
|
+
baseUrl: string;
|
|
4
|
+
modelName: string;
|
|
5
|
+
maxTokens: number;
|
|
6
|
+
temperature: number;
|
|
7
|
+
maxContextTokens: number;
|
|
8
|
+
permissionMode: 'auto' | 'ask';
|
|
9
|
+
maxIterations: number;
|
|
10
|
+
}
|
|
11
|
+
export declare function loadConfig(): Promise<AgentConfig>;
|
|
12
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,GAAG,KAAK,CAAC;IAC/B,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,WAAW,CAAC,CAsBvD"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import * as fs from 'fs/promises';
|
|
2
|
+
import * as os from 'os';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
export async function loadConfig() {
|
|
5
|
+
const config = {
|
|
6
|
+
apiKey: process.env.DE_AGENT_API_KEY || '',
|
|
7
|
+
baseUrl: process.env.DE_AGENT_BASE_URL || 'https://api.openai.com/v1',
|
|
8
|
+
modelName: process.env.DE_AGENT_MODEL_NAME || 'gpt-4o',
|
|
9
|
+
maxTokens: parseInt(process.env.DE_AGENT_MAX_TOKENS || '4096', 10),
|
|
10
|
+
temperature: parseFloat(process.env.DE_AGENT_TEMPERATURE || '0.0'),
|
|
11
|
+
maxContextTokens: parseInt(process.env.DE_AGENT_MAX_CONTEXT_TOKENS || '128000', 10),
|
|
12
|
+
permissionMode: process.env.DE_AGENT_PERMISSION_MODE || 'auto',
|
|
13
|
+
maxIterations: parseInt(process.env.DE_AGENT_MAX_ITERATIONS || '50', 10)
|
|
14
|
+
};
|
|
15
|
+
const configPath = path.join(os.homedir(), '.de-agent', 'config.json');
|
|
16
|
+
try {
|
|
17
|
+
const data = await fs.readFile(configPath, 'utf-8');
|
|
18
|
+
const parsed = JSON.parse(data);
|
|
19
|
+
Object.assign(config, parsed);
|
|
20
|
+
}
|
|
21
|
+
catch (err) {
|
|
22
|
+
// Ignore if config file does not exist
|
|
23
|
+
}
|
|
24
|
+
return config;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,aAAa,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAa7B,MAAM,CAAC,KAAK,UAAU,UAAU;IAC9B,MAAM,MAAM,GAAgB;QAC1B,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,EAAE;QAC1C,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,2BAA2B;QACrE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,QAAQ;QACtD,SAAS,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,MAAM,EAAE,EAAE,CAAC;QAClE,WAAW,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,KAAK,CAAC;QAClE,gBAAgB,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,QAAQ,EAAE,EAAE,CAAC;QACnF,cAAc,EAAG,OAAO,CAAC,GAAG,CAAC,wBAA2C,IAAI,MAAM;QAClF,aAAa,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,IAAI,EAAE,EAAE,CAAC;KACzE,CAAC;IAEF,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC;IACvE,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACpD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,uCAAuC;IACzC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type Tool } from '../tools/tool.js';
|
|
2
|
+
export type PermissionLevel = 'allow' | 'ask' | 'deny';
|
|
3
|
+
export declare class PermissionEvaluator {
|
|
4
|
+
private static SAFE_PREFIXES;
|
|
5
|
+
private static DANGEROUS_PATTERNS;
|
|
6
|
+
evaluateBash(command: string): PermissionLevel;
|
|
7
|
+
evaluateTool(tool: Tool, args: Record<string, unknown>): PermissionLevel;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=permissions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../../src/engine/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,IAAI,EAAE,MAAM,kBAAkB,CAAC;AAE7C,MAAM,MAAM,eAAe,GAAG,OAAO,GAAG,KAAK,GAAG,MAAM,CAAC;AAEvD,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,MAAM,CAAC,aAAa,CAK1B;IAEF,OAAO,CAAC,MAAM,CAAC,kBAAkB,CAG/B;IAEF,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,eAAe;IAe9C,YAAY,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe;CAazE"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export class PermissionEvaluator {
|
|
2
|
+
static SAFE_PREFIXES = [
|
|
3
|
+
'ls', 'cat', 'head', 'tail', 'wc', 'pwd', 'whoami', 'echo',
|
|
4
|
+
'git status', 'git log', 'git diff', 'git branch', 'git show',
|
|
5
|
+
'grep', 'find', 'which', 'type', 'file', 'stat', 'date', 'uname',
|
|
6
|
+
'node --version', 'npm --version', 'python --version',
|
|
7
|
+
];
|
|
8
|
+
static DANGEROUS_PATTERNS = [
|
|
9
|
+
'rm -rf', 'rm -r', 'rmdir', 'mkfs', 'dd if=',
|
|
10
|
+
'chmod 777', ':(){', '> /dev/', 'sudo ', 'su ',
|
|
11
|
+
];
|
|
12
|
+
evaluateBash(command) {
|
|
13
|
+
const trimmed = command.trim();
|
|
14
|
+
for (const pattern of PermissionEvaluator.DANGEROUS_PATTERNS) {
|
|
15
|
+
if (trimmed.includes(pattern)) {
|
|
16
|
+
return 'deny';
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
for (const prefix of PermissionEvaluator.SAFE_PREFIXES) {
|
|
20
|
+
if (trimmed.startsWith(prefix)) {
|
|
21
|
+
return 'allow';
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return 'ask';
|
|
25
|
+
}
|
|
26
|
+
evaluateTool(tool, args) {
|
|
27
|
+
if (tool.name === 'execute_bash' || tool.name === 'bash') {
|
|
28
|
+
const command = (args.command || args.code);
|
|
29
|
+
if (typeof command === 'string') {
|
|
30
|
+
return this.evaluateBash(command);
|
|
31
|
+
}
|
|
32
|
+
return 'ask';
|
|
33
|
+
}
|
|
34
|
+
if (tool.name === 'write_file' || tool.name === 'edit_file') {
|
|
35
|
+
return 'ask';
|
|
36
|
+
}
|
|
37
|
+
return 'allow';
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=permissions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permissions.js","sourceRoot":"","sources":["../../src/engine/permissions.ts"],"names":[],"mappings":"AAIA,MAAM,OAAO,mBAAmB;IACtB,MAAM,CAAC,aAAa,GAAG;QAC7B,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM;QAC1D,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU;QAC7D,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO;QAChE,gBAAgB,EAAE,eAAe,EAAE,kBAAkB;KACtD,CAAC;IAEM,MAAM,CAAC,kBAAkB,GAAG;QAClC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ;QAC5C,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,KAAK;KAC/C,CAAC;IAEF,YAAY,CAAC,OAAe;QAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;QAC/B,KAAK,MAAM,OAAO,IAAI,mBAAmB,CAAC,kBAAkB,EAAE,CAAC;YAC7D,IAAI,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9B,OAAO,MAAM,CAAC;YAChB,CAAC;QACH,CAAC;QACD,KAAK,MAAM,MAAM,IAAI,mBAAmB,CAAC,aAAa,EAAE,CAAC;YACvD,IAAI,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC/B,OAAO,OAAO,CAAC;YACjB,CAAC;QACH,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,YAAY,CAAC,IAAU,EAAE,IAA6B;QACpD,IAAI,IAAI,CAAC,IAAI,KAAK,cAAc,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzD,MAAM,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,CAAW,CAAC;YACtD,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAChC,OAAO,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;YACpC,CAAC;YACD,OAAO,KAAK,CAAC;QACf,CAAC;QACD,IAAI,IAAI,CAAC,IAAI,KAAK,YAAY,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC5D,OAAO,KAAK,CAAC;QACf,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { type AgentConfig } from '../config.js';
|
|
2
|
+
import { type ToolRegistry } from '../tools/tool.js';
|
|
3
|
+
import { PermissionEvaluator } from './permissions.js';
|
|
4
|
+
import { OpenAIClient } from '../llm/openaiClient.js';
|
|
5
|
+
import { Display } from '../ui/display.js';
|
|
6
|
+
export declare class QueryEngine {
|
|
7
|
+
private config;
|
|
8
|
+
private llmClient;
|
|
9
|
+
private toolRegistry;
|
|
10
|
+
private permissionEvaluator;
|
|
11
|
+
private display;
|
|
12
|
+
private history;
|
|
13
|
+
constructor(config: AgentConfig, llmClient: OpenAIClient, toolRegistry: ToolRegistry, permissionEvaluator: PermissionEvaluator, display: Display);
|
|
14
|
+
run(userMessage: string): Promise<string>;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=queryEngine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryEngine.d.ts","sourceRoot":"","sources":["../../src/engine/queryEngine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,cAAc,CAAC;AAEhD,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAoB,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAG3C,qBAAa,WAAW;IACtB,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,YAAY,CAAe;IACnC,OAAO,CAAC,mBAAmB,CAAsB;IACjD,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,OAAO,CAAsB;gBAGnC,MAAM,EAAE,WAAW,EACnB,SAAS,EAAE,YAAY,EACvB,YAAY,EAAE,YAAY,EAC1B,mBAAmB,EAAE,mBAAmB,EACxC,OAAO,EAAE,OAAO;IAYZ,GAAG,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CA2IhD"}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import { ConversationHistory } from '../types.js';
|
|
2
|
+
import { buildSystemPrompt } from './systemPrompt.js';
|
|
3
|
+
export class QueryEngine {
|
|
4
|
+
config;
|
|
5
|
+
llmClient;
|
|
6
|
+
toolRegistry;
|
|
7
|
+
permissionEvaluator;
|
|
8
|
+
display;
|
|
9
|
+
history;
|
|
10
|
+
constructor(config, llmClient, toolRegistry, permissionEvaluator, display) {
|
|
11
|
+
this.config = config;
|
|
12
|
+
this.llmClient = llmClient;
|
|
13
|
+
this.toolRegistry = toolRegistry;
|
|
14
|
+
this.permissionEvaluator = permissionEvaluator;
|
|
15
|
+
this.display = display;
|
|
16
|
+
this.history = new ConversationHistory();
|
|
17
|
+
const toolNames = toolRegistry.getAll().map(t => t.name);
|
|
18
|
+
this.history.addMessage({ role: 'system', content: buildSystemPrompt(process.cwd(), toolNames) });
|
|
19
|
+
}
|
|
20
|
+
async run(userMessage) {
|
|
21
|
+
this.history.addMessage({ role: 'user', content: userMessage });
|
|
22
|
+
let iterations = 0;
|
|
23
|
+
const maxIterations = this.config.maxIterations || 10;
|
|
24
|
+
while (iterations < maxIterations) {
|
|
25
|
+
iterations++;
|
|
26
|
+
this.history.truncateToFit(this.config.maxContextTokens || 128000);
|
|
27
|
+
const messages = this.history.getMessages();
|
|
28
|
+
const tools = this.toolRegistry.getAllSchemas();
|
|
29
|
+
const stream = this.llmClient.chatStream({
|
|
30
|
+
messages,
|
|
31
|
+
tools,
|
|
32
|
+
model: this.config.modelName,
|
|
33
|
+
temperature: this.config.temperature || 0,
|
|
34
|
+
maxTokens: this.config.maxTokens || 4096,
|
|
35
|
+
});
|
|
36
|
+
let fullText = '';
|
|
37
|
+
const toolCallsMap = new Map();
|
|
38
|
+
for await (const chunk of stream) {
|
|
39
|
+
if (chunk.type === 'text_delta') {
|
|
40
|
+
fullText += chunk.content;
|
|
41
|
+
this.display.streamText(chunk.content);
|
|
42
|
+
}
|
|
43
|
+
else if (chunk.type === 'tool_call_delta') {
|
|
44
|
+
const tc = chunk.toolCall;
|
|
45
|
+
if (!toolCallsMap.has(tc.index)) {
|
|
46
|
+
toolCallsMap.set(tc.index, { id: tc.id || '', name: tc.name || '', arguments: tc.arguments || '' });
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
const existing = toolCallsMap.get(tc.index);
|
|
50
|
+
if (tc.id)
|
|
51
|
+
existing.id = tc.id;
|
|
52
|
+
if (tc.name)
|
|
53
|
+
existing.name += tc.name;
|
|
54
|
+
if (tc.arguments)
|
|
55
|
+
existing.arguments += tc.arguments;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else if (chunk.type === 'done') {
|
|
59
|
+
if (fullText)
|
|
60
|
+
this.display.endStream();
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (toolCallsMap.size === 0) {
|
|
64
|
+
// Fallback for DeepSeek models that output raw DSML instead of standard tool calls
|
|
65
|
+
const dsmlMatch = fullText.match(/<||DSML|| calls>([\s\S]*?)<\/||DSML|| calls>/);
|
|
66
|
+
if (dsmlMatch) {
|
|
67
|
+
const invokeRegex = /<||DSML|| invoke name="([^"]+)">([\s\S]*?)<\/||DSML|| invoke>/g;
|
|
68
|
+
let match;
|
|
69
|
+
let index = 0;
|
|
70
|
+
while ((match = invokeRegex.exec(dsmlMatch[1])) !== null) {
|
|
71
|
+
const toolName = match[1];
|
|
72
|
+
const paramsBlock = match[2];
|
|
73
|
+
const paramRegex = /<||DSML|| parameter name="([^"]+)"(?:[^>]*)>([\s\S]*?)<\/||DSML|| parameter>/g;
|
|
74
|
+
const args = {};
|
|
75
|
+
let pMatch;
|
|
76
|
+
while ((pMatch = paramRegex.exec(paramsBlock)) !== null) {
|
|
77
|
+
args[pMatch[1]] = pMatch[2];
|
|
78
|
+
}
|
|
79
|
+
// Map common name mismatches
|
|
80
|
+
let mappedName = toolName;
|
|
81
|
+
if (toolName.toLowerCase() === 'bash' || toolName === 'run_command')
|
|
82
|
+
mappedName = 'bash';
|
|
83
|
+
toolCallsMap.set(index, {
|
|
84
|
+
id: `call_dsml_${Date.now()}_${index}`,
|
|
85
|
+
name: mappedName,
|
|
86
|
+
arguments: JSON.stringify(args)
|
|
87
|
+
});
|
|
88
|
+
index++;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (toolCallsMap.size === 0) {
|
|
93
|
+
this.history.addMessage({ role: 'assistant', content: fullText });
|
|
94
|
+
return fullText;
|
|
95
|
+
}
|
|
96
|
+
const toolCallsList = [];
|
|
97
|
+
for (const tc of toolCallsMap.values()) {
|
|
98
|
+
let args = {};
|
|
99
|
+
try {
|
|
100
|
+
args = tc.arguments ? JSON.parse(tc.arguments) : {};
|
|
101
|
+
}
|
|
102
|
+
catch (e) {
|
|
103
|
+
// ignore parsing errors here, fail below during tool execution validation
|
|
104
|
+
}
|
|
105
|
+
toolCallsList.push({
|
|
106
|
+
id: tc.id,
|
|
107
|
+
name: tc.name,
|
|
108
|
+
arguments: args
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
this.history.addMessage({ role: 'assistant', content: fullText || undefined, toolCalls: toolCallsList });
|
|
112
|
+
for (const tc of toolCallsList) {
|
|
113
|
+
const tool = this.toolRegistry.get(tc.name);
|
|
114
|
+
if (!tool) {
|
|
115
|
+
const errRes = { role: 'tool', toolCallId: tc.id, name: tc.name, content: `Tool not found: ${tc.name}` };
|
|
116
|
+
this.history.addMessage(errRes);
|
|
117
|
+
this.display.printToolResult(tc.name, errRes.content, true);
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
this.display.printToolUse(tc.name, tc.arguments);
|
|
121
|
+
const perm = this.permissionEvaluator.evaluateTool(tool, tc.arguments);
|
|
122
|
+
if (perm === 'deny') {
|
|
123
|
+
const errRes = { role: 'tool', toolCallId: tc.id, name: tc.name, content: `Execution denied by safety policy.` };
|
|
124
|
+
this.history.addMessage(errRes);
|
|
125
|
+
this.display.printToolResult(tc.name, errRes.content, true);
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
else if (perm === 'ask' && this.config.permissionMode !== 'auto') {
|
|
129
|
+
const desc = JSON.stringify(tc.arguments, null, 2);
|
|
130
|
+
const approved = await this.display.askPermission(tc.name, desc);
|
|
131
|
+
if (!approved) {
|
|
132
|
+
const errRes = { role: 'tool', toolCallId: tc.id, name: tc.name, content: `Execution cancelled by user.` };
|
|
133
|
+
this.history.addMessage(errRes);
|
|
134
|
+
this.display.printToolResult(tc.name, errRes.content, true);
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
const result = await tool.execute(tc.arguments);
|
|
140
|
+
const resMsg = { role: 'tool', toolCallId: tc.id, name: tc.name, content: String(result) };
|
|
141
|
+
this.history.addMessage(resMsg);
|
|
142
|
+
this.display.printToolResult(tc.name, resMsg.content, false);
|
|
143
|
+
}
|
|
144
|
+
catch (error) {
|
|
145
|
+
const errRes = { role: 'tool', toolCallId: tc.id, name: tc.name, content: `Tool execution failed: ${error.message}` };
|
|
146
|
+
this.history.addMessage(errRes);
|
|
147
|
+
this.display.printToolResult(tc.name, errRes.content, true);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
throw new Error('Max iterations reached.');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
//# sourceMappingURL=queryEngine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"queryEngine.js","sourceRoot":"","sources":["../../src/engine/queryEngine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemPrompt.d.ts","sourceRoot":"","sources":["../../src/engine/systemPrompt.ts"],"names":[],"mappings":"AAKA,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,EAAO,GAAG,MAAM,CAiD/E"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import { readFileSync, existsSync } from 'fs';
|
|
3
|
+
import { join } from 'path';
|
|
4
|
+
import * as os from 'os';
|
|
5
|
+
export function buildSystemPrompt(cwd, toolNames = []) {
|
|
6
|
+
let gitInfo = 'Git repository not found or git command failed.';
|
|
7
|
+
try {
|
|
8
|
+
const execOpts = { cwd, encoding: 'utf-8', stdio: ['pipe', 'pipe', 'ignore'] };
|
|
9
|
+
const branch = execSync('git branch --show-current', execOpts).trim();
|
|
10
|
+
const status = execSync('git status --short', execOpts).trim();
|
|
11
|
+
const lastCommits = execSync('git log -n 5 --oneline', execOpts).trim();
|
|
12
|
+
gitInfo = `Git Branch: ${branch}\nGit Status:\n${status || 'Clean'}\nLast 5 Commits:\n${lastCommits}`;
|
|
13
|
+
}
|
|
14
|
+
catch (e) {
|
|
15
|
+
// ignore
|
|
16
|
+
}
|
|
17
|
+
const memoryFile = join(cwd, '.de-agent.md');
|
|
18
|
+
let projectMemory = '';
|
|
19
|
+
if (existsSync(memoryFile)) {
|
|
20
|
+
try {
|
|
21
|
+
projectMemory = readFileSync(memoryFile, 'utf-8');
|
|
22
|
+
}
|
|
23
|
+
catch (e) {
|
|
24
|
+
projectMemory = 'Failed to read .de-agent.md';
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
const dateStr = new Date().toISOString();
|
|
28
|
+
return `You are de-agent, an expert AI programming assistant and autonomous agent.
|
|
29
|
+
Your goal is to help the user with programming tasks by writing code, executing commands, and interacting with the system.
|
|
30
|
+
|
|
31
|
+
Environment Information:
|
|
32
|
+
- Current Working Directory: ${cwd}
|
|
33
|
+
- OS: ${os.platform()} ${os.release()}
|
|
34
|
+
- Date/Time: ${dateStr}
|
|
35
|
+
|
|
36
|
+
Version Control:
|
|
37
|
+
${gitInfo}
|
|
38
|
+
|
|
39
|
+
Project Memory (.de-agent.md):
|
|
40
|
+
${projectMemory || 'None'}
|
|
41
|
+
|
|
42
|
+
Available Tools:
|
|
43
|
+
You have access to the following tools: ${toolNames.join(', ')}.
|
|
44
|
+
Always use the EXACT tool name. For example, if you want to run a command, use "bash". If you want to list a directory, use "list_dir".
|
|
45
|
+
|
|
46
|
+
Behavioral Rules:
|
|
47
|
+
1. Be concise. Do not explain unnecessarily unless asked.
|
|
48
|
+
2. Use tools to accomplish tasks.
|
|
49
|
+
3. Validate output of commands.
|
|
50
|
+
4. If something fails, attempt to fix it or explain the issue clearly.
|
|
51
|
+
`;
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=systemPrompt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"systemPrompt.js","sourceRoot":"","sources":["../../src/engine/systemPrompt.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAEzB,MAAM,UAAU,iBAAiB,CAAC,GAAW,EAAE,YAAsB,EAAE;IACrE,IAAI,OAAO,GAAG,iDAAiD,CAAC;IAChE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAgB,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAA+B,EAAE,CAAC;QACtH,MAAM,MAAM,GAAG,QAAQ,CAAC,2BAA2B,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACtE,MAAM,MAAM,GAAG,QAAQ,CAAC,oBAAoB,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/D,MAAM,WAAW,GAAG,QAAQ,CAAC,wBAAwB,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QAExE,OAAO,GAAG,eAAe,MAAM,kBAAkB,MAAM,IAAI,OAAO,sBAAsB,WAAW,EAAE,CAAC;IACxG,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,SAAS;IACX,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,EAAE,cAAc,CAAC,CAAC;IAC7C,IAAI,aAAa,GAAG,EAAE,CAAC;IACvB,IAAI,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,IAAI,CAAC;YACH,aAAa,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,aAAa,GAAG,6BAA6B,CAAC;QAChD,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAEzC,OAAO;;;;+BAIsB,GAAG;QAC1B,EAAE,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE;eACtB,OAAO;;;EAGpB,OAAO;;;EAGP,aAAa,IAAI,MAAM;;;0CAGiB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC;;;;;;;;CAQ7D,CAAC;AACF,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { loadConfig } from './config.js';
|
|
3
|
+
import { ToolRegistry } from './tools/tool.js';
|
|
4
|
+
import { PermissionEvaluator } from './engine/permissions.js';
|
|
5
|
+
import { OpenAIClient } from './llm/openaiClient.js';
|
|
6
|
+
import { Display } from './ui/display.js';
|
|
7
|
+
import { Input } from './ui/input.js';
|
|
8
|
+
import { QueryEngine } from './engine/queryEngine.js';
|
|
9
|
+
import { fileReadTool } from './tools/fileReadTool.js';
|
|
10
|
+
import { fileWriteTool } from './tools/fileWriteTool.js';
|
|
11
|
+
import { fileEditTool } from './tools/fileEditTool.js';
|
|
12
|
+
import { globTool } from './tools/globTool.js';
|
|
13
|
+
import { grepTool } from './tools/grepTool.js';
|
|
14
|
+
import { bashTool } from './tools/bashTool.js';
|
|
15
|
+
import { listDirTool } from './tools/listDirTool.js';
|
|
16
|
+
async function main() {
|
|
17
|
+
const args = process.argv.slice(2);
|
|
18
|
+
let prompt;
|
|
19
|
+
const cliOverrides = {};
|
|
20
|
+
for (let i = 0; i < args.length; i++) {
|
|
21
|
+
const arg = args[i];
|
|
22
|
+
if (arg === '--help' || arg === '-h') {
|
|
23
|
+
console.log(`
|
|
24
|
+
Usage: de-agent [options] [prompt]
|
|
25
|
+
|
|
26
|
+
Options:
|
|
27
|
+
--api-key <key> Set OpenAI/API key
|
|
28
|
+
--base-url <url> Set API base URL
|
|
29
|
+
--model, -m <model> Specify the model to use
|
|
30
|
+
--auto-approve Skip confirmation for all tool executions
|
|
31
|
+
--help, -h Show this help message
|
|
32
|
+
|
|
33
|
+
Examples:
|
|
34
|
+
de-agent Launch interactive REPL mode
|
|
35
|
+
de-agent "create a react app" Run a one-shot task
|
|
36
|
+
`);
|
|
37
|
+
process.exit(0);
|
|
38
|
+
}
|
|
39
|
+
else if (arg === '--model' || arg === '-m') {
|
|
40
|
+
cliOverrides.model = args[++i];
|
|
41
|
+
}
|
|
42
|
+
else if (arg === '--api-key') {
|
|
43
|
+
cliOverrides.apiKey = args[++i];
|
|
44
|
+
}
|
|
45
|
+
else if (arg === '--base-url') {
|
|
46
|
+
cliOverrides.baseUrl = args[++i];
|
|
47
|
+
}
|
|
48
|
+
else if (arg === '--auto-approve') {
|
|
49
|
+
cliOverrides.autoApprove = true;
|
|
50
|
+
}
|
|
51
|
+
else if (!arg.startsWith('-')) {
|
|
52
|
+
prompt = arg;
|
|
53
|
+
}
|
|
54
|
+
else {
|
|
55
|
+
console.error(`Unknown option: ${arg}`);
|
|
56
|
+
process.exit(1);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const config = await loadConfig();
|
|
60
|
+
const finalConfig = { ...config, ...cliOverrides };
|
|
61
|
+
if (!finalConfig.apiKey) {
|
|
62
|
+
console.error('Error: API key is required. Set DE_AGENT_API_KEY environment variable or pass --api-key.');
|
|
63
|
+
process.exit(1);
|
|
64
|
+
}
|
|
65
|
+
const llmClient = new OpenAIClient(finalConfig.apiKey, finalConfig.baseUrl);
|
|
66
|
+
const toolRegistry = new ToolRegistry();
|
|
67
|
+
toolRegistry.register(fileReadTool);
|
|
68
|
+
toolRegistry.register(fileWriteTool);
|
|
69
|
+
toolRegistry.register(fileEditTool);
|
|
70
|
+
toolRegistry.register(globTool);
|
|
71
|
+
toolRegistry.register(grepTool);
|
|
72
|
+
toolRegistry.register(bashTool);
|
|
73
|
+
toolRegistry.register(listDirTool);
|
|
74
|
+
const permissionEvaluator = new PermissionEvaluator();
|
|
75
|
+
const display = new Display();
|
|
76
|
+
const queryEngine = new QueryEngine(finalConfig, llmClient, toolRegistry, permissionEvaluator, display);
|
|
77
|
+
display.printWelcome();
|
|
78
|
+
if (prompt) {
|
|
79
|
+
display.printUserMessage(prompt);
|
|
80
|
+
try {
|
|
81
|
+
await queryEngine.run(prompt);
|
|
82
|
+
}
|
|
83
|
+
catch (e) {
|
|
84
|
+
display.printError(e.message);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
const input = new Input();
|
|
89
|
+
while (true) {
|
|
90
|
+
const userMessage = await input.getInput();
|
|
91
|
+
if (userMessage === null) {
|
|
92
|
+
break;
|
|
93
|
+
}
|
|
94
|
+
try {
|
|
95
|
+
await queryEngine.run(userMessage);
|
|
96
|
+
}
|
|
97
|
+
catch (e) {
|
|
98
|
+
display.printError(e.message);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
input.close();
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
main().catch(err => {
|
|
105
|
+
console.error(err);
|
|
106
|
+
process.exit(1);
|
|
107
|
+
});
|
|
108
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export type StreamEvent = {
|
|
2
|
+
type: 'text_delta';
|
|
3
|
+
content: string;
|
|
4
|
+
} | {
|
|
5
|
+
type: 'tool_call_delta';
|
|
6
|
+
toolCall: {
|
|
7
|
+
index: number;
|
|
8
|
+
id?: string;
|
|
9
|
+
name?: string;
|
|
10
|
+
arguments?: string;
|
|
11
|
+
};
|
|
12
|
+
} | {
|
|
13
|
+
type: 'done';
|
|
14
|
+
};
|
|
15
|
+
export declare class OpenAIClient {
|
|
16
|
+
private openai;
|
|
17
|
+
constructor(apiKey: string, baseUrl?: string);
|
|
18
|
+
chatStream(params: {
|
|
19
|
+
messages: any[];
|
|
20
|
+
tools?: any[];
|
|
21
|
+
model: string;
|
|
22
|
+
temperature: number;
|
|
23
|
+
maxTokens: number;
|
|
24
|
+
}): AsyncGenerator<StreamEvent>;
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=openaiClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openaiClient.d.ts","sourceRoot":"","sources":["../../src/llm/openaiClient.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACvC;IAAE,IAAI,EAAE,iBAAiB,CAAC;IAAC,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACxG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErB,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM;IAOrC,UAAU,CAAC,MAAM,EAAE;QACxB,QAAQ,EAAE,GAAG,EAAE,CAAC;QAChB,KAAK,CAAC,EAAE,GAAG,EAAE,CAAC;QACd,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,cAAc,CAAC,WAAW,CAAC;CA0DhC"}
|