@stigmer/sdk 3.12.6 → 3.12.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/__tests__/update-input-roundtrip.test.js +4 -0
  2. package/__tests__/update-input-roundtrip.test.js.map +1 -1
  3. package/execution/__tests__/transcript.test.d.ts +2 -0
  4. package/execution/__tests__/transcript.test.d.ts.map +1 -0
  5. package/execution/__tests__/transcript.test.js +527 -0
  6. package/execution/__tests__/transcript.test.js.map +1 -0
  7. package/execution/conversation-rules.d.ts +64 -0
  8. package/execution/conversation-rules.d.ts.map +1 -0
  9. package/execution/conversation-rules.js +113 -0
  10. package/execution/conversation-rules.js.map +1 -0
  11. package/execution/transcript.d.ts +171 -0
  12. package/execution/transcript.d.ts.map +1 -0
  13. package/execution/transcript.js +484 -0
  14. package/execution/transcript.js.map +1 -0
  15. package/gen/agentexecution.d.ts +11 -0
  16. package/gen/agentexecution.d.ts.map +1 -1
  17. package/gen/agentexecution.js +30 -1
  18. package/gen/agentexecution.js.map +1 -1
  19. package/gen/client.d.ts +5 -1
  20. package/gen/client.d.ts.map +1 -1
  21. package/gen/client.js +4 -0
  22. package/gen/client.js.map +1 -1
  23. package/gen/identityaccount.d.ts +1 -0
  24. package/gen/identityaccount.d.ts.map +1 -1
  25. package/gen/identityaccount.js +2 -0
  26. package/gen/identityaccount.js.map +1 -1
  27. package/gen/memory.d.ts +58 -0
  28. package/gen/memory.d.ts.map +1 -0
  29. package/gen/memory.js +143 -0
  30. package/gen/memory.js.map +1 -0
  31. package/gen/organization.d.ts +1 -0
  32. package/gen/organization.d.ts.map +1 -1
  33. package/gen/organization.js +2 -0
  34. package/gen/organization.js.map +1 -1
  35. package/index.d.ts +3 -0
  36. package/index.d.ts.map +1 -1
  37. package/index.js +3 -0
  38. package/index.js.map +1 -1
  39. package/package.json +2 -2
  40. package/src/__tests__/update-input-roundtrip.test.ts +4 -0
  41. package/src/execution/__tests__/transcript.golden.md +100 -0
  42. package/src/execution/__tests__/transcript.test.ts +627 -0
  43. package/src/execution/conversation-rules.ts +119 -0
  44. package/src/execution/transcript.ts +735 -0
  45. package/src/gen/agentexecution.ts +45 -1
  46. package/src/gen/client.ts +6 -1
  47. package/src/gen/identityaccount.ts +3 -0
  48. package/src/gen/memory.ts +164 -0
  49. package/src/gen/organization.ts +3 -0
  50. package/src/index.ts +28 -0
