voratiq 0.1.0-beta.20 → 0.1.0-beta.21

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 (85) hide show
  1. package/dist/agents/runtime/policy.d.ts +1 -1
  2. package/dist/bin.js +50 -19
  3. package/dist/cli/contract.d.ts +35 -5
  4. package/dist/cli/contract.js +42 -5
  5. package/dist/cli/list.js +4 -1
  6. package/dist/cli/message.d.ts +28 -0
  7. package/dist/cli/message.js +147 -0
  8. package/dist/cli/operator-envelope.d.ts +22 -1
  9. package/dist/cli/operator-envelope.js +48 -3
  10. package/dist/cli/reduce.js +5 -2
  11. package/dist/cli/verify.js +6 -2
  12. package/dist/commands/list/command.d.ts +1 -0
  13. package/dist/commands/list/command.js +117 -7
  14. package/dist/commands/message/command.d.ts +23 -0
  15. package/dist/commands/message/command.js +215 -0
  16. package/dist/commands/message/errors.d.ts +9 -0
  17. package/dist/commands/message/errors.js +20 -0
  18. package/dist/commands/message/lifecycle.d.ts +14 -0
  19. package/dist/commands/message/lifecycle.js +128 -0
  20. package/dist/commands/reduce/command.d.ts +1 -0
  21. package/dist/commands/reduce/command.js +3 -1
  22. package/dist/commands/reduce/targets.d.ts +1 -0
  23. package/dist/commands/reduce/targets.js +48 -2
  24. package/dist/commands/shared/resolve-stage-competitors.js +4 -1
  25. package/dist/commands/verify/command.d.ts +1 -0
  26. package/dist/commands/verify/command.js +2 -1
  27. package/dist/commands/verify/max-parallel.d.ts +1 -1
  28. package/dist/commands/verify/max-parallel.js +3 -1
  29. package/dist/commands/verify/targets.d.ts +2 -1
  30. package/dist/commands/verify/targets.js +154 -22
  31. package/dist/configs/agents/defaults.js +25 -25
  32. package/dist/configs/orchestration/bootstrap.d.ts +6 -1
  33. package/dist/configs/orchestration/bootstrap.js +27 -6
  34. package/dist/configs/orchestration/types.d.ts +25 -10
  35. package/dist/configs/orchestration/types.js +10 -6
  36. package/dist/configs/verification/types.d.ts +5 -0
  37. package/dist/configs/verification/types.js +3 -0
  38. package/dist/contracts/list.d.ts +38 -4
  39. package/dist/contracts/list.js +30 -1
  40. package/dist/domain/message/competition/adapter.d.ts +36 -0
  41. package/dist/domain/message/competition/adapter.js +197 -0
  42. package/dist/domain/message/competition/prompt.d.ts +8 -0
  43. package/dist/domain/message/competition/prompt.js +29 -0
  44. package/dist/domain/message/model/mutators.d.ts +17 -0
  45. package/dist/domain/message/model/mutators.js +107 -0
  46. package/dist/domain/message/model/types.d.ts +100 -0
  47. package/dist/domain/message/model/types.js +87 -0
  48. package/dist/domain/message/persistence/adapter.d.ts +43 -0
  49. package/dist/domain/message/persistence/adapter.js +124 -0
  50. package/dist/domain/reduce/competition/adapter.d.ts +1 -0
  51. package/dist/domain/reduce/competition/adapter.js +57 -4
  52. package/dist/domain/reduce/competition/prompt.d.ts +1 -1
  53. package/dist/domain/reduce/model/types.d.ts +3 -0
  54. package/dist/domain/reduce/model/types.js +2 -1
  55. package/dist/domain/verify/competition/adapter.js +8 -5
  56. package/dist/domain/verify/competition/programmatic.js +3 -0
  57. package/dist/domain/verify/competition/prompt.js +6 -0
  58. package/dist/domain/verify/competition/rubric.js +7 -1
  59. package/dist/domain/verify/competition/shared-layout.d.ts +42 -2
  60. package/dist/domain/verify/competition/shared-layout.js +92 -21
  61. package/dist/domain/verify/competition/target.d.ts +17 -0
  62. package/dist/domain/verify/model/types.d.ts +20 -2
  63. package/dist/domain/verify/model/types.js +15 -2
  64. package/dist/mcp/server.d.ts +2 -2
  65. package/dist/mcp/server.js +30 -13
  66. package/dist/policy/verification.js +2 -0
  67. package/dist/preflight/index.d.ts +2 -0
  68. package/dist/preflight/index.js +3 -1
  69. package/dist/render/transcripts/list.d.ts +2 -0
  70. package/dist/render/transcripts/list.js +24 -0
  71. package/dist/render/transcripts/message.d.ts +72 -0
  72. package/dist/render/transcripts/message.js +362 -0
  73. package/dist/render/transcripts/stage-progress.d.ts +1 -1
  74. package/dist/render/transcripts/verify.d.ts +4 -0
  75. package/dist/render/transcripts/verify.js +7 -1
  76. package/dist/render/utils/transcript-shell.d.ts +1 -1
  77. package/dist/render/utils/transcript-shell.js +6 -0
  78. package/dist/status/index.d.ts +21 -0
  79. package/dist/status/index.js +30 -0
  80. package/dist/workspace/setup.js +13 -7
  81. package/dist/workspace/structure.d.ts +14 -6
  82. package/dist/workspace/structure.js +25 -9
  83. package/dist/workspace/verification-defaults.d.ts +1 -1
  84. package/dist/workspace/verification-defaults.js +255 -0
  85. package/package.json +15 -16
