Skip to content

Commit c4bf2ed

Browse files
committed
Merge branch 'dev' into main — release v3.11.0
27 commits since v3.10.0. Highlights: Features: - feat(tools/shell): runtime-reloadable global shell deny-groups via config.tools - feat(pancake): TikTok sub-platform support (#990) - feat(pancake): Shopee platform support (#975) - feat(tools): vault tool group in policy (#984) - feat(codex-pool): per-modality round-robin counter (chat vs image) (#1021) - feat(codex-pool,create_image): collapse primary_first + route pools through create_image chain (#1006) - feat(tools): team-root cross-chat read access with separate write-allowed paths - feat(vault): chat_id isolation for isolated teams - feat(tts): tenant timeout wiring + Gemini text-only 400 fix - feat(telegram): inject bot self-identity into agent system prompt - feat(tools): send_file for delivering existing workspace files - feat: native image_generation for Codex + OpenAI-compat (#1002) - feat(pipeline): session compaction overflow recovery (#958) Fixes: - fix(tools): scope credentialed-CLI blocked-command wording to [CREDENTIALED EXEC] marker - fix(tools/read_audio): route transcription models for openai_compat; fail-fast on missing creds - fix(discord): remove redundant allowlist gate that broke pairing/allowlist policies (#985) (#1010) - fix(vault): expand legacy-backfill regex + chat_id isolation coverage - fix(store): persist last_prompt_tokens via sessions.metadata - fix(pipeline): include tool-schema tokens in overhead + dynamic compact max_tokens - fix(telegram): strip own @mention from inbound content Refactor/chore: - refactor(pancake): stateless DM private-reply (#951) - refactor: adopt Go 1.26+ standard library modernizations - refactor(tools): write-allowed paths for edit and shell
2 parents 1b86270 + 25fb62a commit c4bf2ed

270 files changed

Lines changed: 11745 additions & 756 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
290 KB
Loading
663 KB
Loading
149 KB
Loading

.github/pr-assets/1002/index.html

Lines changed: 243 additions & 0 deletions
Large diffs are not rendered by default.
212 KB
Loading

.github/pr-assets/1006/index.html

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8"/>
5+
<meta name="viewport" content="width=device-width,initial-scale=1"/>
6+
<title>PR 1006 · Codex pool refactor + pool-aware create_image</title>
7+
<style>
8+
:root {
9+
--bg:#0d0d0d; --fg:#e8e4df; --card:#1a1714; --border:#2d2923;
10+
--muted:#8a837d; --accent:#ef4444; --good:#22c55e; --code:#151210;
11+
}
12+
html.light {
13+
--bg:#f8f6f3; --fg:#1a1714; --card:#ffffff; --border:#e5e0da;
14+
--muted:#6b6560; --accent:#dc2626; --good:#15803d; --code:#f3f0eb;
15+
}
16+
* { box-sizing: border-box; }
17+
body { margin:0; font-family: -apple-system, BlinkMacSystemFont, "Inter", sans-serif; background: var(--bg); color: var(--fg); padding: 32px; }
18+
.wrap { max-width: 1100px; margin: 0 auto; }
19+
h1 { margin: 0 0 8px 0; font-size: 22px; }
20+
.sub { color: var(--muted); margin-bottom: 28px; font-size: 14px; }
21+
.grid3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-bottom: 32px; }
22+
.card { background: var(--card); border: 1px solid var(--border); border-radius: 10px; padding: 16px; }
23+
.card h3 { margin: 0 0 8px 0; font-size: 13px; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
24+
.card p { margin: 0; font-size: 14px; line-height: 1.5; }
25+
.section { margin-bottom: 32px; }
26+
.section h2 { font-size: 16px; margin: 0 0 4px 0; }
27+
.section .note { color: var(--muted); font-size: 13px; margin-bottom: 12px; }
28+
.shot { background: var(--card); border: 1px solid var(--border); border-radius: 10px; overflow: hidden; }
29+
.shot-header { padding: 10px 14px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; font-size: 12px; }
30+
.label { font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--good); }
31+
.state { color: var(--muted); }
32+
.shot img { width: 100%; display: block; }
33+
pre.terminal { background: var(--code); color: var(--fg); padding: 14px; font-size: 12px; line-height: 1.5; overflow-x: auto; margin: 0; font-family: "SF Mono", Menlo, monospace; }
34+
.hl-good { background: rgba(34,197,94,0.14); border-left: 3px solid var(--good); padding-left: 8px; display: block; }
35+
.toggle { position: fixed; top: 20px; right: 20px; background: var(--card); border: 1px solid var(--border); color: var(--fg); padding: 8px 14px; border-radius: 8px; cursor: pointer; font-size: 12px; }
36+
@media (max-width: 900px) { .grid3 { grid-template-columns: 1fr; } }
37+
</style>
38+
</head>
39+
<body>
40+
<button class="toggle" onclick="document.documentElement.classList.toggle('light')">○ Light</button>
41+
<div class="wrap">
42+
<h1>PR 1006 · Codex pool refactor + pool-aware create_image</h1>
43+
<div class="sub">Closes #1001 and #1008. Captures: staging gateway on <code>claw</code>, master tenant, light theme, <code>openai-codex</code> provider configured as a 2-member <code>round_robin</code> pool with <code>openai-codex-2</code> as a member.</div>
44+
45+
<div class="grid3">
46+
<div class="card"><h3>What changed</h3><p>Chain entries pointing at a Codex OAuth pool now route through the pool's own strategy with internal failover. The outer chain only advances after the pool is fully exhausted.</p></div>
47+
<div class="card"><h3>Why it matters</h3><p>Before: users could accidentally select a pool member in the chain and bypass pool semantics. Now: the dropdown hides pool members and tags owners with an inline <code>Pool</code> chip — mirrors the Create Agent dropdown.</p></div>
48+
<div class="card"><h3>Review cue</h3><p>The inline <code>Pool</code> chip next to <code>openai-codex</code> — and the absence of <code>openai-codex-2</code> from the list — proves the UX unification. Backend failover is proven by 5 integration scenarios in <code>create_image_pool_chain_test.go</code>.</p></div>
49+
</div>
50+
51+
<div class="section">
52+
<h2>1. Pool-filtered Provider dropdown</h2>
53+
<div class="note">Red callout marks the <code>openai-codex</code> option tagged with an inline <code>Pool</code> chip. <code>openai-codex-2</code> (a pool member) is no longer listed — pool routing is reached only by picking the owner, matching the existing Create Agent dropdown pattern.</div>
54+
<div class="shot">
55+
<div class="shot-header">
56+
<span class="label">Implemented</span>
57+
<span class="state">Create Image — Provider Chain dialog, Provider dropdown open</span>
58+
</div>
59+
<img src="pool-dropdown-filtered.png" alt="Pool-filtered dropdown with inline Pool chip on owner"/>
60+
</div>
61+
</div>
62+
63+
<div class="section">
64+
<h2>2. Backend validation</h2>
65+
<div class="note">Full test matrix executed on the PR branch at the current HEAD.</div>
66+
<pre class="terminal"><span class="hl-good">go build ./... — ok (PG)</span>
67+
<span class="hl-good">go build -tags sqliteonly ./... — ok (Desktop)</span>
68+
<span class="hl-good">go vet ./... — no issues</span>
69+
<span class="hl-good">go test ./internal/tools/... ./internal/providers/... — 1599 passed</span>
70+
<span class="hl-good">Integration: 5 pool-chain scenarios × 5 runs under -race — 25/25 deterministic</span>
71+
<span class="hl-good">pnpm --dir ui/web tsc --noEmit — no errors</span></pre>
72+
</div>
73+
</div>
74+
</body>
75+
</html>
146 KB
Loading

