tomo-ai 0.5.4 → 0.5.5
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/CHANGELOG.md +22 -0
- package/README.md +1 -1
- package/defaults/skills/browse/SKILL.md +22 -141
- package/defaults/skills/lcm/DAILY.md +1 -1
- package/defaults/skills/system/CONFIG.md +4 -2
- package/defaults/skills/system/SKILL.md +12 -8
- package/dist/agent/sdk-options.d.ts +3 -3
- package/dist/agent/sdk-options.d.ts.map +1 -1
- package/dist/agent/sdk-options.js +7 -7
- package/dist/agent/sdk-options.js.map +1 -1
- package/dist/agent.d.ts.map +1 -1
- package/dist/agent.js +16 -9
- package/dist/agent.js.map +1 -1
- package/dist/channels/imageStore.d.ts +8 -0
- package/dist/channels/imageStore.d.ts.map +1 -1
- package/dist/channels/imageStore.js +15 -0
- package/dist/channels/imageStore.js.map +1 -1
- package/dist/channels/imessage.d.ts +2 -2
- package/dist/channels/imessage.d.ts.map +1 -1
- package/dist/channels/imessage.js +76 -24
- package/dist/channels/imessage.js.map +1 -1
- package/dist/channels/telegram.d.ts.map +1 -1
- package/dist/channels/telegram.js +10 -5
- package/dist/channels/telegram.js.map +1 -1
- package/dist/channels/types.d.ts +4 -1
- package/dist/channels/types.d.ts.map +1 -1
- package/dist/cli/start.js +15 -0
- package/dist/cli/start.js.map +1 -1
- package/dist/config.d.ts +6 -2
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -1
- package/dist/config.js.map +1 -1
- package/dist/lcm/blocks.d.ts +4 -3
- package/dist/lcm/blocks.d.ts.map +1 -1
- package/dist/lcm/blocks.js +15 -9
- package/dist/lcm/blocks.js.map +1 -1
- package/dist/lcm/compact.d.ts +56 -0
- package/dist/lcm/compact.d.ts.map +1 -1
- package/dist/lcm/compact.js +203 -9
- package/dist/lcm/compact.js.map +1 -1
- package/dist/lcm/runner.d.ts.map +1 -1
- package/dist/lcm/runner.js +11 -4
- package/dist/lcm/runner.js.map +1 -1
- package/package.json +1 -1
- package/defaults/skills/cron/SKILL.md +0 -78
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.5.5 (2026-05-01)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
|
|
7
|
+
- **Inbound image marker is now always emitted, with the saved disk path when local storage is on.** Previously, a `[Sent an image]` fallback only appeared when the user sent an image with no caption — captions replaced the marker outright, and the model couldn't see the on-disk file path even when `saveInboundImages` was on. Now both Telegram and iMessage prepend `[Sent an image]` (or `[Sent N images]` for iMessage's multi-attachment messages) to the user's caption, and append `saved to: /abs/path[, /abs/path…]` when storage is enabled. The agent can now reliably know an image was attached and `Read` it from disk for tool work that goes beyond what the inline content blocks support. New `formatImageMarker(intendedCount, savedPaths)` helper in `channels/imageStore.ts`; both channels thread `savedPath` through `ImageAttachment`. Marker reflects intended-image count, so a download failure for one attachment doesn't hide the fact that an image was sent.
|
|
8
|
+
|
|
9
|
+
### UX
|
|
10
|
+
|
|
11
|
+
- **Group sessions default to hierarchical LCM compaction.** `config.lcm.groupCompactStyle` now defaults to `"lcm"` instead of `"sdk"`. Group sessions get the same daily/weekly/monthly/yearly rollup nudges, %-based compact prompts, and `tomo-lcm-stats` MCP tool that DMs already had. Set to `"sdk"` to opt back into SDK auto-compact for groups. Existing installs with the field unset flip on next `tomo start`. Rollup nudges for group sessions splice in a "Group scope" line so summaries stay focused on that group's conversation rather than mixing in personal/DM context.
|
|
12
|
+
- **`tomo-cron` skill removed; the `schedule_*` MCP tools are now the everyday interface.** The standalone `tomo-cron` skill was redundant once `schedule_create` / `schedule_list` / `schedule_remove` landed on the `tomo-internal` MCP server in 0.5.3. The `tomo-system` skill now briefly mentions the three MCP tools and notes that the `tomo cron …` CLI remains for human debugging (auditing the job store, fixing a stuck job after a restart). Built-in skills list trimmed accordingly.
|
|
13
|
+
- **`tomo-browse` skill switched from `playwright-cli` to `agent-browser`.** New skill content is a thin discovery stub pointing at `agent-browser skills get core`, so workflow guidance always tracks the installed CLI version instead of going stale in this repo. Frontmatter description broadens trigger coverage to web automation, exploratory testing, Electron app automation (VS Code, Slack, Discord, Figma), Slack workspace tasks, Vercel Sandbox, and AWS Bedrock AgentCore.
|
|
14
|
+
|
|
15
|
+
### Bug fixes
|
|
16
|
+
|
|
17
|
+
- **`lcm compact`: fix write race that could clobber events the SDK appended while `compactSession` was running.** Symptom: when an agent invokes a long-running `tomo lcm daily/weekly/...` via Bash tool, the SDK's `thinking` + `tool_use` events for that very turn could land on disk between compactSession's initial read and its truncate-rewrite, then get wiped by the rewrite. The subsequent `tool_result` then had a `parentUuid` pointing at a vanished tool_use, breaking the chain.
|
|
18
|
+
- Fix: capture the file size at read time, re-read the tail at write time, splice any late-arriving events into the new content, and write atomically via `<path>.compacting.tmp` + `rename`.
|
|
19
|
+
- **iMessage typing indicator: stop the flicker.** BlueBubbles' typing decays server-side faster than Telegram's, so the previous 6-second refresh cadence raced the decay and left the indicator visibly turning on/off between ticks during long SDK turns. Three changes: (1) refresh interval dropped from 6 s to **3 s**; (2) added a `tickInFlight` guard so a slow BlueBubbles HTTP server doesn't queue overlapping POSTs; (3) added Tomo-Telegram-style consecutive-error suspension — after 10 consecutive failed POSTs (e.g. Private API helper missing), typing self-suspends with a single `log.warn` and explicitly DELETEs the indicator instead of hammering the endpoint forever. Cross-checked the design against the openclaw bluebubbles extension's typing controller (`openclaw/src/channels/typing.ts`), which uses the same 3 s default and `tickInFlight` pattern.
|
|
20
|
+
|
|
21
|
+
### Internal
|
|
22
|
+
|
|
23
|
+
- **Built-in skill prune on startup.** `cli/start.ts` now removes `~/.tomo/workspace/.claude/skills/tomo-*` directories that no longer have a counterpart in bundled `defaults/skills/`. Custom skills (anything not prefixed `tomo-`) are never touched. Without this, retired built-ins like `tomo-cron` would persist forever on existing installs.
|
|
24
|
+
|
|
3
25
|
## 0.5.4 (2026-04-29)
|
|
4
26
|
|
|
5
27
|
### Features
|
package/README.md
CHANGED
|
@@ -1,159 +1,40 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: tomo-browse
|
|
3
|
-
description:
|
|
3
|
+
description: Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
|
-
#
|
|
6
|
+
# agent-browser
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Fast browser automation CLI for AI agents. Chrome/Chromium via CDP with
|
|
9
|
+
accessibility-tree snapshots and compact `@eN` element refs.
|
|
9
10
|
|
|
10
|
-
|
|
11
|
+
Install: `npm i -g agent-browser && agent-browser install`
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
which playwright-cli || npm install -g @playwright/cli@latest
|
|
14
|
-
```
|
|
13
|
+
## Start here
|
|
15
14
|
|
|
16
|
-
|
|
15
|
+
This file is a discovery stub, not the usage guide. Before running any
|
|
16
|
+
`agent-browser` command, load the actual workflow content from the CLI:
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
playwright-cli snapshot
|
|
22
|
-
playwright-cli click e15
|
|
23
|
-
playwright-cli type "search query"
|
|
24
|
-
playwright-cli screenshot
|
|
25
|
-
playwright-cli -s=tomo close
|
|
19
|
+
agent-browser skills get core # start here — workflows, common patterns, troubleshooting
|
|
20
|
+
agent-browser skills get core --full # include full command reference and templates
|
|
26
21
|
```
|
|
27
22
|
|
|
28
|
-
|
|
23
|
+
The CLI serves skill content that always matches the installed version,
|
|
24
|
+
so instructions never go stale. The content in this stub cannot change
|
|
25
|
+
between releases, which is why it just points at `skills get core`.
|
|
29
26
|
|
|
30
|
-
|
|
27
|
+
## Specialized skills
|
|
31
28
|
|
|
32
|
-
|
|
33
|
-
```bash
|
|
34
|
-
playwright-cli -s=tomo goto https://example.com
|
|
35
|
-
playwright-cli -s=tomo snapshot
|
|
36
|
-
playwright-cli -s=tomo click e15
|
|
37
|
-
playwright-cli -s=tomo close
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## Commands
|
|
41
|
-
|
|
42
|
-
### Core
|
|
29
|
+
Load a specialized skill when the task falls outside browser web pages:
|
|
43
30
|
|
|
44
31
|
```bash
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
playwright-cli dblclick e7
|
|
51
|
-
playwright-cli fill e5 "user@example.com" --submit
|
|
52
|
-
playwright-cli drag e2 e8
|
|
53
|
-
playwright-cli hover e4
|
|
54
|
-
playwright-cli select e9 "option-value"
|
|
55
|
-
playwright-cli upload ./document.pdf
|
|
56
|
-
playwright-cli check e12
|
|
57
|
-
playwright-cli uncheck e12
|
|
58
|
-
playwright-cli snapshot
|
|
59
|
-
playwright-cli eval "document.title"
|
|
60
|
-
playwright-cli dialog-accept
|
|
61
|
-
playwright-cli dialog-dismiss
|
|
62
|
-
playwright-cli -s=tomo close
|
|
32
|
+
agent-browser skills get electron # Electron desktop apps (VS Code, Slack, Discord, Figma, ...)
|
|
33
|
+
agent-browser skills get slack # Slack workspace automation
|
|
34
|
+
agent-browser skills get dogfood # Exploratory testing / QA / bug hunts
|
|
35
|
+
agent-browser skills get vercel-sandbox # agent-browser inside Vercel Sandbox microVMs
|
|
36
|
+
agent-browser skills get agentcore # AWS Bedrock AgentCore cloud browsers
|
|
63
37
|
```
|
|
64
38
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
```bash
|
|
68
|
-
playwright-cli go-back
|
|
69
|
-
playwright-cli go-forward
|
|
70
|
-
playwright-cli reload
|
|
71
|
-
```
|
|
72
|
-
|
|
73
|
-
### Keyboard
|
|
74
|
-
|
|
75
|
-
```bash
|
|
76
|
-
playwright-cli press Enter
|
|
77
|
-
playwright-cli press ArrowDown
|
|
78
|
-
playwright-cli keydown Shift
|
|
79
|
-
playwright-cli keyup Shift
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
### Save as
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
|
-
playwright-cli screenshot
|
|
86
|
-
playwright-cli screenshot e5
|
|
87
|
-
playwright-cli screenshot --filename=page.png
|
|
88
|
-
playwright-cli pdf --filename=page.pdf
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
### Tabs
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
playwright-cli tab-list
|
|
95
|
-
playwright-cli tab-new https://example.com/page
|
|
96
|
-
playwright-cli tab-close
|
|
97
|
-
playwright-cli tab-select 0
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
### Storage
|
|
101
|
-
|
|
102
|
-
```bash
|
|
103
|
-
playwright-cli cookie-list
|
|
104
|
-
playwright-cli cookie-get session_id
|
|
105
|
-
playwright-cli cookie-set session_id abc123
|
|
106
|
-
playwright-cli localstorage-get theme
|
|
107
|
-
playwright-cli localstorage-set theme dark
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
## Raw output
|
|
111
|
-
|
|
112
|
-
Use `--raw` to get clean output for piping:
|
|
113
|
-
|
|
114
|
-
```bash
|
|
115
|
-
playwright-cli --raw eval "document.title"
|
|
116
|
-
playwright-cli --raw snapshot > page.yml
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
## Snapshots
|
|
120
|
-
|
|
121
|
-
After each command, playwright-cli provides a snapshot with element refs (e.g., `e15`, `e3`). Use these refs to interact:
|
|
122
|
-
|
|
123
|
-
```bash
|
|
124
|
-
playwright-cli snapshot
|
|
125
|
-
playwright-cli click e15
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
You can also use CSS selectors or Playwright locators:
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
playwright-cli click "#main > button.submit"
|
|
132
|
-
playwright-cli click "getByRole('button', { name: 'Submit' })"
|
|
133
|
-
```
|
|
134
|
-
|
|
135
|
-
## Targeting elements
|
|
136
|
-
|
|
137
|
-
Prefer refs from snapshots. Fall back to CSS selectors or locators when refs are ambiguous.
|
|
138
|
-
|
|
139
|
-
## Example: Form submission
|
|
140
|
-
|
|
141
|
-
```bash
|
|
142
|
-
playwright-cli open -s=tomo --browser=chrome --persistent --headed https://example.com/form
|
|
143
|
-
playwright-cli snapshot
|
|
144
|
-
playwright-cli fill e1 "user@example.com"
|
|
145
|
-
playwright-cli fill e2 "password123"
|
|
146
|
-
playwright-cli click e3
|
|
147
|
-
playwright-cli snapshot
|
|
148
|
-
playwright-cli -s=tomo close
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
## Example: Multi-tab workflow
|
|
152
|
-
|
|
153
|
-
```bash
|
|
154
|
-
playwright-cli open -s=tomo --browser=chrome --persistent --headed https://example.com
|
|
155
|
-
playwright-cli tab-new https://example.com/other
|
|
156
|
-
playwright-cli tab-select 0
|
|
157
|
-
playwright-cli snapshot
|
|
158
|
-
playwright-cli -s=tomo close
|
|
159
|
-
```
|
|
39
|
+
Run `agent-browser skills list` to see everything available on the
|
|
40
|
+
installed version.
|
|
@@ -15,7 +15,7 @@ tomo lcm daily --session-id SESSION_ID --summary "<today's summary>"
|
|
|
15
15
|
## When to run
|
|
16
16
|
|
|
17
17
|
- **End of day** (before bed or before a long idle). Cleanest shape.
|
|
18
|
-
- **Mid-day** when the harness nudges you that raw tail
|
|
18
|
+
- **Mid-day** when the harness nudges you that the raw tail has grown past the fresh-tail floor (default 32 events; tune via `lcm.dailyFreshTail` in config.json).
|
|
19
19
|
- **Before a big task** when you want clean context for an involved piece of work.
|
|
20
20
|
- **After long tool-heavy work** — reduce clutter before the conversation continues.
|
|
21
21
|
|
|
@@ -40,7 +40,8 @@ Prefer editing via `tomo config` (interactive TUI). This reference is for readin
|
|
|
40
40
|
"lcm": {
|
|
41
41
|
"nudgeAtPct": 70,
|
|
42
42
|
"nudgeResetPct": 60,
|
|
43
|
-
"groupCompactStyle": "sdk"
|
|
43
|
+
"groupCompactStyle": "sdk",
|
|
44
|
+
"dailyFreshTail": 32
|
|
44
45
|
}
|
|
45
46
|
}
|
|
46
47
|
```
|
|
@@ -67,7 +68,8 @@ Prefer editing via `tomo config` (interactive TUI). This reference is for readin
|
|
|
67
68
|
| `maxTurns` | number | Max agent turns per single user message (one turn ≈ one tool-use round). Default `50`. Raise if you see "max turns exceeded" on long tool chains. |
|
|
68
69
|
| `lcm.nudgeAtPct` | number | Context-usage % at which the harness nudges the agent to run `tomo lcm daily`. Default `70`. Lower = compact earlier and more often. |
|
|
69
70
|
| `lcm.nudgeResetPct` | number | Hysteresis reset threshold — the "already nudged" flag clears once usage drops below this %. Default `60`. Must be less than `nudgeAtPct`; invalid values fall back to defaults. |
|
|
70
|
-
| `lcm.groupCompactStyle` | string | `"sdk"` (default) or `"lcm"`. `"sdk"` lets the SDK auto-compact group sessions; `"lcm"` opts groups into the same hierarchical LCM flow as DMs (disables SDK auto-compact and fires
|
|
71
|
+
| `lcm.groupCompactStyle` | string | `"sdk"` (default) or `"lcm"`. `"sdk"` lets the SDK auto-compact group sessions; `"lcm"` opts groups into the same hierarchical LCM flow as DMs (disables SDK auto-compact and fires all three harness nudges: 70% daily, 80% safety net, and the periodic rollup runner). DMs always use LCM regardless. |
|
|
72
|
+
| `lcm.dailyFreshTail` | number | Number of most-recent raw user/assistant events kept outside today's daily rollup so mid-day compacts don't wipe warm short-term texture. Default `32`. Counts SDK events (one tool round = multiple events), not user-typed messages. Set to `0` to compact every event into today's block. Past days are always compacted in full regardless of this value. |
|
|
71
73
|
|
|
72
74
|
## Requirements and overrides
|
|
73
75
|
|
|
@@ -29,15 +29,19 @@ Session stats show:
|
|
|
29
29
|
|
|
30
30
|
**Note:** Context stats come from the SDK API and reflect the state at the end of the *previous* query. After compacting or other changes, you need to wait for a new query to complete before the numbers update.
|
|
31
31
|
|
|
32
|
-
When context crosses the nudge threshold (default 70%, set via `lcm.nudgeAtPct` in config.json), the harness sends a system message asking you to run `tomo lcm daily` — see the `tomo-lcm` skill. A second nudge at 80% asks you to use the `lcm compact` skill before the next user message. Group sessions default to SDK auto-compact instead (override with `lcm.groupCompactStyle: "lcm"`).
|
|
32
|
+
When context crosses the nudge threshold (default 70%, set via `lcm.nudgeAtPct` in config.json), the harness sends a system message asking you to run `tomo lcm daily` — see the `tomo-lcm` skill. A second nudge at 80% asks you to use the `lcm compact` skill before the next user message. A periodic rollup runner also nudges you when daily/weekly/monthly/yearly blocks are due. Group sessions default to SDK auto-compact instead (override with `lcm.groupCompactStyle: "lcm"` to enroll groups in all three nudges).
|
|
33
33
|
|
|
34
34
|
## Cron Jobs
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
Schedule reminders and recurring tasks via the `tomo-internal` MCP tools:
|
|
37
|
+
|
|
38
|
+
- `schedule_create` — create a one-shot or recurring job (`schedule` accepts `in 20m`, `every 6h`, or a 5-field cron expression; `sessionKey` controls where the fired message lands)
|
|
39
|
+
- `schedule_list` — list every job with `id`, `nextRunAt`, `lastStatus`, etc.
|
|
40
|
+
- `schedule_remove` — delete by `id`
|
|
41
|
+
|
|
42
|
+
These are the everyday interface — load them via tool search ("schedule reminder cron") when the user asks to schedule something.
|
|
43
|
+
|
|
44
|
+
The `tomo cron list / add / remove` CLI is still here for human debugging (auditing the job store, fixing a stuck job after a restart). Prefer the MCP tools in normal conversation.
|
|
41
45
|
|
|
42
46
|
## File Paths
|
|
43
47
|
|
|
@@ -104,7 +108,7 @@ Pass identity name (`"alice"`) or session key (`"telegram:-1001234567"`) as `tar
|
|
|
104
108
|
### Built-in skills (`tomo-*`)
|
|
105
109
|
Skills prefixed with `tomo-` are bundled with Tomo and automatically updated on every `tomo start`. Do not edit these — your changes will be overwritten on next restart.
|
|
106
110
|
|
|
107
|
-
Current built-in skills: `tomo-system`, `tomo-lcm`, `tomo-browse
|
|
111
|
+
Current built-in skills: `tomo-system`, `tomo-lcm`, `tomo-browse`.
|
|
108
112
|
|
|
109
113
|
### Custom / third-party skills
|
|
110
114
|
Place skill directories under `~/.tomo/workspace/.claude/skills/`. Each skill needs a `SKILL.md` with YAML frontmatter (`name` and `description`). The harness picks them up automatically — restart Tomo to load new skills.
|
|
@@ -148,7 +152,7 @@ tomo restart # Restart
|
|
|
148
152
|
|
|
149
153
|
### Session feels stale or confused
|
|
150
154
|
```bash
|
|
151
|
-
tomo sessions clear # Reset sessions
|
|
155
|
+
tomo sessions clear # Reset sessions (Must ask user to confirm)
|
|
152
156
|
tomo restart
|
|
153
157
|
```
|
|
154
158
|
Or tell the user to send `/new` in Telegram.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { McpSdkServerConfigWithInstance } from "@anthropic-ai/claude-agent-sdk";
|
|
2
|
-
/** True when the session uses our custom LCM compaction (DMs always; groups
|
|
3
|
-
*
|
|
4
|
-
* charge and the harness skips its compaction nudges. */
|
|
2
|
+
/** True when the session uses our custom LCM compaction (DMs always; groups
|
|
3
|
+
* unless config.lcm.groupCompactStyle="sdk"). When false, SDK auto-compact is
|
|
4
|
+
* in charge and the harness skips its compaction nudges. */
|
|
5
5
|
export declare function usesLcmCompact(sessionKey: string): boolean;
|
|
6
6
|
declare function skillsCanUseTool(toolName: string, input: Record<string, unknown>): Promise<{
|
|
7
7
|
behavior: "allow";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-options.d.ts","sourceRoot":"","sources":["../../src/agent/sdk-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAarF;;
|
|
1
|
+
{"version":3,"file":"sdk-options.d.ts","sourceRoot":"","sources":["../../src/agent/sdk-options.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,8BAA8B,EAAE,MAAM,gCAAgC,CAAC;AAarF;;6DAE6D;AAC7D,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAG1D;AAID,iBAAe,gBAAgB,CAC7B,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAAG;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC,CAa/G;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iEAAiE;IACjE,KAAK,CAAC,EAAE;QACN,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;QACxB;iFACyE;QACzE,SAAS,EAAE,OAAO,CAAC;KACpB,CAAC;CACH;AAED,wBAAgB,UAAU,CACxB,iBAAiB,EAAE,8BAA8B,EACjD,eAAe,CAAC,EAAE,MAAM,EACxB,KAAK,CAAC,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,cAAc;;;;;;;;;;;;;;oBAiDE,CAAC,SAAS,CAAC,EAAE;;;;;;;;;;EAwB/C"}
|
|
@@ -5,16 +5,16 @@ import { TOMO_INTERNAL_MCP_NAME } from "../mcp/internal-server.js";
|
|
|
5
5
|
// DM sessions run our custom hierarchical LCM (daily/weekly/monthly/yearly
|
|
6
6
|
// rollups via skill), so SDK auto-compact is disabled for them via the
|
|
7
7
|
// DISABLE_AUTO_COMPACT env var — we don't want the SDK to collapse our
|
|
8
|
-
// rollup structure behind our back. Group sessions default to
|
|
9
|
-
// (config.lcm.groupCompactStyle="
|
|
10
|
-
//
|
|
11
|
-
/** True when the session uses our custom LCM compaction (DMs always; groups
|
|
12
|
-
*
|
|
13
|
-
* charge and the harness skips its compaction nudges. */
|
|
8
|
+
// rollup structure behind our back. Group sessions default to the same
|
|
9
|
+
// hierarchical LCM flow (config.lcm.groupCompactStyle="lcm"); set it to "sdk"
|
|
10
|
+
// to fall back to SDK auto-compact for groups.
|
|
11
|
+
/** True when the session uses our custom LCM compaction (DMs always; groups
|
|
12
|
+
* unless config.lcm.groupCompactStyle="sdk"). When false, SDK auto-compact is
|
|
13
|
+
* in charge and the harness skips its compaction nudges. */
|
|
14
14
|
export function usesLcmCompact(sessionKey) {
|
|
15
15
|
if (!isGroupSessionKey(sessionKey))
|
|
16
16
|
return true;
|
|
17
|
-
return config.lcm.groupCompactStyle
|
|
17
|
+
return config.lcm.groupCompactStyle !== "sdk";
|
|
18
18
|
}
|
|
19
19
|
const SKILLS_DIR = `${config.workspaceDir}/.claude/skills/`;
|
|
20
20
|
async function skillsCanUseTool(toolName, input) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sdk-options.js","sourceRoot":"","sources":["../../src/agent/sdk-options.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,kBAAkB,CAAC;AACrD,OAAO,EAAE,sBAAsB,EAAE,MAAM,2BAA2B,CAAC;AAEnE,2EAA2E;AAC3E,uEAAuE;AACvE,uEAAuE;AACvE
|
|
1
|
+
{"version":3,"file":"sdk-options.js","sourceRoot":"","sources":["../../src/agent/sdk-options.ts"],"names":[],"mappings":"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"}
|
package/dist/agent.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAmB,eAAe,EAAoB,MAAM,qBAAqB,CAAC;AAevG,MAAM,MAAM,UAAU,GAAG;IAAE,EAAE,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAErE,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpC,MAAM,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,CAAC;CACzE;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,YAAY,CAAkC;IACtD,OAAO,CAAC,aAAa,CAAoC;IAIzD,OAAO,CAAC,cAAc,CAA4E;IAClG,OAAO,CAAC,iBAAiB,CAAkC;IAC3D,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,cAAc,CAAc;IAGpC,OAAO,CAAC,aAAa,CAA8B;IAInD,OAAO,CAAC,YAAY,CAA+B;IACnD,OAAO,CAAC,qBAAqB,CAAiF;IAC9G,OAAO,CAAC,QAAQ,CAAC,iBAAiB,CAAiC;;IAanE,gCAAgC;IAChC,OAAO,CAAC,UAAU;IAIlB;;;;;OAKG;IACH,OAAO,CAAC,oBAAoB;IAK5B,sFAAsF;IACtF,OAAO,CAAC,iBAAiB;IAazB,oEAAoE;YACtD,aAAa;IAsB3B,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAMlC,8EAA8E;IAC9E,kBAAkB,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE;IAIxC;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;IAWzB;;;;;;;;OAQG;YACW,cAAc;IAuC5B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAMtC;YAEY,aAAa;IAwE3B,OAAO,CAAC,sBAAsB;IA6B9B,OAAO,CAAC,gBAAgB;IAQxB,OAAO,CAAC,UAAU;IAQlB;;;;;;;;;;;;;;OAcG;YACW,eAAe;IAwB7B;;;;;OAKG;YACW,oBAAoB;IAelC;;;;;;;OAOG;IACH,OAAO,CAAC,gBAAgB;IAexB;;;;OAIG;IACH,OAAO,CAAC,iBAAiB;
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
package/dist/agent.js
CHANGED
|
@@ -348,7 +348,10 @@ export class Agent {
|
|
|
348
348
|
const pct = Math.round((ctx.contextUsed / ctx.contextMax) * 100);
|
|
349
349
|
if (pct < 80)
|
|
350
350
|
return;
|
|
351
|
-
|
|
351
|
+
const groupNote = isGroupSessionKey(key)
|
|
352
|
+
? " This is a group session — scope the rollup to this group's conversation (threads, decisions, group dynamics); don't mix in personal/DM context from elsewhere."
|
|
353
|
+
: "";
|
|
354
|
+
this.runWithRetry(key, `System: Context usage is at ${pct}% (${ctx.contextUsed}/${ctx.contextMax} tokens). Use the lcm compact skill to free up space before the next user message.${groupNote} After the compact finishes, reply NO_REPLY so we don't send a user-facing message for this housekeeping turn.`).catch(() => { });
|
|
352
355
|
}
|
|
353
356
|
async handleMessage(channel, message) {
|
|
354
357
|
const hasImages = message.images && message.images.length > 0;
|
|
@@ -392,7 +395,7 @@ export class Agent {
|
|
|
392
395
|
const stampedText = this.drainPendingNotes(key) + this.injectTimestamp(textForAgent, channel.name);
|
|
393
396
|
const stream = replyChannel.createStreamingMessage(replyChatId, isGroup ? message.id : undefined);
|
|
394
397
|
const response = await this.runWithRetry(key, stampedText, (text) => stream.update(text.replace(ATTACHMENT_TAG_RE, "").trim()), message.images, this.makeBlockHandler(replyChannel, replyChatId, stream));
|
|
395
|
-
stopTyping();
|
|
398
|
+
await stopTyping();
|
|
396
399
|
this.maybeNudgeCompact(key);
|
|
397
400
|
this.sessions.append(key, {
|
|
398
401
|
role: "assistant",
|
|
@@ -403,7 +406,7 @@ export class Agent {
|
|
|
403
406
|
await this.deliverResponse(replyChannel, replyChatId, response, stream);
|
|
404
407
|
}
|
|
405
408
|
catch (err) {
|
|
406
|
-
stopTyping();
|
|
409
|
+
await stopTyping();
|
|
407
410
|
log.error({ err }, "Error handling message");
|
|
408
411
|
// Passive groups: suppress error messages to avoid polluting the chat
|
|
409
412
|
if (isPassiveGroup)
|
|
@@ -462,7 +465,7 @@ export class Agent {
|
|
|
462
465
|
const allImages = items.flatMap((it) => it.message.images ?? []);
|
|
463
466
|
const stream = replyChannel.createStreamingMessage(replyChatId, isGroup ? lastMessage.id : undefined);
|
|
464
467
|
const response = await this.runWithRetry(key, stampedText, (text) => stream.update(text.replace(ATTACHMENT_TAG_RE, "").trim()), allImages.length > 0 ? allImages : undefined, this.makeBlockHandler(replyChannel, replyChatId, stream));
|
|
465
|
-
stopTyping();
|
|
468
|
+
await stopTyping();
|
|
466
469
|
this.maybeNudgeCompact(key);
|
|
467
470
|
this.sessions.append(key, {
|
|
468
471
|
role: "assistant",
|
|
@@ -473,7 +476,7 @@ export class Agent {
|
|
|
473
476
|
await this.deliverResponse(replyChannel, replyChatId, response, stream);
|
|
474
477
|
}
|
|
475
478
|
catch (err) {
|
|
476
|
-
stopTyping();
|
|
479
|
+
await stopTyping();
|
|
477
480
|
log.error({ err }, "Error handling batched messages");
|
|
478
481
|
if (isPassiveGroup)
|
|
479
482
|
return;
|
|
@@ -503,7 +506,8 @@ export class Agent {
|
|
|
503
506
|
// Context-usage hysteresis: nudge agent to run `tomo lcm daily` when
|
|
504
507
|
// context usage crosses the high-water mark; reset when it drops back
|
|
505
508
|
// below the low-water mark (a successful compact knocks it well under).
|
|
506
|
-
// Skip when the session uses SDK auto-compact (groups
|
|
509
|
+
// Skip when the session uses SDK auto-compact (only groups opted out via
|
|
510
|
+
// config.lcm.groupCompactStyle="sdk"; DMs and groups by default use LCM).
|
|
507
511
|
if (sid && usesLcmCompact(key)) {
|
|
508
512
|
const HIGH = config.lcm.nudgeAtPct / 100;
|
|
509
513
|
const LOW = config.lcm.nudgeResetPct / 100;
|
|
@@ -517,7 +521,10 @@ export class Agent {
|
|
|
517
521
|
if (usedFrac >= HIGH && !nudged) {
|
|
518
522
|
this.contextNudged.set(key, true);
|
|
519
523
|
const pct = Math.round(usedFrac * 100);
|
|
520
|
-
const
|
|
524
|
+
const groupNote = isGroupSessionKey(key)
|
|
525
|
+
? " This is a group session — scope the summary to this group's conversation (threads, decisions, group dynamics); don't mix in personal/DM context from elsewhere."
|
|
526
|
+
: "";
|
|
527
|
+
const nudge = `System: Context usage is at ${pct}% of the window. Please run \`tomo lcm daily --session-id ${sid} --summary "<today-so-far>"\` to roll up today's activity. Two things to know: (1) the daily compact OVERRIDES today's existing daily block — it does not append; write a fresh summary covering the whole day. (2) The command preserves the last ${config.lcm.dailyFreshTail} raw events as fresh tail.${groupNote} After the compact finishes, reply NO_REPLY so we don't send a user-facing message for this housekeeping turn.`;
|
|
521
528
|
log.info({ key, usedPct: `${pct}%` }, "Context nudge (agent should run lcm daily)");
|
|
522
529
|
// Fire-and-forget — don't block the current reply on the nudge
|
|
523
530
|
this.handleCronMessage(nudge, key).catch((err) => {
|
|
@@ -621,7 +628,7 @@ export class Agent {
|
|
|
621
628
|
const stopTyping = deliveryChannel.startTyping(deliveryChatId);
|
|
622
629
|
try {
|
|
623
630
|
const response = await this.runWithRetry(key, stampedMessage);
|
|
624
|
-
stopTyping();
|
|
631
|
+
await stopTyping();
|
|
625
632
|
log.info({ channel: deliveryChannel.name }, "Tomo: %s", response);
|
|
626
633
|
if (isSilentReply(response) || response.includes("NO_REPLY")) {
|
|
627
634
|
log.info("Cron completed silently (no reply sent)");
|
|
@@ -636,7 +643,7 @@ export class Agent {
|
|
|
636
643
|
await deliveryChannel.send({ chatId: deliveryChatId, text: response });
|
|
637
644
|
}
|
|
638
645
|
catch (err) {
|
|
639
|
-
stopTyping();
|
|
646
|
+
await stopTyping();
|
|
640
647
|
log.error({ err }, "Cron message handling failed");
|
|
641
648
|
const detail = err instanceof Error ? err.message : String(err);
|
|
642
649
|
await deliveryChannel.send({ chatId: deliveryChatId, text: `[error] cron failed: ${detail}` });
|