@@ -1,5 +1,5 @@
1
1
  import { z } from "zod";
2
- export declare const listOperators: readonly ["spec", "run", "reduce", "verify"];
2
+ export declare const listOperators: readonly ["spec", "run", "reduce", "verify", "message"];
3
3
  export declare const listModes: readonly ["table", "detail"];
4
4
  export type ListOperator = (typeof listOperators)[number];
5
5
  export type ListMode = (typeof listModes)[number];
@@ -21,7 +21,10 @@ export interface SpecListJsonTableRecord extends ListJsonRecordBase {
21
21
  export interface TargetedListJsonTableRecord extends ListJsonRecordBase {
22
22
  target: ListJsonTargetRef;
23
23
  }
24
- export type ListJsonTableRecord = RunListJsonTableRecord | SpecListJsonTableRecord | TargetedListJsonTableRecord;
24
+ export interface MessageListJsonTableRecord extends ListJsonRecordBase {
25
+ promptPreview: string | null;
26
+ }
27
+ export type ListJsonTableRecord = RunListJsonTableRecord | SpecListJsonTableRecord | TargetedListJsonTableRecord | MessageListJsonTableRecord;
25
28
  export interface RunListJsonRow {
26
29
  agentId: string;
27
30
  status: string;
@@ -44,7 +47,12 @@ export interface VerifyListJsonRow {
44
47
  status: string;
45
48
  duration: string;
46
49
  }
47
- export type ListJsonRow = RunListJsonRow | SpecListJsonRow | ReduceListJsonRow | VerifyListJsonRow;
50
+ export interface MessageListJsonRow {
51
+ agentId: string;
52
+ status: string;
53
+ duration: string;
54
+ }
55
+ export type ListJsonRow = RunListJsonRow | SpecListJsonRow | ReduceListJsonRow | VerifyListJsonRow | MessageListJsonRow;
48
56
  export interface SpecListJsonArtifact {
49
57
  kind: "spec";
50
58
  agentId: string;
@@ -61,7 +69,12 @@ export interface VerificationListJsonArtifact {
61
69
  verifier: string;
62
70
  path: string | null;
63
71
  }
64
- export type ListJsonArtifact = SpecListJsonArtifact | ReductionListJsonArtifact | VerificationListJsonArtifact;
72
+ export interface MessageListJsonArtifact {
73
+ kind: "output";
74
+ agentId: string;
75
+ path: string | null;
76
+ }
77
+ export type ListJsonArtifact = SpecListJsonArtifact | ReductionListJsonArtifact | VerificationListJsonArtifact | MessageListJsonArtifact;
65
78
  export interface ListJsonTableOutput {
66
79
  operator: ListOperator;
67
80
  mode: "table";
@@ -78,6 +91,7 @@ export interface ListJsonDetailOutput {
78
91
  createdAt: string;
79
92
  elapsed?: string;
80
93
  workspacePath: string;
94
+ target?: ListJsonTargetRef;
81
95
  rows: ListJsonRow[];
82
96
  artifacts: ListJsonArtifact[];
83
97
  } | null;
@@ -85,6 +99,7 @@ export interface ListJsonDetailOutput {
85
99
  }
86
100
  export type ListJsonOutput = ListJsonTableOutput | ListJsonDetailOutput;
87
101
  export declare const listOperatorSchema: z.ZodEnum<{
102
+ message: "message";
88
103
  reduce: "reduce";
89
104
  spec: "spec";
90
105
  run: "run";
@@ -96,6 +111,7 @@ export declare const listModeSchema: z.ZodEnum<{
96
111
  }>;
97
112
  export declare const listJsonOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
98
113
  operator: z.ZodEnum<{
114
+ message: "message";
99
115
  reduce: "reduce";
100
116
  spec: "spec";
101
117
  run: "run";
@@ -120,10 +136,16 @@ export declare const listJsonOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
120
136
  kind: z.ZodString;
121
137
  id: z.ZodString;
122
138
  }, z.core.$loose>;
139
+ }, z.core.$loose>, z.ZodObject<{
140
+ id: z.ZodString;
141
+ status: z.ZodString;
142
+ createdAt: z.ZodString;
143
+ promptPreview: z.ZodNullable<z.ZodString>;
123
144
  }, z.core.$loose>]>>;
124
145
  warnings: z.ZodArray<z.ZodString>;
125
146
  }, z.core.$loose>, z.ZodObject<{
126
147
  operator: z.ZodEnum<{
148
+ message: "message";
127
149
  reduce: "reduce";
128
150
  spec: "spec";
129
151
  run: "run";
@@ -137,6 +159,10 @@ export declare const listJsonOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
137
159
  createdAt: z.ZodString;
138
160
  elapsed: z.ZodOptional<z.ZodString>;
139
161
  workspacePath: z.ZodString;
162
+ target: z.ZodOptional<z.ZodObject<{
163
+ kind: z.ZodString;
164
+ id: z.ZodString;
165
+ }, z.core.$loose>>;
140
166
  rows: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
141
167
  agentId: z.ZodString;
142
168
  status: z.ZodString;
@@ -151,6 +177,10 @@ export declare const listJsonOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
151
177
  verifier: z.ZodString;
152
178
  status: z.ZodString;
153
179
  duration: z.ZodString;
180
+ }, z.core.$loose>, z.ZodObject<{
181
+ agentId: z.ZodString;
182
+ status: z.ZodString;
183
+ duration: z.ZodString;
154
184
  }, z.core.$loose>]>>;
155
185
  artifacts: z.ZodArray<z.ZodUnion<readonly [z.ZodObject<{
156
186
  kind: z.ZodLiteral<"spec">;
@@ -165,6 +195,10 @@ export declare const listJsonOutputSchema: z.ZodDiscriminatedUnion<[z.ZodObject<
165
195
  agentId: z.ZodNullable<z.ZodString>;
166
196
  verifier: z.ZodString;
167
197
  path: z.ZodNullable<z.ZodString>;
198
+ }, z.core.$loose>, z.ZodObject<{
199
+ kind: z.ZodLiteral<"output">;
200
+ agentId: z.ZodString;
201
+ path: z.ZodNullable<z.ZodString>;
168
202
  }, z.core.$loose>]>>;
169
203
  }, z.core.$loose>>;
170
204
  warnings: z.ZodArray<z.ZodString>;
@@ -1,5 +1,11 @@
1
1
  import { z } from "zod";
2
- export const listOperators = ["spec", "run", "reduce", "verify"];
2
+ export const listOperators = [
3
+ "spec",
4
+ "run",
5
+ "reduce",
6
+ "verify",
7
+ "message",
8
+ ];
3
9
  export const listModes = ["table", "detail"];
4
10
  export const listOperatorSchema = z.enum(listOperators);
5
11
  export const listModeSchema = z.enum(listModes);
@@ -31,6 +37,11 @@ const targetedListJsonTableRecordSchema = listJsonRecordBaseSchema
31
37
  target: listJsonTargetRefSchema,
32
38
  })
