feat(a2a): steer session citations toward inspect_peer (#1373)

* feat(a2a): steer session citations toward inspect_peer

Copy-reference prose and markdown /sessions/<id> links both parse to hub
ids; MCP/CLI descriptions and flavor prompts forbid treating them as local
FS paths so agents call inspect_peer first (tiann/hapi#1370).

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(a2a): fail closed on ambiguous session citations

Codex #1373: do not silently pick ids[0] when a paste contains multiple
/sessions/ links (shared by inspect_peer and ping_peer). Also strip
trailing prose punctuation from bare citation ids.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(a2a): prefer Copy-reference path over title /sessions/

Codex #1373 MINOR: titles containing /sessions/<other> must not make
normalizeSessionIdPrefix fail closed on an otherwise valid paste.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(a2a): do not short-circuit multi-citation Copy-reference pastes

Codex #1373 MAJOR: only treat parenthesized Copy-reference as canonical
when the paste is that citation alone (plus optional steer suffix).

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
HeavyGee
2026-08-05 15:05:38 +08:00
committed by GitHub
co-authored by Cursor
parent 8c4d4198a8
commit c7e38e872c
17 changed files with 383 additions and 37 deletions
+9 -2
View File
@@ -6,6 +6,7 @@
*/
import { trimIdent } from '@/utils/trimIdent';
import { buildSessionCitationSteerInstruction } from '@hapi/protocol/sessionCitation';
import { SKILL_LOOKUP_INSTRUCTION } from '@/modules/common/skillLookupInstruction';
/**
@@ -14,7 +15,10 @@ import { SKILL_LOOKUP_INSTRUCTION } from '@/modules/common/skillLookupInstructio
export const TITLE_INSTRUCTION = trimIdent(`
Use the title tool sparingly. For a new chat, call the tool "hapi_change_title" once after the user's initial request is clear, and set a concise task title. Do not rename the chat for routine progress, substeps, implementation details, or a slightly better wording. Rename only when the user's primary objective changes substantially and the existing title would be misleading.
When you create or find a local image file that the user should see, call the tool "hapi_display_image" with the image path so HAPI can show it inline.
When the user cites another HAPI session as [title](/sessions/<id>) (or a bare /sessions/<id>), extract that <id>. Call "hapi_inspect_peer" with sessionIdPrefix=<id> to read metadata and recent messages; call "hapi_ping_peer" with sessionIdPrefix=<id> and a message to nudge or hand off. Prefer these over JWT+curl. Shell fallbacks: hapi inspect-peer <id> / hapi ping-peer <id> <message>.
${buildSessionCitationSteerInstruction({
inspectTool: 'hapi_inspect_peer',
pingTool: 'hapi_ping_peer',
})}
${SKILL_LOOKUP_INSTRUCTION}
`);
@@ -24,7 +28,10 @@ export const TITLE_INSTRUCTION = trimIdent(`
*/
export const OPENCODE_NATIVE_TOOL_INSTRUCTION = trimIdent(`
When you create or find a local image file that the user should see, call the tool "hapi_display_image" with the image path so HAPI can show it inline.
When the user cites another HAPI session as [title](/sessions/<id>) (or a bare /sessions/<id>), extract that <id>. Call "hapi_inspect_peer" with sessionIdPrefix=<id> to read metadata and recent messages; call "hapi_ping_peer" with sessionIdPrefix=<id> and a message to nudge or hand off. Prefer these over JWT+curl. Shell fallbacks: hapi inspect-peer <id> / hapi ping-peer <id> <message>.
${buildSessionCitationSteerInstruction({
inspectTool: 'hapi_inspect_peer',
pingTool: 'hapi_ping_peer',
})}
${SKILL_LOOKUP_INSTRUCTION}
`);