fix(chat): link the profile of an agent chat acted on (#19893)

## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agent Chat lets a person ask the CEO agent to act on other agents,
for example to resume a paused agent
> - The chat guidance tells the agent how to link tasks, but it does not
tell the agent how to link an agent profile
> - In a chat eval, the CEO resumed Morgan and reported the result, but
the reply had no link to Morgan
> - The person then has no direct route to check the saved availability
of the agent
> - This pull request adds one guidance sentence for agent profile links
> - The benefit is that a reply about an agent gives the person a link
to that agent

## Linked Issues or Issue Description

**What happened?**
A person asked the chat agent: "Resume Morgan so they can pick up their
work." The agent resumed Morgan through the API and reported the new
status. The reply did not link Morgan's profile. The chat guidance gives
only the task-link template (`/<prefix>/issues/<identifier>`), so the
agent had no route for an agent.

**Expected behavior**
When a reply is about a specific agent, the reply links that agent's
profile at `/<prefix>/agents/<urlKey or id>`. The link is a plain
profile link. It is not an `agent://` mention, because a mention
notifies the agent.

**Steps to reproduce**
1. Pause an agent named Morgan.
2. In Agent Chat with the CEO, send "Resume Morgan so they can pick up
their work."
3. Read the reply. It reports the resume but has no link to Morgan.

Refs #19889 (adds the run-link template in the same guidance; this
change merges cleanly with it).

## What Changed

- `server/src/services/agent-conversations.ts`: add one sentence to the
chat directive. It tells chat to link an affected agent's profile at
`/<prefix>/agents/<urlKey or id>`, and to use `agent://` only to notify
an agent.
- `server/src/__tests__/agent-conversations.test.ts`: add a regression
test that checks the directive and the built task prompt contain the
profile-link guidance.

## Verification

- `cd server && pnpm exec vitest run
src/__tests__/agent-conversations.test.ts -t "chat prompt policy"`
passes (7 tests).
- The new test fails on `origin/master`, because the directive does not
contain the sentence.
- The route exists in `ui/src/App.tsx` (`agents/:agentId`), and the UI
accepts a url key or an id.
- End to end: the `agents.resume-agent` chat eval runs with this change
on its case branch.

## Risks

- Low risk. The change adds prompt text only. No API, schema, or UI
behavior changes.
- The prompt becomes one sentence longer.

## Model Used

- Anthropic Claude Opus 5.5 (`claude-opus-5-5`), agentic coding with
tool use (shell, file edit), extended reasoning.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
DottaandClaude Opus 5.5 authored and GitHub committed 2026-11-07 16:28:00 -06:00
1 parent 29b6411660
commit 0f19eb39d3
2 files changed
+9

No files matched your search

@@ -986,6 +986,13 @@ describe("conversation execution wake policy", () => {
});
describe("chat prompt policy", () => {
it("tells chat to link the profile of an agent it acted on without turning the link into a wake mention", () => {
expect(AGENT_CHAT_DIRECTIVE).toContain("link its profile at /<prefix>/agents/<urlKey or id>");
expect(AGENT_CHAT_DIRECTIVE).toContain("use agent:// only when you intend to notify that agent");
const prompt = buildPaperclipTaskMarkdown({ issue: { id: "chat", identifier: null, title: "Chat", workMode: "ask", conversationAgentId: "agent" } });
expect(prompt).toContain("/<prefix>/agents/<urlKey or id>");
});
it("preserves explicit plan approval while avoiding ritual confirmations for ordinary chat", () => {
expect(AGENT_CHAT_DIRECTIVE).toContain("When the user asks to approve a plan before handoff");
expect(AGENT_CHAT_DIRECTIVE).toContain('interactionKind: "confirmation"');
@@ -112,6 +112,8 @@ For review or follow-up tasks, include the existing source materials the assigne
For task links, use the company-prefixed relative path /<prefix>/issues/<identifier>, deriving the prefix from the returned task identifier. For approval links, use /<prefix>/approvals/<approvalId> with the same company prefix and the returned approval id, so the person can open the approval to decide it. An absolute URL is appropriate only when its actual origin was supplied by the platform. Never invent a hostname for a Paperclip link.
When a reply concerns a specific agent, such as one you paused, resumed, configured, or reported on, link its profile at /<prefix>/agents/<urlKey or id> using the agent's returned urlKey or id. A profile link is not a mention: use agent:// only when you intend to notify that agent.
For status updates, distinguish recorded task status from active execution and verified progress. Read the latest relevant comments and run outcome before explaining a blocker or claiming work is underway. Use the advertised API tools for another task's details when needed. A completed dependency does not prove a block is stale; report the assignee's recorded reason. Agent configuration may be redacted: an empty configuration object without configuration-read permission does not prove settings are disabled or at their defaults. If the evidence is unavailable, say what you could verify and what remains unknown rather than guessing or recommending a status change.
Keep discussion here and leave the conversation available for the next message. Link handed-off tasks in your reply; do not make this conversation blocked by their completion or wait for them. Paperclip will bring completed handed-off tasks back as a new input here so you can explain the result and link it without another user message. After creating an assigned task, let its own run execute the work; do not create its deliverables or change its execution status from this chat. Reply normally and end your turn; Paperclip manages the conversation waiting state. Do not change its status, create a review confirmation just to finish a reply, mark it complete, or poll for another reply. An accepted plan authorizes handoff to execution tasks, never implementation on this conversation. Honor normal approvals. Ask mode is non-mutating. Plan mode supports research and writing/revising the plan; hand off for execution only through the normal authorized workflow.`;