33
39
  .passthrough();
40
+ const messageListJsonTableRecordSchema = listJsonRecordBaseSchema
41
+ .extend({
42
+ promptPreview: z.string().nullable(),
43
+ })
44
+ .passthrough();
34
45
  const runListJsonRowSchema = z
35
46
  .object({
36
47
  agentId: z.string(),
@@ -54,6 +65,13 @@ const verifyListJsonRowSchema = z
54
65
  duration: z.string(),
55
66
  })
56
67
  .passthrough();
68
+ const messageListJsonRowSchema = z
69
+ .object({
70
+ agentId: z.string(),
71
+ status: z.string(),
72
+ duration: z.string(),
73
+ })
74
+ .passthrough();
57
75
  const specListJsonArtifactSchema = z
58
76
  .object({
59
77
  kind: z.literal("spec"),
@@ -76,6 +94,13 @@ const verificationListJsonArtifactSchema = z
76
94
  path: z.string().nullable(),
77
95
  })
78
96
  .passthrough();
97
+ const messageListJsonArtifactSchema = z
98
+ .object({
99
+ kind: z.literal("output"),
100
+ agentId: z.string(),
101
+ path: z.string().nullable(),
102
+ })
103
+ .passthrough();
79
104
  const listJsonDetailSessionSchema = z
