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.
- package/dist/agents/runtime/policy.d.ts +1 -1
- package/dist/bin.js +50 -19
- package/dist/cli/contract.d.ts +35 -5
- package/dist/cli/contract.js +42 -5
- package/dist/cli/list.js +4 -1
- package/dist/cli/message.d.ts +28 -0
- package/dist/cli/message.js +147 -0
- package/dist/cli/operator-envelope.d.ts +22 -1
- package/dist/cli/operator-envelope.js +48 -3
- package/dist/cli/reduce.js +5 -2
- package/dist/cli/verify.js +6 -2
- package/dist/commands/list/command.d.ts +1 -0
- package/dist/commands/list/command.js +117 -7
- package/dist/commands/message/command.d.ts +23 -0
- package/dist/commands/message/command.js +215 -0
- package/dist/commands/message/errors.d.ts +9 -0
- package/dist/commands/message/errors.js +20 -0
- package/dist/commands/message/lifecycle.d.ts +14 -0
- package/dist/commands/message/lifecycle.js +128 -0
- package/dist/commands/reduce/command.d.ts +1 -0
- package/dist/commands/reduce/command.js +3 -1
- package/dist/commands/reduce/targets.d.ts +1 -0
- package/dist/commands/reduce/targets.js +48 -2
- package/dist/commands/shared/resolve-stage-competitors.js +4 -1
- package/dist/commands/verify/command.d.ts +1 -0
- package/dist/commands/verify/command.js +2 -1
- package/dist/commands/verify/max-parallel.d.ts +1 -1
- package/dist/commands/verify/max-parallel.js +3 -1
- package/dist/commands/verify/targets.d.ts +2 -1
- package/dist/commands/verify/targets.js +154 -22
- package/dist/configs/agents/defaults.js +25 -25
- package/dist/configs/orchestration/bootstrap.d.ts +6 -1
- package/dist/configs/orchestration/bootstrap.js +27 -6
- package/dist/configs/orchestration/types.d.ts +25 -10
- package/dist/configs/orchestration/types.js +10 -6
- package/dist/configs/verification/types.d.ts +5 -0
- package/dist/configs/verification/types.js +3 -0
- package/dist/contracts/list.d.ts +38 -4
- package/dist/contracts/list.js +30 -1
- package/dist/domain/message/competition/adapter.d.ts +36 -0
- package/dist/domain/message/competition/adapter.js +197 -0
- package/dist/domain/message/competition/prompt.d.ts +8 -0
- package/dist/domain/message/competition/prompt.js +29 -0
- package/dist/domain/message/model/mutators.d.ts +17 -0
- package/dist/domain/message/model/mutators.js +107 -0
- package/dist/domain/message/model/types.d.ts +100 -0
- package/dist/domain/message/model/types.js +87 -0
- package/dist/domain/message/persistence/adapter.d.ts +43 -0
- package/dist/domain/message/persistence/adapter.js +124 -0
- package/dist/domain/reduce/competition/adapter.d.ts +1 -0
- package/dist/domain/reduce/competition/adapter.js +57 -4
- package/dist/domain/reduce/competition/prompt.d.ts +1 -1
- package/dist/domain/reduce/model/types.d.ts +3 -0
- package/dist/domain/reduce/model/types.js +2 -1
- package/dist/domain/verify/competition/adapter.js +8 -5
- package/dist/domain/verify/competition/programmatic.js +3 -0
- package/dist/domain/verify/competition/prompt.js +6 -0
- package/dist/domain/verify/competition/rubric.js +7 -1
- package/dist/domain/verify/competition/shared-layout.d.ts +42 -2
- package/dist/domain/verify/competition/shared-layout.js +92 -21
- package/dist/domain/verify/competition/target.d.ts +17 -0
- package/dist/domain/verify/model/types.d.ts +20 -2
- package/dist/domain/verify/model/types.js +15 -2
- package/dist/mcp/server.d.ts +2 -2
- package/dist/mcp/server.js +30 -13
- package/dist/policy/verification.js +2 -0
- package/dist/preflight/index.d.ts +2 -0
- package/dist/preflight/index.js +3 -1
- package/dist/render/transcripts/list.d.ts +2 -0
- package/dist/render/transcripts/list.js +24 -0
- package/dist/render/transcripts/message.d.ts +72 -0
- package/dist/render/transcripts/message.js +362 -0
- package/dist/render/transcripts/stage-progress.d.ts +1 -1
- package/dist/render/transcripts/verify.d.ts +4 -0
- package/dist/render/transcripts/verify.js +7 -1
- package/dist/render/utils/transcript-shell.d.ts +1 -1
- package/dist/render/utils/transcript-shell.js +6 -0
- package/dist/status/index.d.ts +21 -0
- package/dist/status/index.js +30 -0
- package/dist/workspace/setup.js +13 -7
- package/dist/workspace/structure.d.ts +14 -6
- package/dist/workspace/structure.js +25 -9
- package/dist/workspace/verification-defaults.d.ts +1 -1
- package/dist/workspace/verification-defaults.js +255 -0
- package/package.json +15 -16
package/dist/contracts/list.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
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>;
|
package/dist/contracts/list.js
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
export const listOperators = [
|
|
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
|
+
}
|