@arts1234567/arc-code 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/LICENSE +21 -0
- package/README.md +109 -0
- package/bin/arc.js +5 -0
- package/dist/agent/executor.js +78 -0
- package/dist/agent/executor.js.map +1 -0
- package/dist/agent/memory.js +57 -0
- package/dist/agent/memory.js.map +1 -0
- package/dist/agent/orchestrator.js +153 -0
- package/dist/agent/orchestrator.js.map +1 -0
- package/dist/agent/planner.js +26 -0
- package/dist/agent/planner.js.map +1 -0
- package/dist/agent/retriever.js +151 -0
- package/dist/agent/retriever.js.map +1 -0
- package/dist/agent/verifier.js +24 -0
- package/dist/agent/verifier.js.map +1 -0
- package/dist/cli.js +33 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.js +47 -0
- package/dist/config.js.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/llm/compaction.js +108 -0
- package/dist/llm/compaction.js.map +1 -0
- package/dist/llm/provider.js +201 -0
- package/dist/llm/provider.js.map +1 -0
- package/dist/llm/system.js +40 -0
- package/dist/llm/system.js.map +1 -0
- package/dist/llm/types.js +4 -0
- package/dist/llm/types.js.map +1 -0
- package/dist/run-interactive.js +22 -0
- package/dist/run-interactive.js.map +1 -0
- package/dist/run-single.js +72 -0
- package/dist/run-single.js.map +1 -0
- package/dist/state.js +75 -0
- package/dist/state.js.map +1 -0
- package/dist/tools/delete.js +63 -0
- package/dist/tools/delete.js.map +1 -0
- package/dist/tools/edit.js +67 -0
- package/dist/tools/edit.js.map +1 -0
- package/dist/tools/execute.js +85 -0
- package/dist/tools/execute.js.map +1 -0
- package/dist/tools/index.js +36 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/list.js +66 -0
- package/dist/tools/list.js.map +1 -0
- package/dist/tools/move.js +56 -0
- package/dist/tools/move.js.map +1 -0
- package/dist/tools/read.js +84 -0
- package/dist/tools/read.js.map +1 -0
- package/dist/tools/read_image.js +67 -0
- package/dist/tools/read_image.js.map +1 -0
- package/dist/tools/search.js +177 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/websearch.js +106 -0
- package/dist/tools/websearch.js.map +1 -0
- package/dist/tools/write.js +47 -0
- package/dist/tools/write.js.map +1 -0
- package/dist/ui/ChatWindow.js +143 -0
- package/dist/ui/ChatWindow.js.map +1 -0
- package/dist/ui/InputBar.js +136 -0
- package/dist/ui/InputBar.js.map +1 -0
- package/dist/ui/ThinkingIndicator.js +67 -0
- package/dist/ui/ThinkingIndicator.js.map +1 -0
- package/dist/ui/commands.js +395 -0
- package/dist/ui/commands.js.map +1 -0
- package/dist/ui/mascot.js +41 -0
- package/dist/ui/mascot.js.map +1 -0
- package/dist/ui/theme.js +43 -0
- package/dist/ui/theme.js.map +1 -0
- package/dist/ui/tui.js +297 -0
- package/dist/ui/tui.js.map +1 -0
- package/dist/ui/words.js +161 -0
- package/dist/ui/words.js.map +1 -0
- package/package.json +64 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Arc-code
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Arc-code
|
|
2
|
+
|
|
3
|
+
> AI-powered coding CLI with **Arc 3.4 Ultra**.
|
|
4
|
+
|
|
5
|
+
Arc-code is an agentic coding assistant that runs in your terminal. It can read files, write code, search your workspace, and run shell commands — all through a single conversational interface.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
**One command. Works on Windows, Mac, and Linux.** Node.js is installed automatically if you don't have it.
|
|
10
|
+
|
|
11
|
+
**Mac / Linux:**
|
|
12
|
+
```bash
|
|
13
|
+
curl -fsSL https://raw.githubusercontent.com/artsblr-bot/arc-code/main/install.sh | bash
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**Windows (PowerShell):**
|
|
17
|
+
```powershell
|
|
18
|
+
iwr -useb https://raw.githubusercontent.com/artsblr-bot/arc-code/main/install.ps1 | iex
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Then run:
|
|
22
|
+
```bash
|
|
23
|
+
arc
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
- **Arc 3.4 Ultra** model with extended thinking, always on.
|
|
29
|
+
- Five focused tools: `read_file`, `write_file`, `list_directory`, `search_files`, `execute_command`.
|
|
30
|
+
- Orange-themed TUI inspired by Claude Code, with a tiny lightning-bug mascot.
|
|
31
|
+
- Animated thinking indicator: spinner + rotating status word + progress bar.
|
|
32
|
+
- Auto-compaction: long conversations are summarised so the context window never overflows.
|
|
33
|
+
- Single key hardcoded for the build. Nothing about the underlying provider appears in the CLI output.
|
|
34
|
+
|
|
35
|
+
## Install
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
npm install
|
|
39
|
+
npm run build
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Run
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
# interactive TUI
|
|
46
|
+
npm start
|
|
47
|
+
|
|
48
|
+
# or directly
|
|
49
|
+
node bin/arc.js start
|
|
50
|
+
|
|
51
|
+
# non-interactive single prompt
|
|
52
|
+
node bin/arc.js start -q "what does this project do?"
|
|
53
|
+
|
|
54
|
+
# in a different directory
|
|
55
|
+
node bin/arc.js start -d /path/to/project
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Commands inside the TUI
|
|
59
|
+
|
|
60
|
+
- Type a message, press `Enter` to send.
|
|
61
|
+
- `Ctrl+C` to exit.
|
|
62
|
+
|
|
63
|
+
## Tests
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npm test # runs both smoke + TUI smoke
|
|
67
|
+
npm run test:smoke
|
|
68
|
+
npm run test:tui
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## Project layout
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
src/
|
|
75
|
+
config.ts # encoded key + model constants
|
|
76
|
+
state.ts # state manager
|
|
77
|
+
llm/
|
|
78
|
+
provider.ts # upstream chat client
|
|
79
|
+
system.ts # Arc 3.4 Ultra system prompt
|
|
80
|
+
compaction.ts # context-window compactor
|
|
81
|
+
types.ts # shared LLM types
|
|
82
|
+
tools/
|
|
83
|
+
read.ts # read_file
|
|
84
|
+
write.ts # write_file
|
|
85
|
+
list.ts # list_directory
|
|
86
|
+
search.ts # search_files (ripgrep + fallback)
|
|
87
|
+
execute.ts # execute_command
|
|
88
|
+
agent/
|
|
89
|
+
orchestrator.ts # main reasoning loop
|
|
90
|
+
planner.ts # step planner
|
|
91
|
+
executor.ts # tool dispatch
|
|
92
|
+
verifier.ts # output validation
|
|
93
|
+
retriever.ts # simple RAG over the workspace
|
|
94
|
+
memory.ts # long-term fact store
|
|
95
|
+
ui/
|
|
96
|
+
tui.tsx # main Ink app
|
|
97
|
+
theme.ts # orange palette
|
|
98
|
+
mascot.tsx # lightning-bug art
|
|
99
|
+
ChatWindow.tsx # conversation log
|
|
100
|
+
ThinkingIndicator.tsx # spinner + word + progress bar
|
|
101
|
+
InputBar.tsx # prompt input
|
|
102
|
+
words.ts # ~150 rotating status words
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Notes
|
|
106
|
+
|
|
107
|
+
- Thinking mode is always enabled. There is no command-line flag to turn it off.
|
|
108
|
+
- The model identifies itself as **Arc 3.4 Ultra** if asked.
|
|
109
|
+
- The key is encoded as char-code arrays in `src/config.ts` so the full string does not appear in the compiled binary.
|
package/bin/arc.js
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
// Arc-code Agent: Executor
|
|
2
|
+
// Dispatches tool calls to the matching tool implementation and returns
|
|
3
|
+
// tool-result messages for the conversation.
|
|
4
|
+
import { getTool } from "../tools/index.js";
|
|
5
|
+
import { IMAGE_SENTINEL } from "../tools/read_image.js";
|
|
6
|
+
import { verifyToolResult } from "./verifier.js";
|
|
7
|
+
export async function executeToolCalls(calls, ctx) {
|
|
8
|
+
const out = [];
|
|
9
|
+
for (const call of calls) {
|
|
10
|
+
const tool = getTool(call.function.name);
|
|
11
|
+
if (!tool) {
|
|
12
|
+
const errMsg = {
|
|
13
|
+
role: "tool",
|
|
14
|
+
tool_call_id: call.id,
|
|
15
|
+
name: call.function.name,
|
|
16
|
+
content: `Error: unknown tool '${call.function.name}'.`,
|
|
17
|
+
};
|
|
18
|
+
out.push({ toolCall: call, resultMessage: errMsg, ok: false });
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
let args = {};
|
|
22
|
+
try {
|
|
23
|
+
args = JSON.parse(call.function.arguments || "{}");
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
const errMsg = {
|
|
27
|
+
role: "tool",
|
|
28
|
+
tool_call_id: call.id,
|
|
29
|
+
name: call.function.name,
|
|
30
|
+
content: `Error: invalid JSON arguments - ${err?.message ?? err}`,
|
|
31
|
+
};
|
|
32
|
+
out.push({ toolCall: call, resultMessage: errMsg, ok: false });
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
let result;
|
|
36
|
+
try {
|
|
37
|
+
result = await tool.execute(args, ctx);
|
|
38
|
+
}
|
|
39
|
+
catch (err) {
|
|
40
|
+
result = `Error executing tool: ${err?.message ?? err}`;
|
|
41
|
+
}
|
|
42
|
+
// ── Vision upgrade ──────────────────────────────────────────────────────
|
|
43
|
+
// When read_image returns an ARC_IMAGE:: sentinel, build a multimodal
|
|
44
|
+
// tool-result message containing both a text label and the image block.
|
|
45
|
+
if (result.startsWith(IMAGE_SENTINEL)) {
|
|
46
|
+
const dataUri = result.slice(IMAGE_SENTINEL.length);
|
|
47
|
+
const fileName = args.path.split(/[\\/]/).pop() ?? "image";
|
|
48
|
+
const blocks = [
|
|
49
|
+
{ type: "text", text: `Image loaded: ${fileName}` },
|
|
50
|
+
{ type: "image_url", image_url: { url: dataUri } },
|
|
51
|
+
];
|
|
52
|
+
out.push({
|
|
53
|
+
toolCall: call,
|
|
54
|
+
resultMessage: {
|
|
55
|
+
role: "tool",
|
|
56
|
+
tool_call_id: call.id,
|
|
57
|
+
name: call.function.name,
|
|
58
|
+
content: blocks,
|
|
59
|
+
},
|
|
60
|
+
ok: true,
|
|
61
|
+
});
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const verification = verifyToolResult(call.function.name, args, result);
|
|
65
|
+
out.push({
|
|
66
|
+
toolCall: call,
|
|
67
|
+
resultMessage: {
|
|
68
|
+
role: "tool",
|
|
69
|
+
tool_call_id: call.id,
|
|
70
|
+
name: call.function.name,
|
|
71
|
+
content: result,
|
|
72
|
+
},
|
|
73
|
+
ok: verification.ok,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
return out;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/agent/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Arc-code Agent: Memory
|
|
2
|
+
// Short-term (in-conversation) and a small long-term fact list. Per blueprint's
|
|
3
|
+
// "Memory/Knowledge" component.
|
|
4
|
+
import { promises as fs } from "fs";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
import * as os from "os";
|
|
7
|
+
function defaultMemoryDir() {
|
|
8
|
+
return path.join(os.homedir(), ".arc-code");
|
|
9
|
+
}
|
|
10
|
+
export class Memory {
|
|
11
|
+
facts = new Map();
|
|
12
|
+
loaded = false;
|
|
13
|
+
memoryDir;
|
|
14
|
+
memoryFile;
|
|
15
|
+
constructor(opts) {
|
|
16
|
+
this.memoryDir = opts?.dir ?? defaultMemoryDir();
|
|
17
|
+
this.memoryFile = path.join(this.memoryDir, "memory.json");
|
|
18
|
+
}
|
|
19
|
+
async load() {
|
|
20
|
+
if (this.loaded)
|
|
21
|
+
return;
|
|
22
|
+
try {
|
|
23
|
+
await fs.mkdir(this.memoryDir, { recursive: true });
|
|
24
|
+
const buf = await fs.readFile(this.memoryFile, "utf-8");
|
|
25
|
+
const arr = JSON.parse(buf);
|
|
26
|
+
for (const f of arr)
|
|
27
|
+
this.facts.set(f.key, f);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
// first run - no memory file yet
|
|
31
|
+
}
|
|
32
|
+
this.loaded = true;
|
|
33
|
+
}
|
|
34
|
+
async save() {
|
|
35
|
+
try {
|
|
36
|
+
await fs.mkdir(this.memoryDir, { recursive: true });
|
|
37
|
+
const arr = Array.from(this.facts.values());
|
|
38
|
+
await fs.writeFile(this.memoryFile, JSON.stringify(arr, null, 2), "utf-8");
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
// best-effort
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
remember(key, value) {
|
|
45
|
+
this.facts.set(key, { key, value, updated: Date.now() });
|
|
46
|
+
}
|
|
47
|
+
recall(key) {
|
|
48
|
+
return this.facts.get(key)?.value;
|
|
49
|
+
}
|
|
50
|
+
asContextBlock() {
|
|
51
|
+
if (this.facts.size === 0)
|
|
52
|
+
return "";
|
|
53
|
+
const lines = Array.from(this.facts.values()).map((f) => `- ${f.key}: ${f.value}`);
|
|
54
|
+
return `Long-term memory:\n${lines.join("\n")}`;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=memory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory.js","sourceRoot":"","sources":["../../src/agent/memory.ts"],"names":[],"mappings":"AAAA,yBAAyB;AACzB,gFAAgF;AAChF,gCAAgC;AAEhC,OAAO,EAAE,QAAQ,IAAI,EAAE,EAAE,MAAM,IAAI,CAAC;AACpC,OAAO,KAAK,IAAI,MAAM,MAAM,CAAC;AAC7B,OAAO,KAAK,EAAE,MAAM,IAAI,CAAC;AAQzB,SAAS,gBAAgB;IACvB,OAAO,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,WAAW,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,OAAO,MAAM;IACjB,KAAK,GAA8B,IAAI,GAAG,EAAE,CAAC;IAC7C,MAAM,GAAG,KAAK,CAAC;IACP,SAAS,CAAS;IAClB,UAAU,CAAS;IAE3B,YAAY,IAAuB;QACjC,IAAI,CAAC,SAAS,GAAG,IAAI,EAAE,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACjD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;IAC7D,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,MAAM;YAAE,OAAO;QACxB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACpD,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;YACxD,MAAM,GAAG,GAAmB,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5C,KAAK,MAAM,CAAC,IAAI,GAAG;gBAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAChD,CAAC;QAAC,MAAM,CAAC;YACP,iCAAiC;QACnC,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACpD,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;YAC5C,MAAM,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAC7E,CAAC;QAAC,MAAM,CAAC;YACP,cAAc;QAChB,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,GAAW,EAAE,KAAa;QACjC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,CAAC,GAAW;QAChB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC;IACpC,CAAC;IAED,cAAc;QACZ,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACrC,MAAM,KAAK,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAC/C,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,KAAK,EAAE,CAChC,CAAC;QACF,OAAO,sBAAsB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;IAClD,CAAC;CACF"}
|
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
// Arc-code Agent: Orchestrator
|
|
2
|
+
// The main loop. Input -> reasoning -> action -> observation -> repeat.
|
|
3
|
+
// Coordinates planner, executor, retriever, verifier, and memory.
|
|
4
|
+
import { streamChat } from "../llm/provider.js";
|
|
5
|
+
import { compactIfNeeded } from "../llm/compaction.js";
|
|
6
|
+
import { getAllDefinitions } from "../tools/index.js";
|
|
7
|
+
import { executeToolCalls } from "./executor.js";
|
|
8
|
+
import { planIfComplex } from "./planner.js";
|
|
9
|
+
import { shouldRetrieve, extractCandidateTerms, retrieveContext, } from "./retriever.js";
|
|
10
|
+
const MAX_TOOL_ROUNDS = 25;
|
|
11
|
+
export class Orchestrator {
|
|
12
|
+
state;
|
|
13
|
+
memory;
|
|
14
|
+
onEvent;
|
|
15
|
+
tools;
|
|
16
|
+
maxIterations;
|
|
17
|
+
cancelled = false;
|
|
18
|
+
constructor(opts) {
|
|
19
|
+
this.state = opts.state;
|
|
20
|
+
this.memory = opts.memory;
|
|
21
|
+
this.onEvent = opts.onEvent;
|
|
22
|
+
this.tools = getAllDefinitions();
|
|
23
|
+
this.maxIterations = opts.maxIterations ?? MAX_TOOL_ROUNDS;
|
|
24
|
+
}
|
|
25
|
+
cancel() {
|
|
26
|
+
this.cancelled = true;
|
|
27
|
+
}
|
|
28
|
+
async run(userPrompt) {
|
|
29
|
+
// 1. Retrieval: maybe enrich the prompt with relevant code context.
|
|
30
|
+
let augmented = userPrompt;
|
|
31
|
+
if (shouldRetrieve(userPrompt)) {
|
|
32
|
+
const terms = extractCandidateTerms(userPrompt);
|
|
33
|
+
if (terms.length > 0) {
|
|
34
|
+
try {
|
|
35
|
+
const chunks = await retrieveContext(this.state.cwd, terms);
|
|
36
|
+
if (chunks.length > 0) {
|
|
37
|
+
const block = chunks
|
|
38
|
+
.map((c) => ` - ${c.file}:${c.line}: ${c.text}`)
|
|
39
|
+
.join("\n");
|
|
40
|
+
augmented = `${userPrompt}\n\n[Relevant code in workspace]\n${block}`;
|
|
41
|
+
this.onEvent({
|
|
42
|
+
type: "status",
|
|
43
|
+
status: `retrieved ${chunks.length} code chunk(s) for context`,
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// retrieval is best-effort
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// 2. Optional plan.
|
|
53
|
+
let planText = null;
|
|
54
|
+
if (userPrompt.length > 120) {
|
|
55
|
+
this.onEvent({ type: "status", status: "planning steps" });
|
|
56
|
+
planText = await planIfComplex(userPrompt);
|
|
57
|
+
if (planText) {
|
|
58
|
+
this.onEvent({ type: "status", status: "plan ready" });
|
|
59
|
+
this.onEvent({ type: "text", content: `\n[Plan]\n${planText}\n` });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// 3. Add the user message and start the tool loop.
|
|
63
|
+
this.state.addMessage({ role: "user", content: augmented });
|
|
64
|
+
this.state.iteration = 0;
|
|
65
|
+
let iter = 0;
|
|
66
|
+
while (iter < this.maxIterations) {
|
|
67
|
+
if (this.cancelled)
|
|
68
|
+
break;
|
|
69
|
+
iter++;
|
|
70
|
+
this.state.iteration = iter;
|
|
71
|
+
this.onEvent({
|
|
72
|
+
type: "status",
|
|
73
|
+
status: `iteration ${iter}`,
|
|
74
|
+
iteration: iter,
|
|
75
|
+
contextPercent: this.state.contextPercent,
|
|
76
|
+
});
|
|
77
|
+
// 4. Compact if context is getting large.
|
|
78
|
+
const compaction = await compactIfNeeded(this.state.messages);
|
|
79
|
+
if (compaction) {
|
|
80
|
+
this.state.setMessages(compaction.messages);
|
|
81
|
+
this.onEvent({
|
|
82
|
+
type: "compaction",
|
|
83
|
+
content: `[Compacted ${compaction.droppedCount} earlier turn(s)]`,
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
// 5. Stream a response from the LLM.
|
|
87
|
+
let textBuffer = "";
|
|
88
|
+
let reasoningBuffer = "";
|
|
89
|
+
const toolCalls = [];
|
|
90
|
+
const turnMessages = this.state.messages;
|
|
91
|
+
await streamChat({
|
|
92
|
+
messages: turnMessages,
|
|
93
|
+
tools: this.tools,
|
|
94
|
+
onEvent: (e) => {
|
|
95
|
+
if (e.type === "reasoning" && e.content) {
|
|
96
|
+
reasoningBuffer += e.content;
|
|
97
|
+
this.onEvent({ type: "reasoning", content: e.content });
|
|
98
|
+
}
|
|
99
|
+
else if (e.type === "text" && e.content) {
|
|
100
|
+
textBuffer += e.content;
|
|
101
|
+
this.onEvent({ type: "text", content: e.content });
|
|
102
|
+
}
|
|
103
|
+
else if (e.type === "tool_call" && e.toolCall) {
|
|
104
|
+
toolCalls.push(e.toolCall);
|
|
105
|
+
this.onEvent({ type: "tool_call", toolCall: e.toolCall });
|
|
106
|
+
}
|
|
107
|
+
else if (e.type === "error") {
|
|
108
|
+
this.onEvent({ type: "error", error: e.error });
|
|
109
|
+
}
|
|
110
|
+
else if (e.type === "done") {
|
|
111
|
+
this.onEvent({ type: "done", status: e.status });
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
// 6. Persist the assistant turn.
|
|
116
|
+
const assistantMsg = {
|
|
117
|
+
role: "assistant",
|
|
118
|
+
content: textBuffer || null,
|
|
119
|
+
...(toolCalls.length > 0 ? { tool_calls: toolCalls } : {}),
|
|
120
|
+
...(reasoningBuffer ? { reasoning_content: reasoningBuffer } : {}),
|
|
121
|
+
};
|
|
122
|
+
this.state.addMessage(assistantMsg);
|
|
123
|
+
// 7. If no tool calls, we are done.
|
|
124
|
+
if (toolCalls.length === 0) {
|
|
125
|
+
this.onEvent({ type: "done", status: "complete" });
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
// 8. Execute the tool calls.
|
|
129
|
+
this.onEvent({ type: "status", status: "executing tools" });
|
|
130
|
+
const executed = await executeToolCalls(toolCalls, {
|
|
131
|
+
cwd: this.state.cwd,
|
|
132
|
+
});
|
|
133
|
+
for (const ex of executed) {
|
|
134
|
+
this.state.addMessage(ex.resultMessage);
|
|
135
|
+
this.onEvent({
|
|
136
|
+
type: "tool_result",
|
|
137
|
+
toolResult: {
|
|
138
|
+
name: ex.toolCall.function.name,
|
|
139
|
+
content: ex.resultMessage.content,
|
|
140
|
+
},
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
// 9. Loop back for the next reasoning turn with tool observations.
|
|
144
|
+
}
|
|
145
|
+
if (iter >= this.maxIterations) {
|
|
146
|
+
this.onEvent({
|
|
147
|
+
type: "error",
|
|
148
|
+
error: "Reached maximum tool-call iterations. Stopping.",
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
//# sourceMappingURL=orchestrator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"orchestrator.js","sourceRoot":"","sources":["../../src/agent/orchestrator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
// Arc-code Agent: Planner
|
|
2
|
+
// Light planner that runs before a complex user request. Produces a short
|
|
3
|
+
// step-by-step plan that is shown to the user and prepended to the assistant
|
|
4
|
+
// turn.
|
|
5
|
+
import { chatOnce } from "../llm/provider.js";
|
|
6
|
+
export async function planIfComplex(userPrompt) {
|
|
7
|
+
if (userPrompt.length < 120)
|
|
8
|
+
return null;
|
|
9
|
+
if (!/\b(build|create|implement|add|refactor|fix|design|write|set up)\b/i.test(userPrompt)) {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
try {
|
|
13
|
+
const messages = [
|
|
14
|
+
{
|
|
15
|
+
role: "user",
|
|
16
|
+
content: `Break this request into 3-6 concrete, ordered steps. Output only the steps, one per line, prefixed with "- ". Do not include code.\n\nRequest: ${userPrompt}`,
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
const out = await chatOnce(messages, 1000);
|
|
20
|
+
return out.trim() || null;
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=planner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"planner.js","sourceRoot":"","sources":["../../src/agent/planner.ts"],"names":[],"mappings":"AAAA,0BAA0B;AAC1B,0EAA0E;AAC1E,6EAA6E;AAC7E,QAAQ;AAER,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAG9C,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,UAAkB;IAElB,IAAI,UAAU,CAAC,MAAM,GAAG,GAAG;QAAE,OAAO,IAAI,CAAC;IACzC,IAAI,CAAC,oEAAoE,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3F,OAAO,IAAI,CAAC;IACd,CAAC;IACD,IAAI,CAAC;QACH,MAAM,QAAQ,GAAc;YAC1B;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE,kJAAkJ,UAAU,EAAE;aACxK;SACF,CAAC;QACF,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC3C,OAAO,GAAG,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC;IAC5B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
// Arc-code Agent: Retriever (RAG)
|
|
2
|
+
// Fetches relevant code context from the workspace when a user request seems
|
|
3
|
+
// to need it. Light implementation: substring/regex search via the search tool.
|
|
4
|
+
import { promises as fs } from "fs";
|
|
5
|
+
import * as path from "path";
|
|
6
|
+
const KEYWORDS = [
|
|
7
|
+
"file",
|
|
8
|
+
"function",
|
|
9
|
+
"class",
|
|
10
|
+
"import",
|
|
11
|
+
"from",
|
|
12
|
+
"where",
|
|
13
|
+
"find",
|
|
14
|
+
"show",
|
|
15
|
+
"read",
|
|
16
|
+
"open",
|
|
17
|
+
"code",
|
|
18
|
+
"module",
|
|
19
|
+
"package",
|
|
20
|
+
"config",
|
|
21
|
+
"src",
|
|
22
|
+
"lib",
|
|
23
|
+
"test",
|
|
24
|
+
];
|
|
25
|
+
export function shouldRetrieve(prompt) {
|
|
26
|
+
const lower = prompt.toLowerCase();
|
|
27
|
+
return KEYWORDS.some((k) => lower.includes(k));
|
|
28
|
+
}
|
|
29
|
+
export function extractCandidateTerms(prompt) {
|
|
30
|
+
// Pick identifiers, file names, and quoted strings.
|
|
31
|
+
const terms = [];
|
|
32
|
+
const re1 = /[A-Za-z0-9_./-]+\.[a-z]{1,5}/g;
|
|
33
|
+
const re2 = /"([^"]{3,})"/g;
|
|
34
|
+
const re3 = /`([^`]{3,})`/g;
|
|
35
|
+
for (const m of prompt.matchAll(re1))
|
|
36
|
+
terms.push(m[0]);
|
|
37
|
+
for (const m of prompt.matchAll(re2))
|
|
38
|
+
terms.push(m[1]);
|
|
39
|
+
for (const m of prompt.matchAll(re3))
|
|
40
|
+
terms.push(m[1]);
|
|
41
|
+
// Also pick CamelCase or snake_case identifiers.
|
|
42
|
+
const re4 = /\b[A-Z][a-zA-Z0-9_]{2,}\b|\b[a-z]+_[a-z_]{2,}\b/g;
|
|
43
|
+
for (const m of prompt.matchAll(re4))
|
|
44
|
+
terms.push(m[0]);
|
|
45
|
+
return Array.from(new Set(terms)).slice(0, 8);
|
|
46
|
+
}
|
|
47
|
+
export async function retrieveContext(root, terms) {
|
|
48
|
+
const chunks = [];
|
|
49
|
+
const seen = new Set();
|
|
50
|
+
for (const term of terms) {
|
|
51
|
+
if (chunks.length >= 12)
|
|
52
|
+
break;
|
|
53
|
+
await walk(root, term, chunks, seen, 0);
|
|
54
|
+
}
|
|
55
|
+
return chunks;
|
|
56
|
+
}
|
|
57
|
+
async function walk(dir, term, out, seen, depth) {
|
|
58
|
+
if (depth > 4 || out.length >= 12)
|
|
59
|
+
return;
|
|
60
|
+
let entries;
|
|
61
|
+
try {
|
|
62
|
+
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
for (const e of entries) {
|
|
68
|
+
if (out.length >= 12)
|
|
69
|
+
return;
|
|
70
|
+
if (e.name === "node_modules" ||
|
|
71
|
+
e.name === ".git" ||
|
|
72
|
+
e.name === "dist" ||
|
|
73
|
+
e.name === "build")
|
|
74
|
+
continue;
|
|
75
|
+
const full = path.join(dir, e.name);
|
|
76
|
+
if (e.isDirectory()) {
|
|
77
|
+
await walk(full, term, out, seen, depth + 1);
|
|
78
|
+
}
|
|
79
|
+
else if (e.isFile() && isTexty(e.name)) {
|
|
80
|
+
const baseName = path.basename(term);
|
|
81
|
+
const nameWithoutExt = baseName.split(".")[0];
|
|
82
|
+
if (!e.name.includes(baseName) && !e.name.includes(nameWithoutExt)) {
|
|
83
|
+
// file name didn't match, still check contents but only if not too big
|
|
84
|
+
try {
|
|
85
|
+
const stat = await fs.stat(full);
|
|
86
|
+
if (stat.size > 500_000)
|
|
87
|
+
continue;
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
try {
|
|
94
|
+
const content = await fs.readFile(full, "utf-8");
|
|
95
|
+
const lines = content.split("\n");
|
|
96
|
+
for (let i = 0; i < lines.length; i++) {
|
|
97
|
+
if (out.length >= 12)
|
|
98
|
+
return;
|
|
99
|
+
if (lines[i].includes(term)) {
|
|
100
|
+
const key = `${full}:${i}`;
|
|
101
|
+
if (seen.has(key))
|
|
102
|
+
continue;
|
|
103
|
+
seen.add(key);
|
|
104
|
+
out.push({
|
|
105
|
+
file: full,
|
|
106
|
+
line: i + 1,
|
|
107
|
+
text: lines[i].slice(0, 240),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// unreadable
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
function isTexty(name) {
|
|
119
|
+
const textExts = [
|
|
120
|
+
".ts",
|
|
121
|
+
".tsx",
|
|
122
|
+
".js",
|
|
123
|
+
".jsx",
|
|
124
|
+
".mjs",
|
|
125
|
+
".cjs",
|
|
126
|
+
".json",
|
|
127
|
+
".md",
|
|
128
|
+
".txt",
|
|
129
|
+
".py",
|
|
130
|
+
".go",
|
|
131
|
+
".rs",
|
|
132
|
+
".java",
|
|
133
|
+
".kt",
|
|
134
|
+
".c",
|
|
135
|
+
".h",
|
|
136
|
+
".cpp",
|
|
137
|
+
".hpp",
|
|
138
|
+
".cs",
|
|
139
|
+
".rb",
|
|
140
|
+
".php",
|
|
141
|
+
".html",
|
|
142
|
+
".css",
|
|
143
|
+
".scss",
|
|
144
|
+
".yml",
|
|
145
|
+
".yaml",
|
|
146
|
+
".toml",
|
|
147
|
+
".xml",
|
|
148
|
+
];
|
|
149
|
+
return textExts.some((ext) => name.endsWith(ext));
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=retriever.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retriever.js","sourceRoot":"","sources":["../../src/agent/retriever.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
// Arc-code Agent: Verifier / Judge
|
|
2
|
+
// Validates tool outputs against simple expectations so the orchestrator can
|
|
3
|
+
// retry or surface errors to the user.
|
|
4
|
+
export function verifyToolResult(name, args, result) {
|
|
5
|
+
if (!result) {
|
|
6
|
+
return { ok: false, reason: "empty result" };
|
|
7
|
+
}
|
|
8
|
+
if (result.startsWith("Error") || result.startsWith("Error ")) {
|
|
9
|
+
return { ok: false, reason: result };
|
|
10
|
+
}
|
|
11
|
+
if (name === "execute_command") {
|
|
12
|
+
if (result.includes("[exit code: 0]"))
|
|
13
|
+
return { ok: true };
|
|
14
|
+
return { ok: false, reason: "non-zero exit code" };
|
|
15
|
+
}
|
|
16
|
+
if (name === "read_file") {
|
|
17
|
+
if (result.startsWith("Error reading file")) {
|
|
18
|
+
return { ok: false, reason: result };
|
|
19
|
+
}
|
|
20
|
+
return { ok: true };
|
|
21
|
+
}
|
|
22
|
+
return { ok: true };
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=verifier.js.map
|