@@ -0,0 +1,527 @@
1
+ // The canonical session transcript (stigmer/stigmer#814): assembly rules,
2
+ // offload resolution, and the two serializations.
3
+ //
4
+ // The Markdown format is a pinned contract: transcript.golden.md freezes the
5
+ // exact rendering of a transcript exercising every construct (thinking,
6
+ // system, tool calls with args/results, offloaded outputs resolved and
7
+ // noted, sub-agent nesting, build-from-plan and in-progress markers). A
8
+ // deliberate format change regenerates the golden with
9
+ // UPDATE_TRANSCRIPT_GOLDEN=1 npx vitest run src/execution/__tests__/transcript.test.ts
10
+ // and reviews the diff; an accidental one fails here.
11
+ import { readFileSync, writeFileSync } from "node:fs";
12
+ import { fileURLToPath } from "node:url";
13
+ import { dirname, resolve } from "node:path";
14
+ import { describe, it, expect } from "vitest";
15
+ import { create } from "@bufbuild/protobuf";
16
+ import { AgentExecutionSchema, } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
17
+ import { ExecutionPhase, MessageType, ToolCallStatus, } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
18
+ import { AgentExecutionListSchema, GetArtifactContentResponseSchema, } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/io_pb";
19
+ import { SessionSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
20
+ import { assembleSessionTranscript, fetchSessionTranscript, resolveOffloadedOutputs, transcriptToJson, transcriptToMarkdown, } from "../transcript";
21
+ const here = dirname(fileURLToPath(import.meta.url));
22
+ // ---------------------------------------------------------------------------
23
+ // Fixture builders
24
+ // ---------------------------------------------------------------------------
25
+ function session() {
26
+ return create(SessionSchema, {
27
+ metadata: { id: "ses_01" },
28
+ spec: { subject: "Fix the flaky test", agentInstanceId: "agi_01" },
29
+ });
30
+ }
31
+ /** Turn 1: prompt echo dedupe, thinking, tool call with args + inline
32
+ * result + duration, offloaded text output, image output, raw system. */
33
+ function exec1() {
34
+ return create(AgentExecutionSchema, {
35
+ metadata: { id: "aex_01a" },
36
+ spec: { sessionId: "ses_01", message: "Why is CI red?" },
37
+ status: {
38
+ phase: ExecutionPhase.EXECUTION_COMPLETED,
39
+ startedAt: "2026-08-20T10:00:00Z",
40
+ completedAt: "2026-08-20T10:01:00Z",
41
+ messages: [
42
+ {
43
+ type: MessageType.MESSAGE_HUMAN,
44
+ content: "Why is CI red?",
45
+ timestamp: "2026-08-20T10:00:01Z",
46
+ },
47
+ {
48
+ type: MessageType.MESSAGE_THINKING,
49
+ content: "The failure is in the retry loop.\nLet me check.",
50
+ timestamp: "2026-08-20T10:00:02Z",
51
+ },
52
+ {
53
+ type: MessageType.MESSAGE_AI,
54
+ content: "Let me look.",
55
+ timestamp: "2026-08-20T10:00:04Z",
56
+ toolCalls: [
57
+ {
58
+ id: "tc_1",
59
+ name: "shell_command",
60
+ args: { command: "go test ./..." },
61
+ result: "FAIL: TestRetry",
62
+ status: ToolCallStatus.TOOL_CALL_COMPLETED,
63
+ startedAt: "2026-08-20T10:00:05Z",
64
+ completedAt: "2026-08-20T10:00:07Z",
65
+ },
66
+ ],
67
+ },
68
+ {
69
+ type: MessageType.MESSAGE_AI,
70
+ content: "",
71
+ timestamp: "2026-08-20T10:00:10Z",
72
+ toolCalls: [
73
+ {
74
+ id: "tc_2",
75
+ name: "read_file",
76
+ args: { path: "retry.go" },
77
+ status: ToolCallStatus.TOOL_CALL_COMPLETED,
78
+ outputRef: {
79
+ storageKey: "artifacts/aex_01a/toolcalls/tc_2.txt",
80
+ sizeBytes: 2048n,
81
+ mimeType: "text/plain",
82
+ truncatedPreview: "package retry…",
83
+ },
84
+ },
85
+ {
86
+ id: "tc_3",
87
+ name: "screenshot",
88
+ status: ToolCallStatus.TOOL_CALL_COMPLETED,
89
+ outputRef: {
90
+ storageKey: "artifacts/aex_01a/toolcalls/tc_3.png",
91
+ sizeBytes: 4096n,
92
+ mimeType: "image/png",
93
+ isImage: true,
94
+ },
95
+ },
96
+ ],
97
+ },
98
+ {
99
+ type: MessageType.MESSAGE_SYSTEM,
100
+ content: "Approval received",
101
+ timestamp: "2026-08-20T10:00:20Z",
102
+ },
103
+ ],
104
+ },
105
+ });
106
+ }
107
+ /** Superseded by exec3's edit-and-resubmit — excluded by default. */
108
+ function exec2() {
109
+ return create(AgentExecutionSchema, {
110
+ metadata: { id: "aex_01b" },
111
+ spec: { sessionId: "ses_01", message: "old prompt" },
112
+ status: { phase: ExecutionPhase.EXECUTION_COMPLETED },
113
+ });
114
+ }
115
+ /** Turn 2: edit-and-resubmit successor with a sub-agent delegation. */
116
+ function exec3() {
117
+ return create(AgentExecutionSchema, {
118
+ metadata: { id: "aex_01c" },
119
+ spec: {
120
+ sessionId: "ses_01",
121
+ message: "edited prompt",
122
+ supersedesExecutionId: "aex_01b",
123
+ },
124
+ status: {
125
+ phase: ExecutionPhase.EXECUTION_COMPLETED,
126
+ startedAt: "2026-08-20T11:00:00Z",
127
+ messages: [
128
+ {
129
+ type: MessageType.MESSAGE_AI,
130
+ content: "Delegating.",
131
+ toolCalls: [
132
+ {
133
+ id: "tc_sa",
134
+ name: "task",
135
+ status: ToolCallStatus.TOOL_CALL_COMPLETED,
136
+ },
137
+ ],
138
+ },
139
+ ],
140
+ subAgentExecutions: [
141
+ {
142
+ id: "tc_sa",
143
+ name: "explore",
144
+ subject: "Explore the repo",
145
+ input: "find tests",
146
+ output: "found 3",
147
+ startedAt: "2026-08-20T11:00:01Z",
148
+ completedAt: "2026-08-20T11:00:06Z",
149
+ messages: [
150
+ {
151
+ type: MessageType.MESSAGE_AI,
152
+ content: "Scanning.",
153
+ toolCalls: [
154
+ {
155
+ id: "tc_sa_1",
156
+ name: "grep",
157
+ result: "3 matches",
158
+ status: ToolCallStatus.TOOL_CALL_COMPLETED,
159
+ outputRef: {
160
+ // Sub-agent outputs are stored under the PARENT
161
+ // execution's id — the storage key is the record of it.
162
+ storageKey: "artifacts/aex_01c/toolcalls/tc_sa_1.txt",
163
+ sizeBytes: 64n,
164
+ mimeType: "text/plain",
165
+ truncatedPreview: "3 matches…",
166
+ },
167
+ },
168
+ ],
169
+ },
170
+ ],
171
+ },
172
+ ],
173
+ },
174
+ });
175
+ }
176
+ /** Turn 3: an in-flight Build-from-plan turn. */
177
+ function exec4() {
178
+ return create(AgentExecutionSchema, {
179
+ metadata: { id: "aex_01d" },
180
+ spec: {
181
+ sessionId: "ses_01",
182
+ message: "Build from plan",
183
+ executionConfig: { buildFromPlan: true },
184
+ },
185
+ status: {
186
+ phase: ExecutionPhase.EXECUTION_IN_PROGRESS,
187
+ startedAt: "2026-08-20T12:00:00Z",
188
+ messages: [{ type: MessageType.MESSAGE_AI, content: "Working on it." }],
189
+ },
190
+ });
191
+ }
192
+ function allExecutions() {
193
+ // Deliberately scrambled: assembly must restore ULID order.
194
+ return [exec3(), exec1(), exec4(), exec2()];
195
+ }
196
+ const RESOLVED = {
197
+ "artifacts/aex_01a/toolcalls/tc_2.txt": {
198
+ storageKey: "artifacts/aex_01a/toolcalls/tc_2.txt",
199
+ content: "package retry\n\nfunc Do() {}",
200
+ truncated: false,
201
+ totalSizeBytes: 2048,
202
+ mimeType: "text/plain",
203
+ isImage: false,
204
+ },
205
+ "artifacts/aex_01a/toolcalls/tc_3.png": {
206
+ storageKey: "artifacts/aex_01a/toolcalls/tc_3.png",
207
+ truncated: false,
208
+ totalSizeBytes: 4096,
209
+ mimeType: "image/png",
210
+ isImage: true,
211
+ },
212
+ "artifacts/aex_01c/toolcalls/tc_sa_1.txt": {
213
+ storageKey: "artifacts/aex_01c/toolcalls/tc_sa_1.txt",
214
+ content: "3 matches in test/",
215
+ truncated: false,
216
+ totalSizeBytes: 64,
217
+ mimeType: "text/plain",
218
+ isImage: false,
219
+ },
220
+ };
221
+ // ---------------------------------------------------------------------------
222
+ // Assembly
223
+ // ---------------------------------------------------------------------------
224
+ describe("assembleSessionTranscript", () => {
225
+ it("orders turns chronologically by ULID regardless of input order", () => {
226
+ const t = assembleSessionTranscript(session(), allExecutions());
227
+ expect(t.turns.map((x) => x.execution.metadata?.id)).toEqual([
228
+ "aex_01a",
229
+ "aex_01c",
230
+ "aex_01d",
231
+ ]);
232
+ });
233
+ it("excludes superseded turns by default, matching the conversation view", () => {
234
+ const t = assembleSessionTranscript(session(), allExecutions());
235
+ expect(t.turns.some((x) => x.execution.metadata?.id === "aex_01b")).toBe(false);
236
+ expect(t.includesSuperseded).toBe(false);
237
+ });
238
+ it("keeps superseded turns, marked, when includeSuperseded is set", () => {
239
+ const t = assembleSessionTranscript(session(), allExecutions(), {
240
+ includeSuperseded: true,
241
+ });
242
+ const ids = t.turns.map((x) => x.execution.metadata?.id);
243
+ expect(ids).toEqual(["aex_01a", "aex_01b", "aex_01c", "aex_01d"]);
244
+ expect(t.turns.map((x) => x.superseded)).toEqual([
245
+ false,
246
+ true,
247
+ false,
248
+ false,
249
+ ]);
250
+ });
251
+ it("synthesizes user prompts by the shared rule", () => {
252
+ const t = assembleSessionTranscript(session(), allExecutions());
253
+ expect(t.turns[0].userPrompt).toBe("Why is CI red?");
254
+ // Build-from-plan: machine label, no user prose.
255
+ expect(t.turns[2].userPrompt).toBeNull();
256
+ expect(t.turns[2].isBuildFromPlan).toBe(true);
257
+ });
258
+ it("suppresses the 'execute' placeholder prompt", () => {
259
+ const exec = create(AgentExecutionSchema, {
260
+ metadata: { id: "aex_x" },
261
+ spec: { sessionId: "ses_01", message: "execute" },
262
+ status: { phase: ExecutionPhase.EXECUTION_COMPLETED },
263
+ });
264
+ const t = assembleSessionTranscript(session(), [exec]);
265
+ expect(t.turns[0].userPrompt).toBeNull();
266
+ expect(t.turns[0].isBuildFromPlan).toBe(false);
267
+ });
268
+ it("marks non-terminal executions in progress", () => {
269
+ const t = assembleSessionTranscript(session(), allExecutions());
270
+ expect(t.turns.map((x) => x.inProgress)).toEqual([false, false, true]);
271
+ });
272
+ });
273
+ function fakeArtifactClient(contentByKey) {
274
+ const requests = [];
275
+ return {
276
+ requests,
277
+ client: {
278
+ agentExecution: {
279
+ listBySession: () => Promise.reject(new Error("not under test")),
280
+ getArtifactContent: (input) => {
281
+ requests.push(input);
282
+ const entry = contentByKey[input.storageKey];
283
+ if (entry === undefined) {
284
+ return Promise.reject(new Error(`no such key: ${input.storageKey}`));
285
+ }
286
+ if (entry instanceof Error)
287
+ return Promise.reject(entry);
288
+ return Promise.resolve(create(GetArtifactContentResponseSchema, {
289
+ content: new TextEncoder().encode(entry.content),
290
+ truncated: entry.truncated ?? false,
291
+ totalSizeBytes: BigInt(entry.totalSizeBytes ?? entry.content.length),
292
+ }));
293
+ },
294
+ },
295
+ },
296
+ };
297
+ }
298
+ describe("resolveOffloadedOutputs", () => {
299
+ it("resolves parent and sub-agent refs, deriving each execution id from the storage key", async () => {
300
+ const { client, requests } = fakeArtifactClient({
301
+ "artifacts/aex_01a/toolcalls/tc_2.txt": { content: "full file" },
302
+ "artifacts/aex_01c/toolcalls/tc_sa_1.txt": { content: "3 matches in test/" },
303
+ });
304
+ const resolved = await resolveOffloadedOutputs(client, allExecutions());
305
+ expect(resolved["artifacts/aex_01a/toolcalls/tc_2.txt"].content).toBe("full file");
306
+ // The sub-agent's ref (nested in exec3's sub_agent_executions) resolved
307
+ // under the PARENT execution's id, taken from the key itself.
308
+ const subAgentRequest = requests.find((r) => r.storageKey === "artifacts/aex_01c/toolcalls/tc_sa_1.txt");
309
+ expect(subAgentRequest?.executionId).toBe("aex_01c");
310
+ });
311
+ it("never fetches image refs, but records them for the serializers", async () => {
312
+ const { client, requests } = fakeArtifactClient({
313
+ "artifacts/aex_01a/toolcalls/tc_2.txt": { content: "full file" },
314
+ "artifacts/aex_01c/toolcalls/tc_sa_1.txt": { content: "x" },
315
+ });
316
+ const resolved = await resolveOffloadedOutputs(client, allExecutions());
317
+ const imageKey = "artifacts/aex_01a/toolcalls/tc_3.png";
318
+ expect(requests.some((r) => r.storageKey === imageKey)).toBe(false);
319
+ expect(resolved[imageKey]).toMatchObject({
320
+ isImage: true,
321
+ mimeType: "image/png",
322
+ totalSizeBytes: 4096,
323
+ });
324
+ });
325
+ it("tolerates individual fetch failures — the rest still resolve", async () => {
326
+ const { client } = fakeArtifactClient({
327
+ "artifacts/aex_01a/toolcalls/tc_2.txt": new Error("storage unavailable"),
328
+ "artifacts/aex_01c/toolcalls/tc_sa_1.txt": { content: "3 matches in test/" },
329
+ });
330
+ const resolved = await resolveOffloadedOutputs(client, allExecutions());
331
+ expect(resolved["artifacts/aex_01a/toolcalls/tc_2.txt"].error).toBe("storage unavailable");
332
+ expect(resolved["artifacts/aex_01a/toolcalls/tc_2.txt"].content).toBeUndefined();
333
+ expect(resolved["artifacts/aex_01c/toolcalls/tc_sa_1.txt"].content).toBe("3 matches in test/");
334
+ });
335
+ it("carries the server's truncation flag and true size", async () => {
336
+ const { client } = fakeArtifactClient({
337
+ "artifacts/aex_01a/toolcalls/tc_2.txt": {
338
+ content: "first half…",
339
+ truncated: true,
340
+ totalSizeBytes: 1048576,
341
+ },
342
+ "artifacts/aex_01c/toolcalls/tc_sa_1.txt": { content: "x" },
343
+ });
344
+ const resolved = await resolveOffloadedOutputs(client, allExecutions());
345
+ expect(resolved["artifacts/aex_01a/toolcalls/tc_2.txt"]).toMatchObject({
346
+ truncated: true,
347
+ totalSizeBytes: 1048576,
348
+ });
349
+ });
350
+ });
351
+ // ---------------------------------------------------------------------------
352
+ // Fetch
353
+ // ---------------------------------------------------------------------------
354
+ describe("fetchSessionTranscript", () => {
355
+ function fakeClient(overrides) {
356
+ const artifacts = fakeArtifactClient({
357
+ "artifacts/aex_01a/toolcalls/tc_2.txt": { content: "full file" },
358
+ "artifacts/aex_01c/toolcalls/tc_sa_1.txt": { content: "3 matches" },
359
+ });
360
+ return {
361
+ session: { get: (id) => Promise.resolve(session()) },
362
+ agentExecution: {
363
+ ...artifacts.client.agentExecution,
364
+ listBySession: () => Promise.resolve(create(AgentExecutionListSchema, {
365
+ totalPages: overrides?.totalPages ?? 1,
366
+ entries: allExecutions(),
367
+ })),
368
+ },
369
+ };
370
+ }
371
+ it("assembles the full transcript with outputs resolved", async () => {
372
+ const t = await fetchSessionTranscript(fakeClient(), "ses_01");
373
+ expect(t.turns).toHaveLength(3);
374
+ expect(t.resolvedOutputs["artifacts/aex_01a/toolcalls/tc_2.txt"].content).toBe("full file");
375
+ });
376
+ it("skips output resolution when disabled", async () => {
377
+ const t = await fetchSessionTranscript(fakeClient(), "ses_01", {
378
+ resolveOutputs: false,
379
+ });
380
+ expect(Object.keys(t.resolvedOutputs)).toHaveLength(0);
381
+ });
382
+ it("refuses to export a silently truncated conversation if the server ever paginates", async () => {
383
+ await expect(fetchSessionTranscript(fakeClient({ totalPages: 2 }), "ses_01")).rejects.toThrow(/2 pages .* single page/s);
384
+ });
385
+ });
386
+ // ---------------------------------------------------------------------------
387
+ // Markdown
388
+ // ---------------------------------------------------------------------------
389
+ describe("transcriptToMarkdown", () => {
390
+ it("matches the pinned format contract (transcript.golden.md)", () => {
391
+ const t = assembleSessionTranscript(session(), allExecutions(), {
392
+ resolvedOutputs: RESOLVED,
393
+ });
394
+ const goldenPath = resolve(here, "transcript.golden.md");
395
+ const actual = transcriptToMarkdown(t);
396
+ if (process.env.UPDATE_TRANSCRIPT_GOLDEN) {
397
+ writeFileSync(goldenPath, actual);
398
+ }
399
+ expect(actual).toBe(readFileSync(goldenPath, "utf8"));
400
+ });
401
+ it("stamps the export time only when provided", () => {
402
+ const t = assembleSessionTranscript(session(), [exec1()]);
403
+ expect(transcriptToMarkdown(t)).not.toContain("Exported:");
404
+ expect(transcriptToMarkdown(t, { generatedAt: "2026-08-22T06:00:00Z" })).toContain("- Exported: 2026-08-22T06:00:00Z");
405
+ });
406
+ it("falls back to the ref's preview, with an honest note, when an output is unresolved", () => {
407
+ const t = assembleSessionTranscript(session(), [exec1()]);
408
+ const md = transcriptToMarkdown(t);
409
+ expect(md).toContain("_Offloaded output not resolved — showing preview._");
410
+ expect(md).toContain("package retry…");
411
+ });
412
+ it("notes the fetch failure when resolution was attempted and failed", () => {
413
+ const t = assembleSessionTranscript(session(), [exec1()], {
414
+ resolvedOutputs: {
415
+ "artifacts/aex_01a/toolcalls/tc_2.txt": {
416
+ storageKey: "artifacts/aex_01a/toolcalls/tc_2.txt",
417
+ truncated: false,
418
+ mimeType: "text/plain",
419
+ isImage: false,
420
+ error: "storage unavailable",
421
+ },
422
+ },
423
+ });
424
+ expect(transcriptToMarkdown(t)).toContain("_Offloaded output unavailable (storage unavailable) — showing preview._");
425
+ });
426
+ it("marks server-truncated outputs with the byte counts", () => {
427
+ const t = assembleSessionTranscript(session(), [exec1()], {
428
+ resolvedOutputs: {
429
+ "artifacts/aex_01a/toolcalls/tc_2.txt": {
430
+ storageKey: "artifacts/aex_01a/toolcalls/tc_2.txt",
431
+ content: "0123456789",
432
+ truncated: true,
433
+ totalSizeBytes: 1048576,
434
+ mimeType: "text/plain",
435
+ isImage: false,
436
+ },
437
+ },
438
+ });
439
+ expect(transcriptToMarkdown(t)).toContain("_Output truncated at 10 of 1048576 bytes (server content cap)._");
440
+ });
441
+ it("sizes fences past backtick runs in the content", () => {
442
+ const exec = create(AgentExecutionSchema, {
443
+ metadata: { id: "aex_x" },
444
+ spec: { sessionId: "ses_01", message: "prompt" },
445
+ status: {
446
+ phase: ExecutionPhase.EXECUTION_COMPLETED,
447
+ messages: [
448
+ {
449
+ type: MessageType.MESSAGE_AI,
450
+ content: "",
451
+ toolCalls: [
452
+ {
453
+ id: "tc",
454
+ name: "shell_command",
455
+ result: "a fence: ```md\ninside\n```",
456
+ status: ToolCallStatus.TOOL_CALL_COMPLETED,
457
+ },
458
+ ],
459
+ },
460
+ ],
461
+ },
462
+ });
463
+ const md = transcriptToMarkdown(assembleSessionTranscript(session(), [exec]));
464
+ expect(md).toContain("````\na fence: ```md\ninside\n```\n````");
465
+ });
466
+ it("marks kept superseded turns", () => {
467
+ const t = assembleSessionTranscript(session(), allExecutions(), {
468
+ includeSuperseded: true,
469
+ });
470
+ const md = transcriptToMarkdown(t);
471
+ expect(md).toContain("- Includes superseded (edited-and-resubmitted) turns");
472
+ expect(md).toContain("_Superseded by an edited resubmission._");
473
+ expect(md).toContain("old prompt");
474
+ });
475
+ });
476
+ // ---------------------------------------------------------------------------
477
+ // JSON
478
+ // ---------------------------------------------------------------------------
479
+ describe("transcriptToJson", () => {
480
+ it("is JSON.stringify-safe despite bigint proto fields (protojson contract)", () => {
481
+ const t = assembleSessionTranscript(session(), allExecutions(), {
482
+ resolvedOutputs: RESOLVED,
483
+ });
484
+ // sizeBytes is int64 → bigint on the proto; a raw stringify of the
485
+ // transcript would throw. The projection must not.
486
+ const text = JSON.stringify(transcriptToJson(t), null, 2);
487
+ const parsed = JSON.parse(text);
488
+ expect(parsed.format).toBe("stigmer.ai/session-transcript/v1");
489
+ expect(parsed.session.metadata.id).toBe("ses_01");
490
+ expect(parsed.turns).toHaveLength(3);
491
+ // protojson: snake_case field names, int64 as string.
492
+ expect(parsed.turns[0].execution.status.messages[3].tool_calls[0].output_ref
493
+ .size_bytes).toBe("2048");
494
+ });
495
+ it("carries the canonical-rule verdicts per turn", () => {
496
+ const t = assembleSessionTranscript(session(), allExecutions(), {
497
+ includeSuperseded: true,
498
+ });
499
+ const parsed = JSON.parse(JSON.stringify(transcriptToJson(t)));
500
+ expect(parsed.includes_superseded).toBe(true);
501
+ expect(parsed.turns[0].user_prompt).toBe("Why is CI red?");
502
+ expect(parsed.turns[1].superseded).toBe(true);
503
+ expect(parsed.turns[3].build_from_plan).toBe(true);
504
+ expect(parsed.turns[3].in_progress).toBe(true);
505
+ });
506
+ it("strips the internal Temporal callback token from execution status", () => {
507
+ const exec = exec1();
508
+ exec.status.callbackToken = new TextEncoder().encode("task-token");
509
+ const t = assembleSessionTranscript(session(), [exec]);
510
+ const parsed = JSON.parse(JSON.stringify(transcriptToJson(t)));
511
+ expect(parsed.turns[0].execution.status.callback_token).toBeUndefined();
512
+ // The strip is surgical — the rest of status is intact.
513
+ expect(parsed.turns[0].execution.status.messages).toHaveLength(5);
514
+ });
515
+ it("keys resolved outputs by storage key with plain-JSON fields", () => {
516
+ const t = assembleSessionTranscript(session(), allExecutions(), {
517
+ resolvedOutputs: RESOLVED,
518
+ });
519
+ const parsed = JSON.parse(JSON.stringify(transcriptToJson(t)));
520
+ expect(parsed.resolved_outputs["artifacts/aex_01a/toolcalls/tc_2.txt"]).toMatchObject({
521
+ content: "package retry\n\nfunc Do() {}",
522
+ mime_type: "text/plain",
523
+ total_size_bytes: 2048,
524
+ });
525
+ });
526
+ });
527
+ //# sourceMappingURL=transcript.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transcript.test.js","sourceRoot":"","sources":["../../../src/execution/__tests__/transcript.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,64 @@
1
+ import type { AgentExecution } from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/api_pb";
2
+ /**
3
+ * Returns the executions in chronological (oldest-first) order — the order a
4
+ * conversation reads top-to-bottom.
5
+ *
6
+ * Defense-in-depth against an unordered list response: the executions ARE the
7
+ * transcript, so a scrambled order drops the newest turns out of view (they no
8
+ * longer sort to the bottom). The server orders this list, but consumers must
9
+ * never depend on that alone. Resource ids are time-sortable ULIDs
10
+ * (`aex_01k…`), so an ascending id sort is creation order without parsing
11
+ * timestamps; entries missing an id sort last but keep a stable relative order.
12
+ */
13
+ export declare function sortChronologically(executions: readonly AgentExecution[]): AgentExecution[];
14
+ /**
15
+ * Collects the ids of executions replaced via edit-and-resubmit.
16
+ *
17
+ * The successor execution carries `spec.supersedes_execution_id`; hiding the
18
+ * superseded turn makes the edited message read as a single corrected exchange
19
+ * (in-place replace). The raw execution list still contains superseded records
20
+ * — execution-history surfaces show them deliberately — so this is a
21
+ * conversation-view rule, applied by whoever renders or exports a
22
+ * conversation.
23
+ *
24
+ * @param extraSupersededId An id known only outside the list — the live stream
25
+ * copy's `supersedesExecutionId`: right after a resubmit, the successor
26
+ * streams before the list refetch delivers it.
27
+ */
28
+ export declare function supersededExecutionIds(executions: readonly AgentExecution[], extraSupersededId?: string | null): Set<string>;
29
+ /**
30
+ * `true` when the execution is a Build-from-plan turn.
31
+ *
32
+ * Such a turn's `spec.message` is a machine-written label ("Build from
33
+ * plan"), not user prose — the real instruction is runner-injected from the
34
+ * same flag. Rendering or exporting the label as a user message would
35
+ * attribute words to the user they never typed; the plan the turn builds from
36
+ * is the visible cause.
37
+ */
38
+ export declare function isBuildFromPlanTurn(exec: AgentExecution): boolean;
39
+ /**
40
+ * The user prose that opens an execution's turn, or `null` when the turn has
41
+ * none.
42
+ *
43
+ * `spec.message` is the submitted prompt, but three shapes of it are not user
44
+ * prose and synthesize no user turn:
45
+ * - empty — nothing was typed (programmatic creates);
46
+ * - the literal `"execute"` — the legacy placeholder stamped on runs started
47
+ * without a message;
48
+ * - a Build-from-plan turn's machine-written label (see
49
+ * {@link isBuildFromPlanTurn}).
50
+ */
51
+ export declare function syntheticUserPrompt(exec: AgentExecution): string | null;
52
+ /**
53
+ * Extracts the execution id from an artifact storage key of the form
54
+ * `artifacts/{executionId}/...`. Returns `null` for an unexpected shape so the
55
+ * caller skips the fetch rather than issuing a request the server would
56
+ * reject.
57
+ *
58
+ * The fetch id must always derive from the key, never from render or export
59
+ * context: offloaded outputs inside a sub-agent's transcript are stored under
60
+ * the PARENT execution's id (the execution whose status was persisted), and
61
+ * the key is the record of that.
62
+ */
63
+ export declare function execIdFromStorageKey(storageKey: string): string | null;
64
+ //# sourceMappingURL=conversation-rules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conversation-rules.d.ts","sourceRoot":"","sources":["../../src/execution/conversation-rules.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,6DAA6D,CAAC;AAElG;;;;;;;;;;GAUG;AACH,wBAAgB,mBAAmB,CACjC,UAAU,EAAE,SAAS,cAAc,EAAE,GACpC,cAAc,EAAE,CASlB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,sBAAsB,CACpC,UAAU,EAAE,SAAS,cAAc,EAAE,EACrC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,GAChC,GAAG,CAAC,MAAM,CAAC,CAQb;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAEjE;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,GAAG,IAAI,CAMvE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAMtE"}