80
105
  .object({
81
106
  id: z.string(),
@@ -83,15 +108,18 @@ const listJsonDetailSessionSchema = z
83
108
  createdAt: z.string(),
84
109
  elapsed: z.string().optional(),
85
110
  workspacePath: z.string(),
111
+ target: listJsonTargetRefSchema.optional(),
86
112
  rows: z.array(z.union([
87
113
  runListJsonRowSchema,
88
114
  stageListJsonRowSchema,
89
115
  verifyListJsonRowSchema,
116
+ messageListJsonRowSchema,
90
117
  ])),
91
118
  artifacts: z.array(z.union([
92
119
  specListJsonArtifactSchema,
93
120
  reductionListJsonArtifactSchema,
94
121
  verificationListJsonArtifactSchema,
122
+ messageListJsonArtifactSchema,
95
123
  ])),
96
124
  })
97
125
  .passthrough();
@@ -103,6 +131,7 @@ const listJsonTableOutputSchema = z
103
131
  runListJsonTableRecordSchema,
104
132
  specListJsonTableRecordSchema,
105
133
  targetedListJsonTableRecordSchema,
134
+ messageListJsonTableRecordSchema,
106
135
  ])),
107
136
  warnings: z.array(z.string()),
108
137
  })
@@ -0,0 +1,36 @@
1
+ import type { CompetitionCommandAdapter } from "../../../competition/command-adapter.js";
2
+ import { type ResolvedExtraContextFile } from "../../../competition/shared/extra-context.js";
3
+ import { type TeardownController } from "../../../competition/shared/teardown.js";
4
+ import type { AgentDefinition } from "../../../configs/agents/types.js";
5
+ import type { EnvironmentConfig } from "../../../configs/environment/types.js";
6
+ import type { TokenUsageResult } from "../../../workspace/chat/token-usage-result.js";
7
+ import { type AgentWorkspacePaths } from "../../../workspace/layout.js";
8
+ import type { ExtractedTokenUsage } from "../../run/model/types.js";
9
+ export type MessageCompetitionCandidate = AgentDefinition;
10
+ export interface MessageCompetitionExecution {
11
+ readonly agentId: string;
12
+ readonly status: "succeeded" | "failed";
13
+ readonly startedAt: string;
14
+ readonly completedAt: string;
15
+ readonly outputPath?: string;
16
+ readonly stdoutPath: string;
17
+ readonly stderrPath: string;
18
+ readonly tokenUsage?: ExtractedTokenUsage;
19
+ readonly tokenUsageResult: TokenUsageResult;
20
+ readonly error?: string;
21
+ }
22
+ interface PreparedMessageCompetitionCandidate {
23
+ readonly candidate: MessageCompetitionCandidate;
24
+ readonly workspacePaths: AgentWorkspacePaths;
25
+ readonly prompt: string;
26
+ }
27
+ export interface CreateMessageCompetitionAdapterInput {
28
+ readonly root: string;
29
+ readonly messageId: string;
30
+ readonly prompt: string;
31
+ readonly environment: EnvironmentConfig;
32
+ readonly extraContextFiles?: readonly ResolvedExtraContextFile[];
33
+ readonly teardown?: TeardownController;
34
+ }
35
+ export declare function createMessageCompetitionAdapter(input: CreateMessageCompetitionAdapterInput): CompetitionCommandAdapter<MessageCompetitionCandidate, PreparedMessageCompetitionCandidate, MessageCompetitionExecution>;
36
+ export {};
@@ -0,0 +1,197 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { detectAgentProcessFailureDetail } from "../../../agents/runtime/failures.js";
4
+ import { runSandboxedAgent } from "../../../agents/runtime/harness.js";
5
+ import { teardownSessionAuth } from "../../../agents/runtime/registry.js";
6
+ import { stageExtraContextFiles, } from "../../../competition/shared/extra-context.js";
7
+ import { composeStageSandboxPolicy } from "../../../competition/shared/sandbox-policy.js";
8
+ import { createTeardownController, runTeardown, } from "../../../competition/shared/teardown.js";
9
+ import { buildUnavailableTokenUsageResult, resolveTokenUsage, } from "../../../domain/shared/token-usage.js";
10
+ import { toErrorMessage } from "../../../utils/errors.js";
11
+ import { normalizePathForDisplay, relativeToRoot, resolvePath, } from "../../../utils/path.js";
12
+ import { extractProviderNativeTokenUsageForSession } from "../../../workspace/chat/native-usage.js";
13
+ import { scaffoldAgentSessionWorkspace, } from "../../../workspace/layout.js";
14
+ import { promoteWorkspaceFile } from "../../../workspace/promotion.js";
15
+ import { MESSAGE_RESPONSE_FILENAME, VORATIQ_MESSAGE_DIR, } from "../../../workspace/structure.js";
16
+ import { buildMessagePrompt } from "./prompt.js";
17
+ export function createMessageCompetitionAdapter(input) {
18
+ const { root, messageId, prompt, environment, extraContextFiles = [], teardown: providedTeardown, } = input;
19
+ const teardown = providedTeardown ?? createTeardownController(`message \`${messageId}\``);
20
+ const ownsTeardown = providedTeardown === undefined;
21
+ teardown.addAction({
22
+ key: `message-auth:${messageId}`,
23
+ label: "session auth",
24
+ cleanup: async () => {
25
+ await teardownSessionAuth(messageId);
26
+ },
27
+ });
28
+ return {
29
+ failurePolicy: "continue",
30
+ prepareCandidates: async (candidates) => {
31
+ const ready = [];
32
+ const failures = [];
33
+ for (const candidate of candidates) {
34
+ const startedAt = new Date().toISOString();
35
+ try {
36
+ const workspacePaths = await scaffoldAgentSessionWorkspace({
37
+ root,
38
+ domain: VORATIQ_MESSAGE_DIR,
39
+ sessionId: messageId,
40
+ agentId: candidate.id,
41
+ });
42
+ registerScratchWorkspaceTeardown(teardown, workspacePaths, candidate.id);
43
+ await stageExtraContextFiles({
44
+ contextPath: workspacePaths.contextPath,
45
+ files: extraContextFiles,
46
+ });
47
+ const builtPrompt = buildMessagePrompt({
48
+ prompt,
49
+ repoRootPath: root,
50
+ workspacePath: workspacePaths.workspacePath,
51
+ extraContextFiles,
52
+ });
53
+ ready.push({
54
+ candidate,
55
+ workspacePaths,
56
+ prompt: builtPrompt,
57
+ });
58
+ }
59
+ catch (error) {
60
+ const completedAt = new Date().toISOString();
61
+ failures.push({
62
+ agentId: candidate.id,
63
+ status: "failed",
64
+ startedAt,
65
+ completedAt,
66
+ stdoutPath: buildStdoutDisplayPath(root, messageId, candidate.id),
67
+ stderrPath: buildStderrDisplayPath(root, messageId, candidate.id),
68
+ tokenUsageResult: buildUnavailableTokenUsageResult({
69
+ provider: candidate.provider,
70
+ modelId: candidate.model,
71
+ message: toErrorMessage(error),
72
+ }),
73
+ error: toErrorMessage(error),
74
+ });
75
+ }
76
+ }
77
+ return { ready, failures };
78
+ },
79
+ executeCandidate: async (prepared) => {
80
+ const { candidate, workspacePaths, prompt: builtPrompt } = prepared;
81
+ const startedAt = new Date().toISOString();
82
+ try {
83
+ const result = await runSandboxedAgent({
84
+ root,
85
+ sessionId: messageId,
86
+ sandboxStageId: "message",
87
+ agent: candidate,
88
+ prompt: builtPrompt,
89
+ environment,
90
+ paths: {
91
+ agentRoot: workspacePaths.agentRoot,
92
+ workspacePath: workspacePaths.workspacePath,
93
+ sandboxHomePath: workspacePaths.sandboxHomePath,
94
+ runtimeManifestPath: workspacePaths.runtimeManifestPath,
95
+ sandboxSettingsPath: workspacePaths.sandboxSettingsPath,
96
+ runtimePath: workspacePaths.runtimePath,
97
+ artifactsPath: workspacePaths.artifactsPath,
98
+ stdoutPath: workspacePaths.stdoutPath,
99
+ stderrPath: workspacePaths.stderrPath,
100
+ },
101
+ captureChat: true,
102
+ teardownAuthOnExit: false,
103
+ ...composeStageSandboxPolicy(),
104
+ });
105
+ const tokenUsageResult = await extractProviderNativeTokenUsageForSession({
106
+ root,
107
+ domain: VORATIQ_MESSAGE_DIR,
108
+ sessionId: messageId,
109
+ agentId: candidate.id,
110
+ provider: candidate.provider,
111
+ modelId: candidate.model,
112
+ chatCaptured: result.chat?.captured === true,
113
+ format: result.chat?.format,
114
+ artifactPath: result.chat?.artifactPath,
115
+ });
116
+ const tokenUsage = resolveTokenUsage(tokenUsageResult);
117
+ if (result.exitCode !== 0 || result.errorMessage) {
118
+ const detail = (await detectAgentProcessFailureDetail({
119
+ provider: candidate.provider,
120
+ stdoutPath: workspacePaths.stdoutPath,
121
+ stderrPath: workspacePaths.stderrPath,
122
+ })) ??
123
+ result.errorMessage ??
124
+ `Agent exited with code ${result.exitCode ?? "unknown"}`;
125
+ return {
126
+ agentId: candidate.id,
127
+ status: "failed",
128
+ startedAt,
129
+ completedAt: new Date().toISOString(),
130
+ stdoutPath: normalizePathForDisplay(relativeToRoot(root, workspacePaths.stdoutPath)),
131
+ stderrPath: normalizePathForDisplay(relativeToRoot(root, workspacePaths.stderrPath)),
132
+ tokenUsage,
133
+ tokenUsageResult,
134
+ error: detail,
135
+ };
136
+ }
137
+ const stagedResponsePath = join(workspacePaths.workspacePath, MESSAGE_RESPONSE_FILENAME);
138
+ await readFile(stagedResponsePath, "utf8");
139
+ const responsePromoteResult = await promoteWorkspaceFile({
140
+ workspacePath: workspacePaths.workspacePath,
141
+ artifactsPath: workspacePaths.artifactsPath,
142
+ stagedRelativePath: MESSAGE_RESPONSE_FILENAME,
143
+ artifactRelativePath: MESSAGE_RESPONSE_FILENAME,
144
+ deleteStaged: true,
145
+ });
146
+ return {
147
+ agentId: candidate.id,
148
+ status: "succeeded",
149
+ startedAt,
150
+ completedAt: new Date().toISOString(),
151
+ outputPath: normalizePathForDisplay(relativeToRoot(root, responsePromoteResult.artifactPath)),
152
+ stdoutPath: normalizePathForDisplay(relativeToRoot(root, workspacePaths.stdoutPath)),
153
+ stderrPath: normalizePathForDisplay(relativeToRoot(root, workspacePaths.stderrPath)),
154
+ tokenUsage,
155
+ tokenUsageResult,
156
+ };
157
+ }
158
+ catch (error) {
159
+ return {
160
+ agentId: candidate.id,
161
+ status: "failed",
162
+ startedAt,
163
+ completedAt: new Date().toISOString(),
164
+ stdoutPath: normalizePathForDisplay(relativeToRoot(root, workspacePaths.stdoutPath)),
165
+ stderrPath: normalizePathForDisplay(relativeToRoot(root, workspacePaths.stderrPath)),
166
+ tokenUsageResult: buildUnavailableTokenUsageResult({
167
+ provider: candidate.provider,
168
+ modelId: candidate.model,
169
+ message: toErrorMessage(error),
170
+ }),
171
+ error: toErrorMessage(error),
172
+ };
173
+ }
174
+ },
175
+ finalizeCompetition: async () => {
176
+ if (ownsTeardown) {
177
+ await runTeardown(teardown);
178
+ }
179
+ },
180
+ sortResults: compareMessageExecutionsByAgentId,
181
+ };
182
+ }
183
+ function registerScratchWorkspaceTeardown(teardown, workspacePaths, agentId) {
184
+ teardown.addPath(workspacePaths.workspacePath, `${agentId} workspace`);
185
+ teardown.addPath(workspacePaths.contextPath, `${agentId} context`);
186
+ teardown.addPath(workspacePaths.runtimePath, `${agentId} runtime`);
187
+ teardown.addPath(workspacePaths.sandboxPath, `${agentId} sandbox`);
188
+ }
189
+ function compareMessageExecutionsByAgentId(left, right) {
190
+ return left.agentId.localeCompare(right.agentId);
191
+ }
192
+ function buildStdoutDisplayPath(root, messageId, agentId) {
193
+ return normalizePathForDisplay(relativeToRoot(root, resolvePath(root, `.voratiq/message/sessions/${messageId}/${agentId}/artifacts/stdout.log`)));
194
+ }
195
+ function buildStderrDisplayPath(root, messageId, agentId) {
196
+ return normalizePathForDisplay(relativeToRoot(root, resolvePath(root, `.voratiq/message/sessions/${messageId}/${agentId}/artifacts/stderr.log`)));
197
+ }
@@ -0,0 +1,8 @@
1
+ import { type ResolvedExtraContextFile } from "../../../competition/shared/extra-context.js";
2
+ export interface BuildMessagePromptOptions {
3
+ prompt: string;
4
+ repoRootPath: string;
5
+ workspacePath: string;
6
+ extraContextFiles?: readonly ResolvedExtraContextFile[];
7
+ }
8
+ export declare function buildMessagePrompt(options: BuildMessagePromptOptions): string;
@@ -0,0 +1,29 @@
1
+ import { appendExtraContextPromptSection, } from "../../../competition/shared/extra-context.js";
2
+ import { appendConstraints, appendOutputRequirements, buildWorkspaceArtifactRequirements, } from "../../../competition/shared/prompt-helpers.js";
3
+ export function buildMessagePrompt(options) {
4
+ const { prompt, repoRootPath, workspacePath, extraContextFiles = [], } = options;
5
+ const lines = [
6
+ "Respond to the prompt below using the available repository context.",
7
+ "",
8
+ "Guidance:",
9
+ "- Inspect the repository directly when needed.",
10
+ "- Keep the response focused on the prompt.",
11
+ "",
12
+ "Prompt:",
13
+ "```",
14
+ prompt.trim(),
15
+ "```",
16
+ ];
17
+ appendConstraints(lines, {
18
+ readAccess: repoRootPath,
19
+ writeAccess: workspacePath,
20
+ });
21
+ appendExtraContextPromptSection(lines, extraContextFiles);
22
+ appendOutputRequirements(lines, buildWorkspaceArtifactRequirements([
23
+ {
24
+ instruction: "Write the response",
25
+ path: "response.md",
26
+ },
27
+ ], ["- `response.md` is required."]));
28
+ return `${lines.join("\n")}\n`;
29
+ }
@@ -0,0 +1,17 @@
1
+ import type { MessageRecipientEntry, MessageRecord, MessageStatus } from "./types.js";
2
+ export interface MessageRecordMutators {
3
+ recordRecipientQueued: (recipient: MessageRecipientEntry) => Promise<void>;
4
+ recordRecipientRunning: (recipient: MessageRecipientEntry) => Promise<void>;
5
+ recordRecipientSnapshot: (recipient: MessageRecipientEntry) => Promise<void>;
6
+ completeMessage: (options: {
7
+ status: MessageStatus;
8
+ error?: string | null;
9
+ }) => Promise<MessageRecord>;
10
+ readRecord: () => Promise<MessageRecord | undefined>;
11
+ }
12
+ export interface CreateMessageRecordMutatorsInput {
13
+ readonly root: string;
14
+ readonly messagesFilePath: string;
15
+ readonly messageId: string;
16
+ }
17
+ export declare function createMessageRecordMutators(input: CreateMessageRecordMutatorsInput): MessageRecordMutators;
@@ -0,0 +1,107 @@
1
+ import { buildLifecycleStartFields, buildRecordLifecycleCompleteFields, } from "../../shared/lifecycle.js";
2
+ import { rewriteMessageRecord } from "../persistence/adapter.js";
3
+ export function createMessageRecordMutators(input) {
4
+ const { root, messagesFilePath, messageId } = input;
5
+ return {
6
+ recordRecipientQueued: async (recipient) => {
7
+ await updateRecipient({
8
+ root,
9
+ messagesFilePath,
10
+ messageId,
11
+ recipient,
12
+ });
13
+ },
14
+ recordRecipientRunning: async (recipient) => {
15
+ await updateRecipient({
16
+ root,
17
+ messagesFilePath,
18
+ messageId,
19
+ recipient,
20
+ });
21
+ },
22
+ recordRecipientSnapshot: async (recipient) => {
23
+ await updateRecipient({
24
+ root,
25
+ messagesFilePath,
26
+ messageId,
27
+ recipient,
28
+ forceFlush: recipient.status === "succeeded" ||
29
+ recipient.status === "failed" ||
30
+ recipient.status === "aborted",
31
+ });
32
+ },
33
+ completeMessage: async ({ status, error }) => await rewriteMessageRecord({
34
+ root,
35
+ messagesFilePath,
36
+ sessionId: messageId,
37
+ mutate: (existing) => ({
38
+ ...existing,
39
+ status,
40
+ ...buildRecordLifecycleCompleteFields({ existing }),
41
+ ...(error !== undefined ? { error } : {}),
42
+ }),
43
+ forceFlush: true,
44
+ }),
45
+ readRecord: async () => await rewriteMessageRecord({
46
+ root,
47
+ messagesFilePath,
48
+ sessionId: messageId,
49
+ mutate: (record) => record,
50
+ }),
51
+ };
52
+ }
53
+ async function updateRecipient(options) {
54
+ const { root, messagesFilePath, messageId, recipient, forceFlush = false, } = options;
55
+ await rewriteMessageRecord({
56
+ root,
57
+ messagesFilePath,
58
+ sessionId: messageId,
59
+ forceFlush,
60
+ mutate: (existing) => {
61
+ const recipients = [...existing.recipients];
62
+ const index = recipients.findIndex((entry) => entry.agentId === recipient.agentId);
63
+ const current = index >= 0 ? recipients[index] : undefined;
64
+ const merged = mergeRecipientEntries(current, recipient);
65
+ if (index >= 0) {
66
+ recipients[index] = merged;
67
+ }
68
+ else {
69
+ recipients.push(merged);
70
+ }
71
+ return {
72
+ ...existing,
73
+ status: existing.status === "running" || merged.status !== "running"
74
+ ? existing.status
75
+ : "running",
76
+ ...(merged.startedAt
77
+ ? buildLifecycleStartFields({
78
+ existingStartedAt: existing.startedAt,
79
+ timestamp: merged.startedAt,
80
+ })
81
+ : {}),
82
+ recipients,
83
+ };
84
+ },
85
+ });
86
+ }
87
+ function mergeRecipientEntries(existing, incoming) {
88
+ if (existing &&
89
+ isTerminalRecipientStatus(existing.status) &&
90
+ !isTerminalRecipientStatus(incoming.status)) {
91
+ return existing;
92
+ }
93
+ return {
94
+ ...(existing ?? {}),
95
+ ...incoming,
96
+ outputPath: incoming.outputPath ?? existing?.outputPath,
97
+ stdoutPath: incoming.stdoutPath ?? existing?.stdoutPath,
98
+ stderrPath: incoming.stderrPath ?? existing?.stderrPath,
99
+ tokenUsage: incoming.tokenUsage ?? existing?.tokenUsage,
100
+ error: incoming.error !== undefined ? incoming.error : (existing?.error ?? null),
101
+ startedAt: incoming.startedAt ?? existing?.startedAt,
102
+ completedAt: incoming.completedAt ?? existing?.completedAt,
103
+ };
104
+ }
105
+ function isTerminalRecipientStatus(status) {
106
+ return status === "succeeded" || status === "failed" || status === "aborted";
107
+ }