Merge remote-tracking branch 'upstream/master' into fix/workspace-instruction-frame-metadata

# Conflicts:
#	packages/support/acp-snapshot/README.i18n.yaml
#	packages/support/acp-snapshot/README.md
#	packages/support/acp-snapshot/README.zh.md
This commit is contained in:
ZiyaZhang
2026-07-28 08:59:32 -07:00
122 changed files with 3370 additions and 2451 deletions
@@ -0,0 +1,12 @@
{
"prompt": "respond",
"logs": [{
"file": "b/main/session.jsonl",
"lines": [
{ "type": "session", "id": "{{SID}}", "createdAt": 100, "cwd": "{{CWD}}", "delegationDepth": 0 },
{ "type": "request/header", "seq": 0, "time": 100, "data": { "header": { "config": { "model": "fake" }, "system": "SYS PROMPT", "tools": [{ "name": "t1", "description": "D1", "parameters": { "type": "object" } }] }, "reason": "initial" } },
{ "type": "request/header", "seq": 1, "time": 100, "data": { "header": { "config": { "model": "fake" }, "system": "SYS PROMPT\n\nNEW PROMPT LINE", "tools": [{ "name": "t1", "description": "D1", "parameters": { "type": "object" } }] }, "reason": "change" } },
{ "type": "turn/start", "seq": 2, "time": 100, "data": { "turn": 1 } }
]
}]
}
@@ -0,0 +1 @@
{ "steps": [{ "op": "initialize" }, { "op": "newSession" }, { "op": "prompt", "text": "pin" }] }
@@ -0,0 +1,4 @@
{"type":"session","id":"13131313-3434-4545-8686-787878787878","createdAt":7,"cwd":"/rec/shared-pin-cwd","delegationDepth":0}
{"type":"request/header","seq":0,"time":7,"data":{"header":{"config":{"model":"fake"},"system":"{{system}}","tools":"{{tools}}"},"reason":"initial"}}
{"type":"request/header","seq":1,"time":7,"data":{"header":{"config":{"model":"fake"},"system":"{{system}}","tools":"{{tools}}"},"reason":"change"}}
{"type":"turn/start","seq":2,"time":7,"data":{"turn":1}}
@@ -0,0 +1,4 @@
{"jsonrpc":"2.0","id":1,"result":{"protocolVersion":1,"agentCapabilities":{"loadSession":false}}}
{"jsonrpc":"2.0","id":2,"result":{"sessionId":"{{sessionId}}"}}
{"jsonrpc":"2.0","method":"session/update","params":{"sessionId":"{{sessionId}}","update":{"sessionUpdate":"agent_message_chunk","content":{"type":"text","text":"thinking about it"}}}}
{"jsonrpc":"2.0","id":3,"result":{"stopReason":"end_turn"}}
@@ -6,6 +6,8 @@ import { fileURLToPath } from 'node:url'
import { afterAll, describe, expect, it } from 'vitest'
import { defineAcpSnapshotSuite, type HarvestedLog, type Scenario } from '../src/index.ts'
import {
assertUniqueSnapshotContents,
claimSharedSnapshot,
fixtureContext,
formatSystemPromptSnapshot,
headerChangeCount,
@@ -18,6 +20,7 @@ import {
scenarioSkipped,
sessionFixtureNames,
restorePinnedToolSchemas,
type SharedSnapshotClaim,
stabilizeRefreshLog,
stdoutExpectedVariants,
unknownToolCallIds,
@@ -57,6 +60,16 @@ const RECORD_SRC = fileURLToPath(new URL('./fixtures/record-suite', import.meta.
// Replay pins explicit header classes; recording covers the default fallback.
const REPLAY_SCENARIOS: Scenario[] = [
{ name: 'pin-turn', hasModelTurn: true, recorded: true, pinsHeader: true, expectedHeaderChanges: 1, headerClass: 'main' },
{
name: 'shared-pin',
hasModelTurn: true,
recorded: true,
pinsHeader: true,
expectedHeaderChanges: 1,
headerClass: 'shared',
systemPromptSource: 'pin-turn',
toolSchemasSource: 'pin-turn',
},
{
name: 'plain-turn',
hasModelTurn: true,
@@ -214,6 +227,158 @@ describe('defineAcpSnapshotSuite: registration contract', () => {
})
}).toThrow(/header class "default" pinned by both first-pin and second-pin/)
})
it('throws when scenario names are duplicated', () => {
expect(() => {
defineAcpSnapshotSuite({
agent: AGENT,
snapshotsDir: REPLAY_DIR,
scenarios: [
{ name: 'duplicate', hasModelTurn: true, recorded: true, pinsHeader: true },
{ name: 'duplicate', hasModelTurn: true, recorded: true },
],
mode: 'replay',
})
}).toThrow(/duplicate scenario name "duplicate"/)
})
it.each(['systemPromptSource', 'toolSchemasSource'] as const)(
'rejects %s away from a header pin',
(field) => {
expect(() => {
defineAcpSnapshotSuite({
agent: AGENT,
snapshotsDir: REPLAY_DIR,
scenarios: [{
name: 'plain',
hasModelTurn: true,
recorded: true,
[field]: 'owner',
}],
mode: 'replay',
})
}).toThrow(new RegExp(`plain\\.${field} is only valid on a header-pinning scenario`))
},
)
it('rejects an unknown or non-pinning sidecar source', () => {
expect(() => {
defineAcpSnapshotSuite({
agent: AGENT,
snapshotsDir: REPLAY_DIR,
scenarios: [{
name: 'pin',
hasModelTurn: true,
recorded: true,
pinsHeader: true,
systemPromptSource: 'missing',
}],
mode: 'replay',
})
}).toThrow(/pin names unknown system-prompt snapshot source "missing"/)
expect(() => {
defineAcpSnapshotSuite({
agent: AGENT,
snapshotsDir: REPLAY_DIR,
scenarios: [
{
name: 'pin',
hasModelTurn: true,
recorded: true,
pinsHeader: true,
toolSchemasSource: 'plain',
},
{ name: 'plain', hasModelTurn: true, recorded: true },
],
mode: 'replay',
})
}).toThrow(/pin names non-pinning tool-schema snapshot source "plain"/)
})
it('rejects a sidecar source that redirects the same artifact', () => {
expect(() => {
defineAcpSnapshotSuite({
agent: AGENT,
snapshotsDir: REPLAY_DIR,
scenarios: [
{ name: 'owner', hasModelTurn: true, recorded: true, pinsHeader: true },
{
name: 'redirect',
hasModelTurn: true,
recorded: true,
pinsHeader: true,
headerClass: 'redirect',
systemPromptSource: 'owner',
},
{
name: 'consumer',
hasModelTurn: true,
recorded: true,
pinsHeader: true,
headerClass: 'consumer',
systemPromptSource: 'redirect',
},
],
mode: 'replay',
})
}).toThrow(/consumer names system-prompt snapshot source "redirect", which does not own its sidecar/)
})
it('rejects shared sidecars with different header-change counts', () => {
expect(() => {
defineAcpSnapshotSuite({
agent: AGENT,
snapshotsDir: REPLAY_DIR,
scenarios: [
{
name: 'owner',
hasModelTurn: true,
recorded: true,
pinsHeader: true,
expectedHeaderChanges: 1,
},
{
name: 'consumer',
hasModelTurn: true,
recorded: true,
pinsHeader: true,
headerClass: 'consumer',
toolSchemasSource: 'owner',
},
],
mode: 'replay',
})
}).toThrow(/consumer and owner declare different header-change counts for shared tool-schema snapshot/)
})
})
describe('shared snapshot content', () => {
it('accepts identical claims and rejects order-dependent shared output', () => {
const claims = new Map<string, SharedSnapshotClaim>()
claimSharedSnapshot(claims, 'shared/system-prompt.expected.md', 'first', 'prompt\n')
claimSharedSnapshot(claims, 'shared/system-prompt.expected.md', 'second', 'prompt\n')
expect(claims.get('shared/system-prompt.expected.md')).toEqual({
scenario: 'first',
content: 'prompt\n',
})
expect(() => {
claimSharedSnapshot(claims, 'shared/system-prompt.expected.md', 'third', 'different\n')
}).toThrow(/diverged between first and third/)
})
it('rejects identical committed content under different paths', () => {
assertUniqueSnapshotContents('prompt', [
{ path: 'one/system-prompt.expected.md', content: 'one\n' },
{ path: 'two/system-prompt.expected.md', content: 'two\n' },
])
expect(() => {
assertUniqueSnapshotContents('prompt', [
{ path: 'one/system-prompt.expected.md', content: 'same\n' },
{ path: 'two/system-prompt.expected.md', content: 'same\n' },
])
}).toThrow(/identical prompt snapshots appear in one\/system-prompt\.expected\.md and two\/system-prompt\.expected\.md/)
})
})
describe('sessionFixtureNames', () => {