feat(sharing): per-agent custom instructions for public & channel chats (#1205)#1337
Conversation
vybe
left a comment
There was a problem hiding this comment.
Validated via /validate-pr — two blockers (the prompt-injection framing, public/channel/x402 wiring, and tests look solid otherwise):
1. Missing Postgres/Alembic migration (Invariant #3). Adds agent_ownership.public_channel_system_prompt via a SQLite migration (_migrate_agent_ownership_public_channel_prompt) + schema.py/tables.py, but no Alembic revision under src/backend/migrations/versions/. PG deployments won't get the column. (schema-parity only guards the SQLite track — same gap as #1339.)
2. Conflicts with dev after #1317. #1317 restructured SharingPanel.vue (moved operator management to the new Access tab, reframed around Identity Proof / access policy). This PR was built on the old layout, so the SharingPanel.vue / routers/sharing.py conflicts need a rebase onto the redesigned component.
— posted via /validate-pr
|
Resolve by running |
fadcb90 to
a8565ad
Compare
Rebased onto
|
Rebased onto
|
…ts (#1205) Owners can attach extra system-prompt instructions that apply to public-facing conversations ONLY — public links, channel chats (Slack/Telegram/WhatsApp), and x402 paid chat — without changing the agent's behavior in their own authenticated chats, scheduled runs, loops, or agent-to-agent calls. The text-surface counterpart of voice_system_prompt. - schema/migration: agent_ownership.public_channel_system_prompt TEXT (schema.py + tables.py Core object + versioned migration, Invariant #3) - db: get/set_public_channel_system_prompt (set strips, empty clears) + facade delegation - models: PublicChannelPrompt / PublicChannelPromptUpdate (4000-char cap) - api: owner-only GET/PUT /api/agents/{name}/public-prompt (sharing.py), mirroring the voice-prompt endpoints - injection: platform_prompt_service.build_public_channel_caller_prompt folds the fragment with the MEM-001 memory block (public fragment first); wired into the three public-facing sites — message_router (channels), public.py (sync+async), paid.py (x402). Authenticated chat / schedules / loops / a2a never call it, so the scope exclusion holds by construction. Unset = strict no-op; a DB error degrades to the memory block (never blocks a chat) - ui: Additional Instructions textarea (save/clear, char counter) in SharingPanel.vue via two agents-store methods - tests: db get/set/clear/isolation + helper composition (4 combos + db-error degradation), SQLite + Postgres; schema-parity + migrations suites green - docs: requirements section 44, architecture endpoint + column Related to #1205 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…em_prompt (#1205) The PR predates Alembic adoption (#1183) and shipped only the SQLite migration. Add the paired Postgres revision (0005, chained after 0004_agent_ownership_voice_name) so the dual-track migration invariant holds — ADD COLUMN IF NOT EXISTS, no-op when 0001_baseline already created the column. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
81cbb3f to
53d5c1e
Compare
|
Re-review after today's Blockers (conflicts vs current
Migration (no action needed here): your Non-blocking quality:
After the rebase + green CI, re-request me and I'll merge. Context: #1421 (P0 alembic width fix) and #1335 both merged to |
/#1335/#1406 conflicts Resolutions: - requirements.md: take dev's index (#1406 split); relocate the #1205 section into requirements/public-access.md as Section 47 (46 was taken by #1335's roster requirement) - Alembic: renumber 0011_agent_ownership_public_channel_prompt -> 0012, re-parent on 0011_agent_ownership_tts_voice (#1397 landed first; whichever lands second renumbers) - db/migrations.py: keep both MIGRATIONS entries (tts_voice + public_channel_prompt) - routers/sharing.py + SharingPanel.vue + architecture.md: keep both #1335 roster and #1205 public-prompt surfaces (independent features) - .claude + src/backend/enterprise submodules: reset to dev's pointers (the branch pinned unrelated/stale commits) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PR Validation Report (/validate-pr) — post-resolution re-reviewPR: #1337 — feat(sharing): per-agent custom instructions for public & channel chats Both earlier blockers and today's 13:30 conflict list are now fully addressed — I resolved the rebase on-branch (merge commit
Recommendation: APPROVE — merging on green CI. |
vybe
left a comment
There was a problem hiding this comment.
Re-review complete — both original blockers fixed by the author, and I resolved the dev rebase on-branch (1c14fe6: requirements relocation to public-access.md §47, Alembic 0012 renumber, #1335 coexistence, submodule pointers reset). Full CI green incl. frontend-e2e + pg-migrations. See validation report above. Merging.
- migrations.py, test_25_telegram_voice_out.py: parent-squash echoes; PR does not touch them -> take dev's versions (keeps #1337 public_channel_prompt migration and #1397's final test set) - TelegramChannelPanel.vue: dev == feature/25 tip here; keep this branch's intended replacement of the inline voice block with shared VoiceRepliesControl
Summary
Adds a per-agent Additional instructions field on the Sharing tab that injects a custom system-prompt fragment into public-facing conversations only — public links, channel chats (Slack/Telegram/WhatsApp), and x402 paid chat. Owners can tailor persona, scope limits, disclaimers, or guardrails for outside audiences without touching how the agent behaves in their own authenticated chats, scheduled work, or agent-to-agent calls. The text-surface counterpart of the existing
voice_system_prompt.Implementation (mirrors
voice_system_promptend-to-end)agent_ownership.public_channel_system_prompt TEXTinschema.pyand thedb/tables.pyCore object, plus a versioned migration (Invariant Feature/vector log retention #3). Covers SQLite + Postgres.get/set_public_channel_system_prompt(set strips whitespace, empty clears) + facade delegation.PublicChannelPrompt/PublicChannelPromptUpdate, 4000-char cap (Invariant Add internal health route, without which main didn't start #14).GET/PUT /api/agents/{name}/public-prompt(sharing.py).platform_prompt_service.build_public_channel_caller_promptfolds the fragment with the MEM-001 memory block (public fragment first), wired into the three public-facing sites:message_router.py(all channels),public.py(public chat sync + async),paid.py(x402). Authenticated chat / Session tab / schedules / loops / a2a never call it — the scope exclusion holds by construction.SharingPanel.vuevia two agents-store methods (Invariants Feature/process engine #6/security: Fix token logging and add HTML reports to gitignore #7).Behavior guarantees
caller_prompt).Acceptance criteria
caller_promptTesting
30 passed— newtest_public_channel_prompt.py(db get/set/clear/isolation on SQLite + Postgres; helper composition: 4 combos + db-error degradation) plus the schema-parity and migrations suites green.Fixes #1205
🤖 Generated with Claude Code