CHANGELOG.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,21 @@ All notable changes to GoClaw are documented here. For full documentation, see [
2020
}
2121
```
2222

23+
### New Features
24+
25+
- **Pancake private-reply (comment → DM).** Enables a one-time DM to commenters
26+
after the public reply. Stateless on GoClaw side — no DB dedup table, no
27+
in-memory state:
28+
- Config: `features.private_reply` (bool) + `private_reply_message` (text).
29+
- **Template variables** `{{commenter_name}}` and `{{post_title}}` with
30+
literal-replace semantics (pre-sanitizes `{{`/`}}` from var values to
31+
prevent var-in-var substitution).
32+
- Empty `private_reply_message` → English fallback constant.
33+
- **Dedup strategy**: webhook-level comment_id dedup (already in
34+
`comment_handler.go`) + Facebook's per-comment idempotent `private_replies`
35+
endpoint handle duplicates platform-side. No GoClaw state required.
36+
- No DB migration.
37+
2338
### Improvements
2439

2540
- **Context pruning cleanup.** Removed redundant Pass 0 (per-result 30% guard),
@@ -30,6 +45,10 @@ All notable changes to GoClaw are documented here. For full documentation, see [
3045
missing a `mode` field get auto-backfilled with `mode: "cache-ttl"` to
3146
preserve their intent after the opt-in flip. Rows with NULL config stay
3247
NULL (new opt-in default applies). PG migration 51; SQLite schema v19.
48+
- **Pancake channel metadata routing.** Whitelist in
49+
`internal/channels/routing_metadata.go` now preserves `post_id` and
50+
`display_name` across the inbound → outbound hop so the private-reply
51+
template variables survive the agent pipeline round-trip.
3352

3453
## Project Status
3554

cmd/gateway_builtin_tools.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ func builtinToolSeedData() []store.BuiltinToolDef {
9090

9191
// messaging
9292
{Name: "message", DisplayName: "Message", Description: "Send a proactive message to a user on a connected channel (Telegram, Discord, etc.)", Category: "messaging", Enabled: true},
93+
{Name: "send_file", DisplayName: "Send File", Description: "Send an existing workspace file as an attachment in the current chat (does not create or modify the file)", Category: "messaging", Enabled: true},
9394

9495
// scheduling
9596
{Name: "cron", DisplayName: "Cron Scheduler", Description: "Schedule or manage recurring tasks using cron expressions, at-times, or intervals", Category: "scheduling", Enabled: true,

cmd/gateway_consumer_normal.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,16 @@ func processNormalMessage(
255255
extraPrompt += tsp
256256
}
257257

258+
// Append channel-provided self-identity hint (e.g. "You are @bot (Name) on Telegram").
259+
// Prevents the LLM from treating its own platform handle as another bot when users
260+
// @mention it directly or reference it alongside another bot in multi-bot groups.
261+
if identity := msg.Metadata[tools.MetaChannelSelfIdentity]; identity != "" {
262+
if extraPrompt != "" {
263+
extraPrompt += "\n\n"
264+
}
265+
extraPrompt += identity
266+
}
267+
258268
// Per-topic skill filter override (from group/topic config hierarchy).
259269
var skillFilter []string
260270
if ts := msg.Metadata[tools.MetaTopicSkills]; ts != "" {
@@ -379,6 +389,7 @@ func processNormalMessage(
379389
ChannelType: resolveChannelType(deps.ChannelMgr, msg.Channel),
380390
ChatTitle: msg.Metadata[tools.MetaChatTitle],
381391
ChatID: msg.ChatID,
392+
WorkspaceChatID: msg.ChatID,
382393
PeerKind: peerKind,
383394
LocalKey: msg.Metadata["local_key"],
384395
UserID: userID,

0 commit comments

Comments
 (0)