Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions actions/setup/js/copilot_session_bootstrap.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,34 @@ describe("Copilot retry session bootstrap", () => {

const run = () => runLogParser({ parseLog: parseCopilotLog, parserName: "Copilot", supportsDirectories: true, artifactDir: root });

it.each([false, true])("publishes Unified session as a top-level disclosure with safe outputs enabled: %s", async safeOutputs => {
writeSession("session", session("session", "2026-10-03T18:23:15Z", { tool: true }));
if (safeOutputs) {
const outputs = path.join(root, "safe-outputs.jsonl");
fs.writeFileSync(outputs, serialize([{ type: "create_issue", title: "Test issue", body: "Test body" }]));
process.env.GH_AW_SAFE_OUTPUTS = outputs;
}

await run();

expect(core.setFailed).not.toHaveBeenCalled();
expect(core.summary.addRaw).toHaveBeenCalledOnce();
const markdown = core.summary.addRaw.mock.calls[0][0];
expect(markdown).toMatch(/^<details><summary>Unified session<\/summary>\n\n/);
expect(markdown.match(/<summary>Unified session<\/summary>/g)).toHaveLength(1);
expect(markdown).not.toContain("<summary>Agentic Conversation</summary>");
expect(markdown).toContain("retained result");
let depth = 0;
for (const match of markdown.matchAll(/<details(?: open)?>|<\/details>|<summary>(Unified session|Safe Outputs)<\/summary>/g)) {
if (match[0].startsWith("<details")) depth++;
else if (match[0] === "</details>") depth--;
else expect(depth).toBe(1);
expect(depth).toBeGreaterThanOrEqual(0);
}
expect(depth).toBe(0);
if (safeOutputs) expect(markdown).toContain("<summary>Safe Outputs</summary>");
});

it("persists every retry conversation with source provenance but accounts only the chronological final attempt", async () => {
writeSession("z-first", session("first", "2026-10-03T18:23:15Z", { inputTokens: 100, tool: true }));
writeSession("a-last", session("last", "2026-10-03T18:23:23Z"));
Expand Down
12 changes: 7 additions & 5 deletions actions/setup/js/log_parser_bootstrap.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ const { writeSessionArtifact } = require("./session_artifact.cjs");
const { collectCodexJSONRecords } = require("./codex_log_framing.cjs");
const { collectAgentExecution, parseAgentExitCode, isAgentExecutionEvent } = require("./agent_execution.cjs");
const { hasCopilotConversation, hasMalformedJsonl, deduplicateCopilotFallback } = require("./copilot_session.cjs");
const { isUnifiedSessionTrace } = require("./unified_session_render.cjs");
const INFERENCE_ACCESS_ERROR_PATTERN = /Access denied by policy settings|invalid access to inference/i;
const CLAUDE_RATE_LIMIT_PATTERN = /rate_limit_error|429 Too Many Requests|"api_error_status"\s*:\s*429|request rejected \(429\)|rate limit/i;
const CLAUDE_OVERLOAD_PATTERN = /overloaded_error|"overloaded"/i;
Expand Down Expand Up @@ -532,11 +533,12 @@ async function runLogParser(options) {
parserName,
});

// Wrap the agent log in a details/summary section (open by default)
const wrappedAgentLog = wrapAgentLogInSection(copilotCliStyleMarkdown, {
parserName,
open: true,
});
const wrappedAgentLog = isUnifiedSessionTrace(publicationEntries)
? copilotCliStyleMarkdown
: wrapAgentLogInSection(copilotCliStyleMarkdown, {
parserName,
open: true,
});

// Add safe outputs preview to step summary
let fullMarkdown = wrappedAgentLog;
Expand Down
2 changes: 1 addition & 1 deletion actions/setup/js/session_cli.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe("Session CLI adapter", () => {
]);
const file = write("usage/aw_session.jsonl", sessionCLI(["reconstruct", root]));
const markdown = sessionCLI(["markdown", file]);
expect(markdown).toContain("<summary>Unified session</summary>");
expect(markdown).toMatch(/^<details><summary>Unified session<\/summary>\n\n/);
expect(markdown).toContain("Visible assistant response");
expect(markdown).toContain("tool.execution_start");
expect(markdown).not.toContain("private user prompt");
Expand Down
2 changes: 1 addition & 1 deletion actions/setup/js/unified_session_render.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -341,7 +341,7 @@ describe("unified session publication views", () => {
expect(trace).toEqual(original);
const markdown = generateCopilotCliStyleSummary(trace);
expect(markdown).toContain("Done <details>");
expect(markdown).toContain("<details><summary>Unified session</summary>");
expect(markdown).toMatch(/^<details><summary>Unified session<\/summary>\n\n/);
expect(markdown).not.toContain("### Unified session");
expect(markdown).not.toContain("=== Unified session ===");
expect(markdown).not.toContain("| Time |");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1419,13 +1419,14 @@ envelope's target `agentId` does not identify the emitting caller. Readers must
not invent parent tool IDs to distinguish these scopes; a view containing only
one nested scope can select that scope's initialization and accounting explicitly.

Actions publishes this view once in a plain-titled `Unified session` disclosure,
Actions publishes this view once in a top-level `Unified session` disclosure,
using a fenced CLI-style transcript like the Claude conversation summary rather
than a Markdown table. Opening the disclosure shows source-local conversations
with paired tool outcomes; per-source statistics and the full chronological
timeline remain in separate, collapsed disclosures. Gateway diagnostics do not
append a second unified event timeline, and the disclosure does not repeat its
title as a standalone heading.
timeline remain in separate, collapsed disclosures. The log parser does not wrap
this view in an additional `Agentic Conversation` disclosure. Gateway diagnostics
do not append a second unified event timeline, and the disclosure does not repeat
its title as a standalone heading.

| Observation | Unified display projection |
| --- | --- |
Expand Down
Loading