itermbot 1.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/.github/workflows/ci.yml +81 -0
- package/.github/workflows/release.yml +83 -0
- package/.releaserc.cjs +26 -0
- package/README.md +91 -0
- package/config/agent.yaml +121 -0
- package/config/app.yaml +26 -0
- package/config/memory.yaml +33 -0
- package/config/models.yaml +36 -0
- package/config/skills.yaml +4 -0
- package/config/tool.yaml +17 -0
- package/config/tsconfig.json +18 -0
- package/dist/agent.d.ts +14 -0
- package/dist/agent.d.ts.map +1 -0
- package/dist/agent.js +16 -0
- package/dist/agent.js.map +1 -0
- package/dist/config.d.ts +6 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +6 -0
- package/dist/config.js.map +1 -0
- package/dist/context.d.ts +12 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +14 -0
- package/dist/context.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +182 -0
- package/dist/index.js.map +1 -0
- package/dist/session-hint.d.ts +4 -0
- package/dist/session-hint.d.ts.map +1 -0
- package/dist/session-hint.js +25 -0
- package/dist/session-hint.js.map +1 -0
- package/dist/startup-colors.d.ts +26 -0
- package/dist/startup-colors.d.ts.map +1 -0
- package/dist/startup-colors.js +242 -0
- package/dist/startup-colors.js.map +1 -0
- package/dist/target-routing.d.ts +15 -0
- package/dist/target-routing.d.ts.map +1 -0
- package/dist/target-routing.js +355 -0
- package/dist/target-routing.js.map +1 -0
- package/macos_disk_usage_agent_plan.md +244 -0
- package/package.json +49 -0
- package/scripts/patch-buildin-cache.sh +25 -0
- package/scripts/test-llm.mjs +27 -0
- package/skills/command-explain-and-guard/SKILL.md +39 -0
- package/skills/command-explain-and-guard/handler.js +86 -0
- package/skills/disk-usage-investigate/SKILL.md +44 -0
- package/skills/disk-usage-investigate/handler.js +12 -0
- package/skills/gpu-ssh-monitor/SKILL.md +45 -0
- package/skills/repo-triage/SKILL.md +40 -0
- package/skills/repo-triage/handler.js +56 -0
- package/skills/test-failure-diagnose/SKILL.md +43 -0
- package/skills/test-failure-diagnose/handler.js +107 -0
- package/src/agent.ts +35 -0
- package/src/config.ts +12 -0
- package/src/context.ts +23 -0
- package/src/index.ts +207 -0
- package/src/session-hint.ts +28 -0
- package/src/startup-colors.ts +317 -0
- package/src/target-routing.ts +419 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ['**']
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ['**']
|
|
8
|
+
repository_dispatch:
|
|
9
|
+
types:
|
|
10
|
+
- easynet-package-updated
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
test:
|
|
18
|
+
name: Test & Build
|
|
19
|
+
runs-on: ubuntu-latest
|
|
20
|
+
timeout-minutes: 25
|
|
21
|
+
steps:
|
|
22
|
+
- name: Checkout
|
|
23
|
+
uses: actions/checkout@v4
|
|
24
|
+
|
|
25
|
+
- name: Setup Node.js
|
|
26
|
+
uses: actions/setup-node@v4
|
|
27
|
+
with:
|
|
28
|
+
node-version: '20'
|
|
29
|
+
cache: 'npm'
|
|
30
|
+
registry-url: 'https://registry.npmjs.org'
|
|
31
|
+
|
|
32
|
+
- name: Force npm registry to npmjs.org
|
|
33
|
+
run: |
|
|
34
|
+
touch .npmrc
|
|
35
|
+
grep -q '^registry=https://registry.npmjs.org' .npmrc || echo "registry=https://registry.npmjs.org/" >> .npmrc
|
|
36
|
+
grep -q '@easynet:registry=' .npmrc || echo "@easynet:registry=https://registry.npmjs.org/" >> .npmrc
|
|
37
|
+
grep -q '@wallee:registry=' .npmrc || echo "@wallee:registry=https://registry.npmjs.org/" >> .npmrc
|
|
38
|
+
|
|
39
|
+
- name: Use @easynet deps from npm (CI has no file:../../)
|
|
40
|
+
run: |
|
|
41
|
+
node -e "
|
|
42
|
+
const fs = require('fs');
|
|
43
|
+
const pkgPath = 'package.json';
|
|
44
|
+
const p = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
45
|
+
const deps = { ...p.dependencies, ...p.devDependencies };
|
|
46
|
+
let changed = false;
|
|
47
|
+
for (const [name, v] of Object.entries(deps)) {
|
|
48
|
+
if (name.startsWith('@easynet/') && typeof v === 'string' && v.startsWith('file:')) {
|
|
49
|
+
if (p.dependencies[name]) { p.dependencies[name] = 'latest'; changed = true; }
|
|
50
|
+
if (p.devDependencies[name]) { p.devDependencies[name] = 'latest'; changed = true; }
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (changed) fs.writeFileSync(pkgPath, JSON.stringify(p, null, 2) + '\n');
|
|
54
|
+
"
|
|
55
|
+
|
|
56
|
+
- name: Remove lockfile to avoid stale local/git refs
|
|
57
|
+
run: rm -f package-lock.json
|
|
58
|
+
|
|
59
|
+
- name: Install dependencies
|
|
60
|
+
env:
|
|
61
|
+
NPM_CONFIG_REGISTRY: "https://registry.npmjs.org/"
|
|
62
|
+
run: npm install --legacy-peer-deps
|
|
63
|
+
|
|
64
|
+
- name: Build
|
|
65
|
+
run: npm run build --if-present
|
|
66
|
+
|
|
67
|
+
- name: Typecheck
|
|
68
|
+
run: npm run typecheck --if-present
|
|
69
|
+
|
|
70
|
+
- name: Test
|
|
71
|
+
run: npm test --if-present
|
|
72
|
+
|
|
73
|
+
- name: Diagnostics (on failure)
|
|
74
|
+
if: failure()
|
|
75
|
+
run: |
|
|
76
|
+
echo "Node: $(node -v) | npm: $(npm -v)"
|
|
77
|
+
echo "--- .npmrc ---"
|
|
78
|
+
cat .npmrc 2>&1 || true
|
|
79
|
+
echo "--- npm config ---"
|
|
80
|
+
npm config list 2>&1 || true
|
|
81
|
+
npm ls --depth=0 2>&1 | head -50
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches:
|
|
6
|
+
- master
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
repository_dispatch:
|
|
9
|
+
types:
|
|
10
|
+
- easynet-package-updated
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
permissions:
|
|
17
|
+
contents: write
|
|
18
|
+
|
|
19
|
+
jobs:
|
|
20
|
+
release:
|
|
21
|
+
name: Release
|
|
22
|
+
runs-on: ubuntu-latest
|
|
23
|
+
timeout-minutes: 30
|
|
24
|
+
steps:
|
|
25
|
+
- name: Checkout
|
|
26
|
+
uses: actions/checkout@v4
|
|
27
|
+
with:
|
|
28
|
+
fetch-depth: 0
|
|
29
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
30
|
+
|
|
31
|
+
- name: Setup Node.js
|
|
32
|
+
uses: actions/setup-node@v4
|
|
33
|
+
with:
|
|
34
|
+
node-version: '20'
|
|
35
|
+
cache: 'npm'
|
|
36
|
+
registry-url: 'https://registry.npmjs.org'
|
|
37
|
+
|
|
38
|
+
- name: Force npm registry to npmjs.org
|
|
39
|
+
run: |
|
|
40
|
+
touch .npmrc
|
|
41
|
+
grep -q '^registry=https://registry.npmjs.org' .npmrc || echo "registry=https://registry.npmjs.org/" >> .npmrc
|
|
42
|
+
grep -q '@easynet:registry=' .npmrc || echo "@easynet:registry=https://registry.npmjs.org/" >> .npmrc
|
|
43
|
+
grep -q '@wallee:registry=' .npmrc || echo "@wallee:registry=https://registry.npmjs.org/" >> .npmrc
|
|
44
|
+
|
|
45
|
+
- name: Use @easynet deps from npm (CI has no file:../../)
|
|
46
|
+
run: |
|
|
47
|
+
node -e "
|
|
48
|
+
const fs = require('fs');
|
|
49
|
+
const pkgPath = 'package.json';
|
|
50
|
+
const p = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));
|
|
51
|
+
const deps = { ...p.dependencies, ...p.devDependencies };
|
|
52
|
+
let changed = false;
|
|
53
|
+
for (const [name, v] of Object.entries(deps)) {
|
|
54
|
+
if (name.startsWith('@easynet/') && typeof v === 'string' && v.startsWith('file:')) {
|
|
55
|
+
if (p.dependencies[name]) { p.dependencies[name] = 'latest'; changed = true; }
|
|
56
|
+
if (p.devDependencies[name]) { p.devDependencies[name] = 'latest'; changed = true; }
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
if (changed) fs.writeFileSync(pkgPath, JSON.stringify(p, null, 2) + '\n');
|
|
60
|
+
"
|
|
61
|
+
|
|
62
|
+
- name: Remove lockfile to avoid stale local/git refs
|
|
63
|
+
run: rm -f package-lock.json
|
|
64
|
+
|
|
65
|
+
- name: Install dependencies
|
|
66
|
+
env:
|
|
67
|
+
NPM_CONFIG_REGISTRY: "https://registry.npmjs.org/"
|
|
68
|
+
run: npm install --legacy-peer-deps
|
|
69
|
+
|
|
70
|
+
- name: Build
|
|
71
|
+
run: npm run build --if-present
|
|
72
|
+
|
|
73
|
+
- name: Typecheck
|
|
74
|
+
run: npm run typecheck --if-present
|
|
75
|
+
|
|
76
|
+
- name: Test
|
|
77
|
+
run: npm test --if-present
|
|
78
|
+
|
|
79
|
+
- name: Release
|
|
80
|
+
env:
|
|
81
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
82
|
+
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
83
|
+
run: npx semantic-release
|
package/.releaserc.cjs
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/** @type {import('semantic-release').GlobalConfig} */
|
|
2
|
+
module.exports = {
|
|
3
|
+
branches: ['master'],
|
|
4
|
+
plugins: [
|
|
5
|
+
[
|
|
6
|
+
'@semantic-release/commit-analyzer',
|
|
7
|
+
{
|
|
8
|
+
releaseRules: [
|
|
9
|
+
{ type: 'feat', release: 'patch' },
|
|
10
|
+
{ type: 'fix', release: 'patch' },
|
|
11
|
+
{ type: 'docs', release: 'patch' },
|
|
12
|
+
{ type: 'chore', release: 'patch' },
|
|
13
|
+
{ type: 'refactor', release: 'patch' },
|
|
14
|
+
{ type: 'perf', release: 'patch' },
|
|
15
|
+
{ type: 'test', release: 'patch' },
|
|
16
|
+
{ type: 'ci', release: 'patch' },
|
|
17
|
+
{ type: 'build', release: 'patch' },
|
|
18
|
+
{ message: '*', release: 'patch' },
|
|
19
|
+
],
|
|
20
|
+
},
|
|
21
|
+
],
|
|
22
|
+
'@semantic-release/release-notes-generator',
|
|
23
|
+
'@semantic-release/npm',
|
|
24
|
+
'@semantic-release/git',
|
|
25
|
+
],
|
|
26
|
+
};
|
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# iTermBot
|
|
2
|
+
|
|
3
|
+
iTermBot is an application built on the **@easynet** agent framework. It runs two agents:
|
|
4
|
+
|
|
5
|
+
1. **ReAct agent** — LangChain `createAgent` (ReAct pattern) with tools and memory.
|
|
6
|
+
2. **Deep agent** — DeepAgents `createDeepAgent` with a persistent store backed by agent-memory.
|
|
7
|
+
|
|
8
|
+
Both agents share:
|
|
9
|
+
|
|
10
|
+
- **@easynet/agent-common** — YAML config (app, paths).
|
|
11
|
+
- **@easynet/agent-model** — LLM and embedding models from `models.yaml`.
|
|
12
|
+
- **@easynet/agent-memory** — Agent memory (recall/inject for ReAct; store adapter for Deep).
|
|
13
|
+
- **@easynet/agent-tool** + **@easynet/agent-tool-buildin** — Tools (FS, HTTP, util, exec, etc.).
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- Node.js >= 18
|
|
18
|
+
- Ollama (or another OpenAI-compatible endpoint) for the LLM. Default config uses `http://localhost:11434/v1` and `qwen3:0.6b`.
|
|
19
|
+
|
|
20
|
+
## Setup
|
|
21
|
+
|
|
22
|
+
The app uses **npm packages** only (no file: links), so it builds from a clean install:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
cd apps/itermbot
|
|
26
|
+
npm install
|
|
27
|
+
npm run build
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Tool support uses agent-tool’s `@easynet/agent-tool` and `@easynet/agent-tool-buildin` from the npm registry.
|
|
31
|
+
|
|
32
|
+
## Config
|
|
33
|
+
|
|
34
|
+
| File | Purpose |
|
|
35
|
+
|------|--------|
|
|
36
|
+
| `config/app.yaml` | App name and paths (loaded via agent-common). |
|
|
37
|
+
| `config/models.yaml` | LLM + embedding instances (agent-model). |
|
|
38
|
+
| `config/memory.yaml` | Memory backend config (agent-memory). |
|
|
39
|
+
| `config/tool.yaml` | Tool list used by all environments. |
|
|
40
|
+
|
|
41
|
+
Paths in `config/app.yaml` are relative to the app root (current working directory when you run the app).
|
|
42
|
+
|
|
43
|
+
### Tool source by environment
|
|
44
|
+
|
|
45
|
+
- `APP_ENV=development` and `APP_ENV=production` both use `config/tool.yaml`
|
|
46
|
+
|
|
47
|
+
Example:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
APP_ENV=development npm run react
|
|
51
|
+
APP_ENV=production npm run react
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Usage
|
|
55
|
+
|
|
56
|
+
- **Interactive (ReAct agent):**
|
|
57
|
+
```bash
|
|
58
|
+
npm start
|
|
59
|
+
# or
|
|
60
|
+
npm run react
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
- **Interactive (Deep agent):**
|
|
64
|
+
```bash
|
|
65
|
+
npm run deep
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
- **One-shot query:**
|
|
69
|
+
```bash
|
|
70
|
+
node dist/index.js react "What time is it?"
|
|
71
|
+
node dist/index.js deep "Remember I prefer short answers."
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Scripts
|
|
75
|
+
|
|
76
|
+
| Script | Description |
|
|
77
|
+
|--------|-------------|
|
|
78
|
+
| `npm run build` | Compile TypeScript to `dist/`. |
|
|
79
|
+
| `npm start` | Run interactive with ReAct agent. |
|
|
80
|
+
| `npm run react` | Same as start (ReAct). |
|
|
81
|
+
| `npm run deep` | Interactive with Deep agent. |
|
|
82
|
+
| `npm run typecheck` | Type-check only. |
|
|
83
|
+
| `npm run test:llm` | Test LLM config (scripts/test-llm.mjs). |
|
|
84
|
+
|
|
85
|
+
## Architecture
|
|
86
|
+
|
|
87
|
+
- **context.ts** — Builds shared `BotContext`: LLM (`createAgentLlm`), memory (`createAgentMemory`), tools (`createAgentTools` with env-selected tool config and `coreTools`).
|
|
88
|
+
- **agents/react-agent.ts** — LangChain `createAgent`; before each run, injects memory via `memory.recall`; optional `remember()` with `memory.memorize`.
|
|
89
|
+
- **agents/deep-agent.ts** — DeepAgents `createDeepAgent` with state backend (no extra memory store adapter wiring).
|
|
90
|
+
|
|
91
|
+
Both agents use the same LLM, memory backend, and tool set; only the orchestration (ReAct vs Deep) differs.
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
shared:
|
|
2
|
+
models:
|
|
3
|
+
path: ./config/models.yaml
|
|
4
|
+
memory:
|
|
5
|
+
path: ./config/memory.yaml
|
|
6
|
+
namespace_mode: fixed
|
|
7
|
+
namespace: user:itermbot
|
|
8
|
+
top_k: 8
|
|
9
|
+
budget_tokens: 1200
|
|
10
|
+
auto_write: true
|
|
11
|
+
auto_write_scope: thread
|
|
12
|
+
auto_write_max_chars: 2400
|
|
13
|
+
auto_write_user: true
|
|
14
|
+
auto_write_assistant: true
|
|
15
|
+
tools:
|
|
16
|
+
path: ./config/tool.yaml
|
|
17
|
+
|
|
18
|
+
profiles:
|
|
19
|
+
react:
|
|
20
|
+
skills:
|
|
21
|
+
path: ./config/skills.yaml
|
|
22
|
+
mode: prompt
|
|
23
|
+
embedding_threshold: 0.85
|
|
24
|
+
keyword_threshold: 0.55
|
|
25
|
+
system_prompt: |
|
|
26
|
+
You are iTermBot in iTerm (chat panel + target panel, same tab).
|
|
27
|
+
|
|
28
|
+
## 1) Hard Rules
|
|
29
|
+
- ALL shell commands must run in target panel via `itermRunCommandInSession`.
|
|
30
|
+
- Never bypass terminal execution with local filesystem/meta shortcuts (e.g. listDir/readFile; reading iTermBot config/skills under project paths).
|
|
31
|
+
- User must SEE command execution in target panel.
|
|
32
|
+
- Do not open new window/tab unless explicitly requested.
|
|
33
|
+
- Do NOT call `itermSplitPane` unless explicitly requested (assume chat + target already exist).
|
|
34
|
+
- If target `sessionId` is provided, always pass it.
|
|
35
|
+
- Treat tool `output` as evidence. If empty, do NOT retry same command with larger `waitMs`; choose a faster alternative.
|
|
36
|
+
- Prefer fast commands (`df -h`, `du -sh ~ 2>/dev/null`, `ls -la`); avoid slow recursion. For disk usage, use `du -sh <specific-dir>` over `du -sh /*`.
|
|
37
|
+
- Use fastest viable path: low-cost first, then expand only for user need/evidence gap.
|
|
38
|
+
- Avoid expensive defaults (full scan/test/build/reinstall) unless necessary.
|
|
39
|
+
- Never use `sudo`.
|
|
40
|
+
- After each command: analyze output and report concise conclusion + next step.
|
|
41
|
+
- Never fabricate values not present in output; never repeat identical bullets.
|
|
42
|
+
- For "current screen"/"当前屏幕"/"当前panel输出": do NOT ask user to paste; capture with no-op `:` and analyze returned `output`.
|
|
43
|
+
- Current-screen defaults: `maxOutputLines` 400-800 (not 200); for "详细分析" start 800-1000; prioritize buffer tail.
|
|
44
|
+
- For full analysis (完整/全部/全量): paginate with `outputOffsetLines + maxOutputLines`; continue until coverage is enough or oldest-needed chunk has `isOutputTruncated=false`; keep chunk notes and merge into one evidence-based conclusion.
|
|
45
|
+
|
|
46
|
+
## 2) Output Format
|
|
47
|
+
- Always valid Markdown with stable structure (headings, bullets, fenced code).
|
|
48
|
+
- Raw JSON only when explicitly requested.
|
|
49
|
+
|
|
50
|
+
## 3) Output Quality
|
|
51
|
+
- Evidence-first:
|
|
52
|
+
1) key terminal output in fenced block (truncate if needed),
|
|
53
|
+
2) short summary (3-8 bullets).
|
|
54
|
+
- File-list requests ("list files"/"show files"/"ls"): use `ls -1A`, return names directly from output.
|
|
55
|
+
- Do not infer stats from `ls -la`.
|
|
56
|
+
- If long output: state truncation and ask whether to drill into a directory.
|
|
57
|
+
- File-list default: one fenced `text` block, no inferred summary/statistics unless requested.
|
|
58
|
+
- Do not use estimate markers ("~", "about", "(?)") unless they appear in output.
|
|
59
|
+
- If output exceeds one pass/context window: chunk (~120-200 lines), summarize each chunk with facts only, then merge.
|
|
60
|
+
- Prefer deterministic slicing (`head`/`tail`/`sed -n start,endp`) over resending huge raw blocks.
|
|
61
|
+
|
|
62
|
+
## 4) ReAct Tool-Call Syntax
|
|
63
|
+
- If next step is tool call, output exactly one line: `toolName({ ... })`.
|
|
64
|
+
- Parentheses must contain one valid JSON object only:
|
|
65
|
+
- double-quoted keys/strings,
|
|
66
|
+
- no comments/trailing commas,
|
|
67
|
+
- no extra text outside JSON.
|
|
68
|
+
- No natural-language wrapper around tool JSON.
|
|
69
|
+
Bad: `The user asked ... {"command":"df -h"}`.
|
|
70
|
+
- Keep chain-of-thought private; expose only tool call + observation.
|
|
71
|
+
|
|
72
|
+
## 5) Skills
|
|
73
|
+
- Use runtime-injected skills directly.
|
|
74
|
+
- Never run skill discovery/read commands in target panel (`cat/find/grep ...SKILL.md`).
|
|
75
|
+
- Before multi-step investigations, check skills via runtime context, not terminal scans.
|
|
76
|
+
|
|
77
|
+
## 6) Progress Updates
|
|
78
|
+
- For multi-step tasks, do not wait until the end.
|
|
79
|
+
- Every 1-3 `itermRunCommandInSession` calls, send 1-3 sentence update with:
|
|
80
|
+
- commands run,
|
|
81
|
+
- key findings,
|
|
82
|
+
- next planned commands.
|
|
83
|
+
|
|
84
|
+
## 7) Memory Rules
|
|
85
|
+
- `thread`: session-scoped facts/logs/outputs/stack traces/intermediate state/noisy large output.
|
|
86
|
+
- `cross_thread`: durable preferences and stable profile facts (style/tool preferences, long-term constraints), reusable cross-session conclusions.
|
|
87
|
+
- Never store secrets (password/token/key).
|
|
88
|
+
- If unsure: `thread` for operations, `cross_thread` only for stable preferences/facts.
|
|
89
|
+
max_steps: 40
|
|
90
|
+
print_steps: false
|
|
91
|
+
fallback_text: Command sent to iTerm panel.
|
|
92
|
+
command_window_label: iTerm window
|
|
93
|
+
|
|
94
|
+
deep:
|
|
95
|
+
system_prompt: |
|
|
96
|
+
You are iTermBot (Deep agent) for multi-step terminal workflows in iTerm (chat panel + target panel, same tab).
|
|
97
|
+
|
|
98
|
+
## Core
|
|
99
|
+
- ALL shell commands must run via `itermRunCommandInSession` in target panel.
|
|
100
|
+
- Never bypass terminal with filesystem shortcuts (listDir/readFile/etc.).
|
|
101
|
+
- User must SEE command execution in target panel.
|
|
102
|
+
|
|
103
|
+
## Behavior
|
|
104
|
+
- Do not open new windows/tabs unless explicitly requested.
|
|
105
|
+
- For any shell task (files, scripts, git, package managers, etc.), always use `itermRunCommandInSession`.
|
|
106
|
+
- If target `sessionId` is provided, always pass it.
|
|
107
|
+
- Treat returned `output` as evidence. If empty, do NOT rerun same command; continue or choose faster alternative.
|
|
108
|
+
- For current screen/panel analysis, do NOT ask user to paste; capture with no-op `:` and analyze returned `output`.
|
|
109
|
+
- Current-screen defaults: `maxOutputLines` 400-800; for detailed analysis start 800-1000; prioritize buffer tail.
|
|
110
|
+
- For complete/all relevant screen analysis, paginate with `outputOffsetLines + maxOutputLines` until enough coverage (or oldest needed chunk no longer truncated), then merge.
|
|
111
|
+
- If output is too long for one pass/context window: chunk (~120-200 lines), summarize per chunk, then merge to one evidence-based conclusion.
|
|
112
|
+
- Prefer deterministic slicing (`head`/`tail`/`sed -n start,endp`) over resending huge output.
|
|
113
|
+
- Prefer fast commands; avoid slow recursive scans of large directories.
|
|
114
|
+
- Prefer fastest viable path: low-cost first, escalate only when needed.
|
|
115
|
+
- Avoid expensive defaults (full repo scan/test/build/reinstall) unless required.
|
|
116
|
+
- Never use `sudo`.
|
|
117
|
+
- Write long-term preferences and key project facts to memory.
|
|
118
|
+
- For complex tasks, think step-by-step and briefly mark current step.
|
|
119
|
+
- Keep replies concise and structured.
|
|
120
|
+
recursion_limit: 8
|
|
121
|
+
memories_path: /memories/
|
package/config/app.yaml
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# iTermBot app-level config
|
|
2
|
+
|
|
3
|
+
app:
|
|
4
|
+
prompt_templates:
|
|
5
|
+
iterm_policy: |
|
|
6
|
+
## iTerm Operating Policy
|
|
7
|
+
- Target panel output is the remote source of truth.
|
|
8
|
+
- Never use local machine commands for system/project data collection.
|
|
9
|
+
- For remote operations/investigation, use `itermRunCommandInSession` in target panel.
|
|
10
|
+
- For current screen/panel analysis, never ask user to paste text; capture via no-op `:`.
|
|
11
|
+
- For full coverage, paginate with `outputOffsetLines + maxOutputLines`, summarize by chunk, then merge.
|
|
12
|
+
- If output is long, use bounded chunk analysis with interim summaries and one final conclusion.
|
|
13
|
+
- Prefer fast/low-cost commands; avoid heavy full scans/builds/tests unless required.
|
|
14
|
+
- Host may auto-update target panel when focus moves to a non-chat panel.
|
|
15
|
+
- Final response must be valid Markdown with stable formatting.
|
|
16
|
+
- Host may auto-recover target routing (reuse non-chat pane or auto-split); if still failing, ask user.
|
|
17
|
+
target_session: |
|
|
18
|
+
## Target Panel Session
|
|
19
|
+
Routed target panel (may change at runtime):
|
|
20
|
+
- sessionId: "{{sessionId}}"
|
|
21
|
+
- windowId: {{windowId}}
|
|
22
|
+
- tabIndex: {{tabIndex}}
|
|
23
|
+
Never use `windowId: 0` and never guess IDs.
|
|
24
|
+
|
|
25
|
+
agent:
|
|
26
|
+
path: ./config/agent.yaml
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# iTermBot agent memory (@easynet/agent-memory)
|
|
2
|
+
memory:
|
|
3
|
+
thread:
|
|
4
|
+
store:
|
|
5
|
+
type: sqlite
|
|
6
|
+
config:
|
|
7
|
+
dbPath: ../data/thread.db
|
|
8
|
+
sessionCompaction:
|
|
9
|
+
enabled: true
|
|
10
|
+
maxTokens: 3000
|
|
11
|
+
keepRecentTurns: 12
|
|
12
|
+
summaryKey: "__session_summary__"
|
|
13
|
+
checkEveryTurns: 3
|
|
14
|
+
cross_thread:
|
|
15
|
+
store:
|
|
16
|
+
type: sqlite
|
|
17
|
+
config:
|
|
18
|
+
dbPath: ../data/cross-thread.db
|
|
19
|
+
knowledge:
|
|
20
|
+
store:
|
|
21
|
+
type: sqlite
|
|
22
|
+
config:
|
|
23
|
+
dbPath: ../data/knowledge.db
|
|
24
|
+
|
|
25
|
+
observability:
|
|
26
|
+
trace: false
|
|
27
|
+
|
|
28
|
+
privacy:
|
|
29
|
+
forbiddenMetadataKeys:
|
|
30
|
+
- password
|
|
31
|
+
- api_key
|
|
32
|
+
- secret
|
|
33
|
+
- token
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Unified model config for itermbot
|
|
2
|
+
# Sections: llm (chat models), embed (embedding models), runtime
|
|
3
|
+
# Env overrides:
|
|
4
|
+
# - LLM_BASE_URL_STRONG: strong model HTTP endpoint
|
|
5
|
+
# - LLM_MODEL_STRONG: strong model name
|
|
6
|
+
# - LLM_API_KEY_STRONG: strong model API key
|
|
7
|
+
# - LLM_BASE_URL: small default endpoint
|
|
8
|
+
# - LLM_MODEL: small default model name
|
|
9
|
+
llm:
|
|
10
|
+
default: small
|
|
11
|
+
small:
|
|
12
|
+
provider: openai
|
|
13
|
+
base_url: http://localhost:11434/v1
|
|
14
|
+
model: qwen3:0.6b
|
|
15
|
+
easynet:
|
|
16
|
+
provider: openai
|
|
17
|
+
base_url: https://ollama-rtx-4070.easynet.world/v1
|
|
18
|
+
model: gpt-oss-80k:latest
|
|
19
|
+
strong:
|
|
20
|
+
provider: openai
|
|
21
|
+
base_url: https://api.groq.com/openai/v1
|
|
22
|
+
model: openai/gpt-oss-120b
|
|
23
|
+
# agent-model expects camelCase apiKey; use env var, do not commit real keys:
|
|
24
|
+
# export GROQ_API_KEY="your Groq API key"
|
|
25
|
+
apiKey: ${GROQ_API_KEY}
|
|
26
|
+
|
|
27
|
+
embed:
|
|
28
|
+
default: gemma
|
|
29
|
+
gemma:
|
|
30
|
+
provider: openai
|
|
31
|
+
base_url: https://ollama-nvidia-8g-2.easynet.world/v1
|
|
32
|
+
model: embeddinggemma:latest
|
|
33
|
+
apiKey: ollama
|
|
34
|
+
|
|
35
|
+
runtime:
|
|
36
|
+
check_connectivity: false
|
package/config/tool.yaml
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# iTermBot tools (shared across development and production)
|
|
2
|
+
# Only load the iterm tools needed — no fs/http/util tools that would
|
|
3
|
+
# distract the LLM from using itermRunCommandInSession.
|
|
4
|
+
tools:
|
|
5
|
+
list:
|
|
6
|
+
- "npm:@easynet/agent-tool-buildin@latest#itermRunCommandInSession"
|
|
7
|
+
- "npm:@easynet/agent-tool-buildin@latest#itermSendText"
|
|
8
|
+
- "npm:@easynet/agent-tool-buildin@latest#itermListCurrentWindowSessions"
|
|
9
|
+
- "npm:@easynet/agent-tool-buildin@latest#itermListWindows"
|
|
10
|
+
- "npm:@easynet/agent-tool-buildin@latest#itermSetSessionColors"
|
|
11
|
+
- "npm:@easynet/agent-tool-buildin@latest#itermSplitPane"
|
|
12
|
+
- "npm:@easynet/agent-tool-buildin@latest#itermGetSessionInfo"
|
|
13
|
+
sandboxedPath: .
|
|
14
|
+
allowedHosts:
|
|
15
|
+
- api.github.com
|
|
16
|
+
- duckduckgo.com
|
|
17
|
+
- www.duckduckgo.com
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2022",
|
|
4
|
+
"module": "NodeNext",
|
|
5
|
+
"moduleResolution": "NodeNext",
|
|
6
|
+
"outDir": "../dist",
|
|
7
|
+
"rootDir": "../src",
|
|
8
|
+
"strict": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"declaration": true,
|
|
12
|
+
"declarationMap": true,
|
|
13
|
+
"sourceMap": true,
|
|
14
|
+
"resolveJsonModule": true
|
|
15
|
+
},
|
|
16
|
+
"include": ["../src/**/*"],
|
|
17
|
+
"exclude": ["../node_modules", "../dist"]
|
|
18
|
+
}
|
package/dist/agent.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iTermBot agent factories — thin wrappers over agent-runtime.
|
|
3
|
+
*/
|
|
4
|
+
import { type ReactAgentRuntime, type DeepAgentRuntime, type ReactAgentOptions, type DeepAgentOptions, type CreateContextOptions } from "@easynet/agent-runtime";
|
|
5
|
+
export type { ReactAgentRuntime, DeepAgentRuntime, CreateContextOptions };
|
|
6
|
+
export interface CreateAppAgentOptions extends CreateContextOptions {
|
|
7
|
+
react?: ReactAgentOptions;
|
|
8
|
+
}
|
|
9
|
+
export interface CreateAppDeepAgentOptions extends CreateContextOptions {
|
|
10
|
+
deep?: DeepAgentOptions;
|
|
11
|
+
}
|
|
12
|
+
export declare function createAgent(options?: CreateAppAgentOptions): Promise<ReactAgentRuntime>;
|
|
13
|
+
export declare function createDeepAgentFromContext(options?: CreateAppDeepAgentOptions): Promise<DeepAgentRuntime>;
|
|
14
|
+
//# sourceMappingURL=agent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAGL,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAGhC,YAAY,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,oBAAoB,EAAE,CAAC;AAE1E,MAAM,WAAW,qBAAsB,SAAQ,oBAAoB;IACjE,KAAK,CAAC,EAAE,iBAAiB,CAAC;CAC3B;AAED,MAAM,WAAW,yBAA0B,SAAQ,oBAAoB;IACrE,IAAI,CAAC,EAAE,gBAAgB,CAAC;CACzB;AAED,wBAAsB,WAAW,CAAC,OAAO,GAAE,qBAA0B,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAIjG;AAED,wBAAsB,0BAA0B,CAAC,OAAO,GAAE,yBAA8B,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAInH"}
|
package/dist/agent.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iTermBot agent factories — thin wrappers over agent-runtime.
|
|
3
|
+
*/
|
|
4
|
+
import { createReactAgent, createDeepAgent, } from "@easynet/agent-runtime";
|
|
5
|
+
import { createAgent as createAgentContext } from "./context.js";
|
|
6
|
+
export async function createAgent(options = {}) {
|
|
7
|
+
const { react, ...contextOptions } = options;
|
|
8
|
+
const ctx = await createAgentContext({ agentName: "react", ...contextOptions });
|
|
9
|
+
return createReactAgent(ctx, { agentName: "react", ...react });
|
|
10
|
+
}
|
|
11
|
+
export async function createDeepAgentFromContext(options = {}) {
|
|
12
|
+
const { deep, ...contextOptions } = options;
|
|
13
|
+
const ctx = await createAgentContext({ agentName: "deep", ...contextOptions });
|
|
14
|
+
return createDeepAgent(ctx, { agentName: "deep", ...deep });
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=agent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EACL,gBAAgB,EAChB,eAAe,GAMhB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,WAAW,IAAI,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAYjE,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,UAAiC,EAAE;IACnE,MAAM,EAAE,KAAK,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,CAAC;IAC7C,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC,CAAC;IAChF,OAAO,gBAAgB,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,KAAK,EAAE,CAAC,CAAC;AACjE,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,UAAqC,EAAE;IACtF,MAAM,EAAE,IAAI,EAAE,GAAG,cAAc,EAAE,GAAG,OAAO,CAAC;IAC5C,MAAM,GAAG,GAAG,MAAM,kBAAkB,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,cAAc,EAAE,CAAC,CAAC;IAC/E,OAAO,eAAe,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,CAAC,CAAC;AAC9D,CAAC"}
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iTermBot config — re-exports from @easynet/agent-runtime.
|
|
3
|
+
* Default tool paths use a shared file (tool.yaml) for all environments.
|
|
4
|
+
*/
|
|
5
|
+
export { loadAppConfig, getModelsConfigPath, getMemoryConfigPath, getToolConfigPath, type AppConfig, type AgentProfileConfig, } from "@easynet/agent-runtime";
|
|
6
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,EACjB,KAAK,SAAS,EACd,KAAK,kBAAkB,GACxB,MAAM,wBAAwB,CAAC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* iTermBot config — re-exports from @easynet/agent-runtime.
|
|
3
|
+
* Default tool paths use a shared file (tool.yaml) for all environments.
|
|
4
|
+
*/
|
|
5
|
+
export { loadAppConfig, getModelsConfigPath, getMemoryConfigPath, getToolConfigPath, } from "@easynet/agent-runtime";
|
|
6
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,aAAa,EACb,mBAAmB,EACnB,mBAAmB,EACnB,iBAAiB,GAGlB,MAAM,wBAAwB,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared runtime context: LLM, memory, tools.
|
|
3
|
+
* Built once and passed to both ReAct and Deep agents.
|
|
4
|
+
*/
|
|
5
|
+
import { type AppContextBuilders, type BotContext, type BotTool, type CreateContextOptions } from "@easynet/agent-runtime";
|
|
6
|
+
export type { BotContext, BotTool, CreateContextOptions };
|
|
7
|
+
export declare const createAgentLlm: AppContextBuilders["createAgentLlm"];
|
|
8
|
+
export declare const createAgentMemory: AppContextBuilders["createAgentMemory"];
|
|
9
|
+
export declare const createAgentTools: AppContextBuilders["createAgentTools"];
|
|
10
|
+
export declare const createAgent: AppContextBuilders["createAgent"];
|
|
11
|
+
export declare const createBotContext: AppContextBuilders["createBotContext"];
|
|
12
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAEL,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,OAAO,EACZ,KAAK,oBAAoB,EAC1B,MAAM,wBAAwB,CAAC;AAEhC,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,oBAAoB,EAAE,CAAC;AAM1D,eAAO,MAAM,cAAc,EAAE,kBAAkB,CAAC,gBAAgB,CAA2B,CAAC;AAC5F,eAAO,MAAM,iBAAiB,EAAE,kBAAkB,CAAC,mBAAmB,CAA8B,CAAC;AACrG,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,CAAC,kBAAkB,CAA6B,CAAC;AAClG,eAAO,MAAM,WAAW,EAAE,kBAAkB,CAAC,aAAa,CAAwB,CAAC;AACnF,eAAO,MAAM,gBAAgB,EAAE,kBAAkB,CAAC,kBAAkB,CAA6B,CAAC"}
|
package/dist/context.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared runtime context: LLM, memory, tools.
|
|
3
|
+
* Built once and passed to both ReAct and Deep agents.
|
|
4
|
+
*/
|
|
5
|
+
import { createAppContext, } from "@easynet/agent-runtime";
|
|
6
|
+
const builders = createAppContext({
|
|
7
|
+
toolPath: "config/tool.yaml",
|
|
8
|
+
});
|
|
9
|
+
export const createAgentLlm = builders.createAgentLlm;
|
|
10
|
+
export const createAgentMemory = builders.createAgentMemory;
|
|
11
|
+
export const createAgentTools = builders.createAgentTools;
|
|
12
|
+
export const createAgent = builders.createAgent;
|
|
13
|
+
export const createBotContext = builders.createBotContext;
|
|
14
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.js","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EACL,gBAAgB,GAKjB,MAAM,wBAAwB,CAAC;AAIhC,MAAM,QAAQ,GAAuB,gBAAgB,CAAC;IACpD,QAAQ,EAAE,kBAAkB;CAC7B,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,cAAc,GAAyC,QAAQ,CAAC,cAAc,CAAC;AAC5F,MAAM,CAAC,MAAM,iBAAiB,GAA4C,QAAQ,CAAC,iBAAiB,CAAC;AACrG,MAAM,CAAC,MAAM,gBAAgB,GAA2C,QAAQ,CAAC,gBAAgB,CAAC;AAClG,MAAM,CAAC,MAAM,WAAW,GAAsC,QAAQ,CAAC,WAAW,CAAC;AACnF,MAAM,CAAC,MAAM,gBAAgB,GAA2C,QAAQ,CAAC,gBAAgB,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|