replicas-engine 0.1.217 → 0.1.219
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/src/index.js +478 -322
- package/package.json +1 -1
package/dist/src/index.js
CHANGED
|
@@ -34,6 +34,7 @@ function codexReasoningEffortForThinkingLevel(thinkingLevel) {
|
|
|
34
34
|
// ../shared/src/event.ts
|
|
35
35
|
var CODEX_QUOTA_STATUS_EVENT_TYPE = "codex-quota-status";
|
|
36
36
|
var COMPACTION_STATUS_EVENT_TYPE = "compaction-status";
|
|
37
|
+
var CHAT_GOAL_EVENT_TYPE = "chat-goal";
|
|
37
38
|
var CONTEXT_USAGE_EVENT_TYPE = "context-usage";
|
|
38
39
|
|
|
39
40
|
// ../shared/src/languages.ts
|
|
@@ -1628,6 +1629,15 @@ var DEFAULT_DEFAULT_SKILLS = {
|
|
|
1628
1629
|
}
|
|
1629
1630
|
};
|
|
1630
1631
|
|
|
1632
|
+
// ../shared/src/prompts.ts
|
|
1633
|
+
function parseGoalCommand(message) {
|
|
1634
|
+
const match = message.trim().match(/^\/goal(?:\s+([\s\S]*))?$/i);
|
|
1635
|
+
const value = match?.[1]?.trim();
|
|
1636
|
+
if (!value) return null;
|
|
1637
|
+
if (/^(clear|reset|unset)$/i.test(value)) return { type: "clear" };
|
|
1638
|
+
return { type: "set", objective: value };
|
|
1639
|
+
}
|
|
1640
|
+
|
|
1631
1641
|
// ../shared/src/replicas-config.ts
|
|
1632
1642
|
import { parse as parseYaml } from "yaml";
|
|
1633
1643
|
|
|
@@ -1749,7 +1759,7 @@ function parseReplicasConfigString(content, filename) {
|
|
|
1749
1759
|
}
|
|
1750
1760
|
|
|
1751
1761
|
// ../shared/src/engine/environment.ts
|
|
1752
|
-
var DAYTONA_SNAPSHOT_ID = "
|
|
1762
|
+
var DAYTONA_SNAPSHOT_ID = "27-05-2026-royal-york-v1";
|
|
1753
1763
|
|
|
1754
1764
|
// ../shared/src/engine/types.ts
|
|
1755
1765
|
var DEFAULT_CHAT_TITLES = {
|
|
@@ -6069,25 +6079,17 @@ async function restartCodexAspHost() {
|
|
|
6069
6079
|
}
|
|
6070
6080
|
}
|
|
6071
6081
|
|
|
6072
|
-
// src/managers/codex-asp/
|
|
6082
|
+
// src/managers/codex-asp/mappers.ts
|
|
6073
6083
|
var DEFAULT_MODEL2 = "gpt-5.5";
|
|
6074
6084
|
var THREAD_START_METHOD = "thread/start";
|
|
6075
6085
|
var THREAD_RESUME_METHOD = "thread/resume";
|
|
6076
6086
|
var THREAD_READ_METHOD = "thread/read";
|
|
6087
|
+
var THREAD_GOAL_SET_METHOD = "thread/goal/set";
|
|
6088
|
+
var THREAD_GOAL_GET_METHOD = "thread/goal/get";
|
|
6089
|
+
var THREAD_GOAL_CLEAR_METHOD = "thread/goal/clear";
|
|
6077
6090
|
var TURN_START_METHOD = "turn/start";
|
|
6078
6091
|
var TURN_INTERRUPT_METHOD = "turn/interrupt";
|
|
6079
6092
|
var ACCOUNT_RATE_LIMITS_READ_METHOD = "account/rateLimits/read";
|
|
6080
|
-
var TURN_STARTED_METHOD = "turn/started";
|
|
6081
|
-
var TURN_COMPLETED_METHOD = "turn/completed";
|
|
6082
|
-
var TURN_PLAN_UPDATED_METHOD = "turn/plan/updated";
|
|
6083
|
-
var ITEM_STARTED_METHOD = "item/started";
|
|
6084
|
-
var ITEM_COMPLETED_METHOD = "item/completed";
|
|
6085
|
-
var AGENT_MESSAGE_DELTA_METHOD = "item/agentMessage/delta";
|
|
6086
|
-
var ACCOUNT_RATE_LIMITS_UPDATED_METHOD = "account/rateLimits/updated";
|
|
6087
|
-
var THREAD_TOKEN_USAGE_UPDATED_METHOD = "thread/tokenUsage/updated";
|
|
6088
|
-
var THREAD_COMPACTED_METHOD = "thread/compacted";
|
|
6089
|
-
var COMMAND_APPROVAL_METHOD = "item/commandExecution/requestApproval";
|
|
6090
|
-
var FILE_CHANGE_APPROVAL_METHOD = "item/fileChange/requestApproval";
|
|
6091
6093
|
function toReasoningEffort(thinkingLevel) {
|
|
6092
6094
|
return codexReasoningEffortForThinkingLevel(thinkingLevel);
|
|
6093
6095
|
}
|
|
@@ -6104,6 +6106,278 @@ function extractRateLimitsSnapshot(rateLimits) {
|
|
|
6104
6106
|
function timestampFromSeconds(value) {
|
|
6105
6107
|
return new Date((value ?? Date.now() / 1e3) * 1e3).toISOString();
|
|
6106
6108
|
}
|
|
6109
|
+
function aspGoalToChatGoal(goal) {
|
|
6110
|
+
return {
|
|
6111
|
+
threadId: goal.threadId,
|
|
6112
|
+
objective: goal.objective,
|
|
6113
|
+
status: goal.status,
|
|
6114
|
+
tokenBudget: goal.tokenBudget,
|
|
6115
|
+
tokensUsed: goal.tokensUsed,
|
|
6116
|
+
timeUsedSeconds: goal.timeUsedSeconds,
|
|
6117
|
+
createdAt: timestampFromSeconds(goal.createdAt),
|
|
6118
|
+
updatedAt: timestampFromSeconds(goal.updatedAt)
|
|
6119
|
+
};
|
|
6120
|
+
}
|
|
6121
|
+
function formatTurnFailure(turn) {
|
|
6122
|
+
const turnError = turn.error;
|
|
6123
|
+
if (!turnError) {
|
|
6124
|
+
return "Codex ASP turn failed without error details";
|
|
6125
|
+
}
|
|
6126
|
+
const parts = [`Codex ASP turn failed: ${turnError.message}`];
|
|
6127
|
+
if (turnError.codexErrorInfo !== null) {
|
|
6128
|
+
parts.push(`codexErrorInfo=${JSON.stringify(turnError.codexErrorInfo)}`);
|
|
6129
|
+
}
|
|
6130
|
+
if (turnError.additionalDetails) {
|
|
6131
|
+
parts.push(`details=${turnError.additionalDetails}`);
|
|
6132
|
+
}
|
|
6133
|
+
return parts.join(" ");
|
|
6134
|
+
}
|
|
6135
|
+
function formatCommandOutput(item) {
|
|
6136
|
+
const exitCode = item.exitCode ?? (item.status === "completed" ? 0 : 1);
|
|
6137
|
+
const output = item.aggregatedOutput ?? "";
|
|
6138
|
+
return output ? `Exit code: ${exitCode}
|
|
6139
|
+
${output}` : `Exit code: ${exitCode}`;
|
|
6140
|
+
}
|
|
6141
|
+
function fileChangeToPatchInput(item) {
|
|
6142
|
+
const lines = ["*** Begin Patch"];
|
|
6143
|
+
for (const change of item.changes) {
|
|
6144
|
+
if (change.kind.type === "add") {
|
|
6145
|
+
lines.push(`*** Add File: ${change.path}`);
|
|
6146
|
+
} else if (change.kind.type === "delete") {
|
|
6147
|
+
lines.push(`*** Delete File: ${change.path}`);
|
|
6148
|
+
} else {
|
|
6149
|
+
lines.push(`*** Update File: ${change.path}`);
|
|
6150
|
+
if (change.kind.move_path) {
|
|
6151
|
+
lines.push(`*** Move to: ${change.kind.move_path}`);
|
|
6152
|
+
}
|
|
6153
|
+
}
|
|
6154
|
+
if (change.diff.trim().length > 0) {
|
|
6155
|
+
lines.push(change.diff);
|
|
6156
|
+
}
|
|
6157
|
+
}
|
|
6158
|
+
lines.push("*** End Patch");
|
|
6159
|
+
return lines.join("\n");
|
|
6160
|
+
}
|
|
6161
|
+
function itemToAgentEventDrafts(item, lifecycle) {
|
|
6162
|
+
if (item.type === "agentMessage") {
|
|
6163
|
+
if (lifecycle !== "completed" || !item.text) return [];
|
|
6164
|
+
return [{
|
|
6165
|
+
type: "response_item",
|
|
6166
|
+
payload: {
|
|
6167
|
+
type: "message",
|
|
6168
|
+
role: "assistant",
|
|
6169
|
+
content: [{
|
|
6170
|
+
type: "output_text",
|
|
6171
|
+
text: item.text
|
|
6172
|
+
}]
|
|
6173
|
+
}
|
|
6174
|
+
}];
|
|
6175
|
+
}
|
|
6176
|
+
if (item.type === "reasoning") {
|
|
6177
|
+
if (lifecycle !== "completed") return [];
|
|
6178
|
+
const text = [...item.summary, ...item.content].filter(Boolean).join("\n").trim();
|
|
6179
|
+
if (!text) return [];
|
|
6180
|
+
return [{
|
|
6181
|
+
type: "event_msg",
|
|
6182
|
+
payload: {
|
|
6183
|
+
type: "agent_reasoning",
|
|
6184
|
+
text
|
|
6185
|
+
}
|
|
6186
|
+
}];
|
|
6187
|
+
}
|
|
6188
|
+
if (item.type === "commandExecution") {
|
|
6189
|
+
if (lifecycle === "started") {
|
|
6190
|
+
return [{
|
|
6191
|
+
type: "response_item",
|
|
6192
|
+
payload: {
|
|
6193
|
+
type: "function_call",
|
|
6194
|
+
name: "exec_command",
|
|
6195
|
+
call_id: item.id,
|
|
6196
|
+
arguments: JSON.stringify({ cmd: item.command })
|
|
6197
|
+
}
|
|
6198
|
+
}];
|
|
6199
|
+
}
|
|
6200
|
+
return [{
|
|
6201
|
+
type: "response_item",
|
|
6202
|
+
payload: {
|
|
6203
|
+
type: "function_call_output",
|
|
6204
|
+
call_id: item.id,
|
|
6205
|
+
output: formatCommandOutput(item)
|
|
6206
|
+
}
|
|
6207
|
+
}];
|
|
6208
|
+
}
|
|
6209
|
+
if (item.type === "fileChange") {
|
|
6210
|
+
if (lifecycle === "started") {
|
|
6211
|
+
return [{
|
|
6212
|
+
type: "response_item",
|
|
6213
|
+
payload: {
|
|
6214
|
+
type: "custom_tool_call",
|
|
6215
|
+
name: "apply_patch",
|
|
6216
|
+
call_id: item.id,
|
|
6217
|
+
input: fileChangeToPatchInput(item),
|
|
6218
|
+
status: "in_progress"
|
|
6219
|
+
}
|
|
6220
|
+
}];
|
|
6221
|
+
}
|
|
6222
|
+
return [{
|
|
6223
|
+
type: "response_item",
|
|
6224
|
+
payload: {
|
|
6225
|
+
type: "custom_tool_call_output",
|
|
6226
|
+
call_id: item.id,
|
|
6227
|
+
output: JSON.stringify({
|
|
6228
|
+
output: item.status,
|
|
6229
|
+
metadata: { exit_code: item.status === "completed" ? 0 : 1 }
|
|
6230
|
+
})
|
|
6231
|
+
}
|
|
6232
|
+
}];
|
|
6233
|
+
}
|
|
6234
|
+
if (item.type === "mcpToolCall" || item.type === "dynamicToolCall" || item.type === "webSearch") {
|
|
6235
|
+
const tool2 = item.type === "webSearch" ? "web_search" : item.tool;
|
|
6236
|
+
const input = item.type === "webSearch" ? item.query : JSON.stringify(item.arguments);
|
|
6237
|
+
if (lifecycle === "started") {
|
|
6238
|
+
return [{
|
|
6239
|
+
type: "response_item",
|
|
6240
|
+
payload: {
|
|
6241
|
+
type: "custom_tool_call",
|
|
6242
|
+
name: tool2,
|
|
6243
|
+
call_id: item.id,
|
|
6244
|
+
input,
|
|
6245
|
+
status: "in_progress"
|
|
6246
|
+
}
|
|
6247
|
+
}];
|
|
6248
|
+
}
|
|
6249
|
+
const failed = item.type === "mcpToolCall" && item.status === "failed" || item.type === "dynamicToolCall" && item.success === false;
|
|
6250
|
+
return [{
|
|
6251
|
+
type: "response_item",
|
|
6252
|
+
payload: {
|
|
6253
|
+
type: "custom_tool_call_output",
|
|
6254
|
+
call_id: item.id,
|
|
6255
|
+
output: JSON.stringify({
|
|
6256
|
+
output: failed ? "Failed" : "Done",
|
|
6257
|
+
metadata: { exit_code: failed ? 1 : 0 }
|
|
6258
|
+
})
|
|
6259
|
+
}
|
|
6260
|
+
}];
|
|
6261
|
+
}
|
|
6262
|
+
return [];
|
|
6263
|
+
}
|
|
6264
|
+
function threadToHistoryEvents(thread) {
|
|
6265
|
+
const events = [];
|
|
6266
|
+
for (const turn of thread.turns) {
|
|
6267
|
+
const startedAt = timestampFromSeconds(turn.startedAt);
|
|
6268
|
+
const completedAt = timestampFromSeconds(turn.completedAt ?? turn.startedAt);
|
|
6269
|
+
for (const item of turn.items) {
|
|
6270
|
+
if (item.type === "userMessage") {
|
|
6271
|
+
const message = item.content.filter((input) => input.type === "text").map((input) => input.text).join("\n");
|
|
6272
|
+
if (message) {
|
|
6273
|
+
events.push({
|
|
6274
|
+
timestamp: startedAt,
|
|
6275
|
+
type: "event_msg",
|
|
6276
|
+
payload: { type: "user_message", message }
|
|
6277
|
+
});
|
|
6278
|
+
}
|
|
6279
|
+
continue;
|
|
6280
|
+
}
|
|
6281
|
+
for (const draft of itemToAgentEventDrafts(item, "started")) {
|
|
6282
|
+
events.push({ timestamp: startedAt, ...draft });
|
|
6283
|
+
}
|
|
6284
|
+
for (const draft of itemToAgentEventDrafts(item, "completed")) {
|
|
6285
|
+
events.push({ timestamp: completedAt, ...draft });
|
|
6286
|
+
}
|
|
6287
|
+
}
|
|
6288
|
+
}
|
|
6289
|
+
return events;
|
|
6290
|
+
}
|
|
6291
|
+
async function buildThreadStartParams(workingDirectory, request, developerInstructions) {
|
|
6292
|
+
const additionalDirectories = await getAgentAdditionalDirectories();
|
|
6293
|
+
return {
|
|
6294
|
+
model: request.model ?? DEFAULT_MODEL2,
|
|
6295
|
+
cwd: workingDirectory,
|
|
6296
|
+
runtimeWorkspaceRoots: additionalDirectories,
|
|
6297
|
+
sandbox: "danger-full-access",
|
|
6298
|
+
developerInstructions: developerInstructions ?? null,
|
|
6299
|
+
config: { web_search: "live" },
|
|
6300
|
+
experimentalRawEvents: false,
|
|
6301
|
+
persistExtendedHistory: false
|
|
6302
|
+
};
|
|
6303
|
+
}
|
|
6304
|
+
async function buildThreadResumeParams(workingDirectory, threadId, request, developerInstructions) {
|
|
6305
|
+
const additionalDirectories = await getAgentAdditionalDirectories();
|
|
6306
|
+
return {
|
|
6307
|
+
threadId,
|
|
6308
|
+
model: request.model ?? DEFAULT_MODEL2,
|
|
6309
|
+
cwd: workingDirectory,
|
|
6310
|
+
runtimeWorkspaceRoots: additionalDirectories,
|
|
6311
|
+
sandbox: "danger-full-access",
|
|
6312
|
+
developerInstructions: developerInstructions ?? null,
|
|
6313
|
+
config: { web_search: "live" },
|
|
6314
|
+
excludeTurns: false,
|
|
6315
|
+
persistExtendedHistory: false
|
|
6316
|
+
};
|
|
6317
|
+
}
|
|
6318
|
+
async function buildTurnInput(request) {
|
|
6319
|
+
const input = [{
|
|
6320
|
+
type: "text",
|
|
6321
|
+
text: request.message,
|
|
6322
|
+
text_elements: []
|
|
6323
|
+
}];
|
|
6324
|
+
if (!request.images || request.images.length === 0) {
|
|
6325
|
+
return { input, tempImagePaths: [] };
|
|
6326
|
+
}
|
|
6327
|
+
const normalizedImages = await normalizeImages(request.images);
|
|
6328
|
+
const tempImagePaths = await saveNormalizedImagesToTempFiles(normalizedImages);
|
|
6329
|
+
input.push(...tempImagePaths.map((path4) => ({
|
|
6330
|
+
type: "localImage",
|
|
6331
|
+
path: path4
|
|
6332
|
+
})));
|
|
6333
|
+
return { input, tempImagePaths };
|
|
6334
|
+
}
|
|
6335
|
+
async function buildTurnStartParams(threadId, request, developerInstructions) {
|
|
6336
|
+
const effort = toReasoningEffort(request.thinkingLevel);
|
|
6337
|
+
const model = request.model ?? DEFAULT_MODEL2;
|
|
6338
|
+
const { input, tempImagePaths } = await buildTurnInput(request);
|
|
6339
|
+
return {
|
|
6340
|
+
params: {
|
|
6341
|
+
threadId,
|
|
6342
|
+
input,
|
|
6343
|
+
model,
|
|
6344
|
+
...effort ? { effort } : {},
|
|
6345
|
+
...developerInstructions ? {
|
|
6346
|
+
collaborationMode: {
|
|
6347
|
+
mode: "default",
|
|
6348
|
+
settings: {
|
|
6349
|
+
model,
|
|
6350
|
+
reasoning_effort: effort ?? null,
|
|
6351
|
+
developer_instructions: developerInstructions
|
|
6352
|
+
}
|
|
6353
|
+
}
|
|
6354
|
+
} : {}
|
|
6355
|
+
},
|
|
6356
|
+
tempImagePaths
|
|
6357
|
+
};
|
|
6358
|
+
}
|
|
6359
|
+
|
|
6360
|
+
// src/managers/codex-asp/notification-dispatch.ts
|
|
6361
|
+
var TURN_STARTED_METHOD = "turn/started";
|
|
6362
|
+
var TURN_COMPLETED_METHOD = "turn/completed";
|
|
6363
|
+
var TURN_PLAN_UPDATED_METHOD = "turn/plan/updated";
|
|
6364
|
+
var THREAD_GOAL_UPDATED_METHOD = "thread/goal/updated";
|
|
6365
|
+
var THREAD_GOAL_CLEARED_METHOD = "thread/goal/cleared";
|
|
6366
|
+
var ITEM_STARTED_METHOD = "item/started";
|
|
6367
|
+
var ITEM_COMPLETED_METHOD = "item/completed";
|
|
6368
|
+
var AGENT_MESSAGE_DELTA_METHOD = "item/agentMessage/delta";
|
|
6369
|
+
var ACCOUNT_RATE_LIMITS_UPDATED_METHOD = "account/rateLimits/updated";
|
|
6370
|
+
var THREAD_TOKEN_USAGE_UPDATED_METHOD = "thread/tokenUsage/updated";
|
|
6371
|
+
var THREAD_COMPACTED_METHOD = "thread/compacted";
|
|
6372
|
+
var COMMAND_APPROVAL_METHOD = "item/commandExecution/requestApproval";
|
|
6373
|
+
var FILE_CHANGE_APPROVAL_METHOD = "item/fileChange/requestApproval";
|
|
6374
|
+
function dispatchAspNotification(notification, handlers) {
|
|
6375
|
+
const handler = handlers[notification.method];
|
|
6376
|
+
if (!handler) return;
|
|
6377
|
+
handler(notification);
|
|
6378
|
+
}
|
|
6379
|
+
|
|
6380
|
+
// src/managers/codex-asp/codex-asp-manager.ts
|
|
6107
6381
|
var CodexAspManager = class extends CodingAgentManager {
|
|
6108
6382
|
currentThreadId = null;
|
|
6109
6383
|
activeTurnId = null;
|
|
@@ -6111,6 +6385,7 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6111
6385
|
historyEvents = [];
|
|
6112
6386
|
emittedItemStages = /* @__PURE__ */ new Set();
|
|
6113
6387
|
quotaStatus = new CodexQuotaStatusTracker();
|
|
6388
|
+
currentGoal = null;
|
|
6114
6389
|
constructor(options) {
|
|
6115
6390
|
super(options);
|
|
6116
6391
|
this.initializeManager(this.processMessageInternal.bind(this));
|
|
@@ -6137,48 +6412,72 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6137
6412
|
}
|
|
6138
6413
|
async getHistory() {
|
|
6139
6414
|
if (!this.currentThreadId) {
|
|
6140
|
-
return { thread_id: null, events: [] };
|
|
6415
|
+
return { thread_id: null, events: [], goal: null };
|
|
6141
6416
|
}
|
|
6142
6417
|
try {
|
|
6143
6418
|
const host = await getCodexAspHost();
|
|
6144
|
-
const response = await
|
|
6145
|
-
|
|
6146
|
-
|
|
6147
|
-
|
|
6148
|
-
|
|
6419
|
+
const [response] = await Promise.all([
|
|
6420
|
+
host.client.request(
|
|
6421
|
+
THREAD_READ_METHOD,
|
|
6422
|
+
{ threadId: this.currentThreadId, includeTurns: true }
|
|
6423
|
+
),
|
|
6424
|
+
this.refreshThreadGoal(host, this.currentThreadId)
|
|
6425
|
+
]);
|
|
6426
|
+
const events = threadToHistoryEvents(response.thread);
|
|
6149
6427
|
if (events.length > 0) {
|
|
6150
|
-
const supplementalEvents = this.historyEvents.filter((event) => event.type === CODEX_QUOTA_STATUS_EVENT_TYPE || event.type === CONTEXT_USAGE_EVENT_TYPE);
|
|
6428
|
+
const supplementalEvents = this.historyEvents.filter((event) => event.type === CODEX_QUOTA_STATUS_EVENT_TYPE || event.type === CONTEXT_USAGE_EVENT_TYPE || event.type === CHAT_GOAL_EVENT_TYPE || event.type === "event_msg" && event.payload.command === "goal");
|
|
6151
6429
|
return {
|
|
6152
6430
|
thread_id: this.currentThreadId,
|
|
6153
|
-
events: [...events, ...supplementalEvents].sort((a, b) => a.timestamp.localeCompare(b.timestamp))
|
|
6431
|
+
events: [...events, ...supplementalEvents].sort((a, b) => a.timestamp.localeCompare(b.timestamp)),
|
|
6432
|
+
goal: this.currentGoal
|
|
6154
6433
|
};
|
|
6155
6434
|
}
|
|
6156
6435
|
} catch {
|
|
6157
6436
|
}
|
|
6158
6437
|
return {
|
|
6159
6438
|
thread_id: this.currentThreadId,
|
|
6160
|
-
events: [...this.historyEvents]
|
|
6439
|
+
events: [...this.historyEvents],
|
|
6440
|
+
goal: this.currentGoal
|
|
6161
6441
|
};
|
|
6162
6442
|
}
|
|
6443
|
+
getGoal() {
|
|
6444
|
+
return this.currentGoal;
|
|
6445
|
+
}
|
|
6163
6446
|
async processMessageInternal(request) {
|
|
6164
6447
|
let userMessageRecorded = false;
|
|
6165
|
-
const recordUserMessage = () => {
|
|
6448
|
+
const recordUserMessage = (extraPayload = {}) => {
|
|
6166
6449
|
if (userMessageRecorded) return;
|
|
6167
6450
|
userMessageRecorded = true;
|
|
6168
6451
|
this.recordHistoryEvent("event_msg", {
|
|
6169
6452
|
type: "user_message",
|
|
6170
|
-
message: request.message
|
|
6453
|
+
message: request.message,
|
|
6454
|
+
...extraPayload
|
|
6171
6455
|
});
|
|
6172
6456
|
};
|
|
6173
|
-
|
|
6457
|
+
const goalCommand = parseGoalCommand(request.message);
|
|
6458
|
+
const dispatch = async () => {
|
|
6459
|
+
if (goalCommand?.type === "clear") {
|
|
6460
|
+
await this.executeGoalClearCommand(request, recordUserMessage);
|
|
6461
|
+
return;
|
|
6462
|
+
}
|
|
6463
|
+
if (goalCommand?.type === "set") {
|
|
6464
|
+
await this.executeAspTurn(request, recordUserMessage, {
|
|
6465
|
+
runTurn: (host, threadId) => this.runGoalTurn(host, threadId, request, goalCommand.objective),
|
|
6466
|
+
userMessagePayload: { command: "goal" }
|
|
6467
|
+
});
|
|
6468
|
+
return;
|
|
6469
|
+
}
|
|
6174
6470
|
await this.executeAspTurn(request, recordUserMessage);
|
|
6471
|
+
};
|
|
6472
|
+
try {
|
|
6473
|
+
await dispatch();
|
|
6175
6474
|
} catch (error) {
|
|
6176
6475
|
if (isCodexAuthError(error)) {
|
|
6177
6476
|
const refreshed = await codexTokenManager.fetchFreshCredentials(error instanceof Error ? error.message : String(error));
|
|
6178
6477
|
if (refreshed) {
|
|
6179
6478
|
await restartCodexAspHost();
|
|
6180
6479
|
this.threadAttached = false;
|
|
6181
|
-
await
|
|
6480
|
+
await dispatch();
|
|
6182
6481
|
return;
|
|
6183
6482
|
}
|
|
6184
6483
|
}
|
|
@@ -6188,22 +6487,34 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6188
6487
|
await this.onTurnComplete();
|
|
6189
6488
|
}
|
|
6190
6489
|
}
|
|
6191
|
-
async
|
|
6490
|
+
async executeGoalClearCommand(request, recordUserMessage) {
|
|
6491
|
+
const host = await getCodexAspHost();
|
|
6492
|
+
const developerInstructions = this.buildCombinedInstructions(request.customInstructions);
|
|
6493
|
+
const threadId = await this.ensureThread(host, request, developerInstructions);
|
|
6494
|
+
recordUserMessage({ command: "goal" });
|
|
6495
|
+
await host.client.request(
|
|
6496
|
+
THREAD_GOAL_CLEAR_METHOD,
|
|
6497
|
+
{ threadId }
|
|
6498
|
+
);
|
|
6499
|
+
this.recordGoalChange(null, true);
|
|
6500
|
+
}
|
|
6501
|
+
async executeAspTurn(request, recordUserMessage, options = {}) {
|
|
6192
6502
|
const host = await getCodexAspHost();
|
|
6193
6503
|
if (this.quotaStatus.blocked && this.quotaStatus.latestSnapshot) {
|
|
6194
6504
|
await this.refreshQuotaSnapshot(host);
|
|
6195
6505
|
if (this.quotaStatus.blocked && this.quotaStatus.latestSnapshot) {
|
|
6196
|
-
recordUserMessage();
|
|
6506
|
+
recordUserMessage(options.userMessagePayload);
|
|
6197
6507
|
this.emitQuotaStatus(this.quotaStatus.latestSnapshot, true);
|
|
6198
6508
|
return;
|
|
6199
6509
|
}
|
|
6200
6510
|
}
|
|
6201
6511
|
const developerInstructions = this.buildCombinedInstructions(request.customInstructions);
|
|
6202
6512
|
const threadId = await this.ensureThread(host, request, developerInstructions);
|
|
6203
|
-
recordUserMessage();
|
|
6513
|
+
recordUserMessage(options.userMessagePayload);
|
|
6514
|
+
const runTurn = options.runTurn ?? ((aspHost, aspThreadId, aspInstructions) => this.runTurn(aspHost, aspThreadId, request, aspInstructions));
|
|
6204
6515
|
let completedTurn;
|
|
6205
6516
|
try {
|
|
6206
|
-
completedTurn = await
|
|
6517
|
+
completedTurn = await runTurn(host, threadId, developerInstructions);
|
|
6207
6518
|
} catch (error) {
|
|
6208
6519
|
await this.refreshQuotaSnapshot(host);
|
|
6209
6520
|
if (this.quotaStatus.blocked) {
|
|
@@ -6216,7 +6527,7 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6216
6527
|
if (this.quotaStatus.blocked) {
|
|
6217
6528
|
return;
|
|
6218
6529
|
}
|
|
6219
|
-
throw new Error(
|
|
6530
|
+
throw new Error(formatTurnFailure(completedTurn));
|
|
6220
6531
|
}
|
|
6221
6532
|
if (completedTurn.status === "completed") {
|
|
6222
6533
|
this.emitTurnCompletedItems(completedTurn);
|
|
@@ -6227,7 +6538,7 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6227
6538
|
if (!this.threadAttached) {
|
|
6228
6539
|
const response = await host.client.request(
|
|
6229
6540
|
THREAD_RESUME_METHOD,
|
|
6230
|
-
await
|
|
6541
|
+
await buildThreadResumeParams(this.workingDirectory, this.currentThreadId, request, developerInstructions)
|
|
6231
6542
|
);
|
|
6232
6543
|
this.currentThreadId = response.thread.id;
|
|
6233
6544
|
this.threadAttached = true;
|
|
@@ -6238,82 +6549,34 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6238
6549
|
}
|
|
6239
6550
|
const threadStartResponse = await host.client.request(
|
|
6240
6551
|
THREAD_START_METHOD,
|
|
6241
|
-
await this.
|
|
6552
|
+
await buildThreadStartParams(this.workingDirectory, request, developerInstructions)
|
|
6242
6553
|
);
|
|
6243
6554
|
this.currentThreadId = threadStartResponse.thread.id;
|
|
6244
6555
|
this.threadAttached = true;
|
|
6245
6556
|
await this.onSaveSessionId(this.currentThreadId);
|
|
6246
6557
|
return this.currentThreadId;
|
|
6247
6558
|
}
|
|
6248
|
-
async
|
|
6249
|
-
const
|
|
6250
|
-
return {
|
|
6251
|
-
|
|
6252
|
-
|
|
6253
|
-
|
|
6254
|
-
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
experimentalRawEvents: false,
|
|
6258
|
-
persistExtendedHistory: false
|
|
6259
|
-
};
|
|
6260
|
-
}
|
|
6261
|
-
async buildThreadResumeParams(threadId, request, developerInstructions) {
|
|
6262
|
-
const additionalDirectories = await getAgentAdditionalDirectories();
|
|
6263
|
-
return {
|
|
6264
|
-
threadId,
|
|
6265
|
-
model: request.model ?? DEFAULT_MODEL2,
|
|
6266
|
-
cwd: this.workingDirectory,
|
|
6267
|
-
runtimeWorkspaceRoots: additionalDirectories,
|
|
6268
|
-
sandbox: "danger-full-access",
|
|
6269
|
-
developerInstructions: developerInstructions ?? null,
|
|
6270
|
-
config: { web_search: "live" },
|
|
6271
|
-
excludeTurns: false,
|
|
6272
|
-
persistExtendedHistory: false
|
|
6273
|
-
};
|
|
6274
|
-
}
|
|
6275
|
-
async buildTurnStartParams(threadId, request, developerInstructions) {
|
|
6276
|
-
const effort = toReasoningEffort(request.thinkingLevel);
|
|
6277
|
-
const model = request.model ?? DEFAULT_MODEL2;
|
|
6278
|
-
const { input, tempImagePaths } = await this.buildTurnInput(request);
|
|
6279
|
-
return {
|
|
6280
|
-
params: {
|
|
6281
|
-
threadId,
|
|
6282
|
-
input,
|
|
6283
|
-
model,
|
|
6284
|
-
...effort ? { effort } : {},
|
|
6285
|
-
...developerInstructions ? {
|
|
6286
|
-
collaborationMode: {
|
|
6287
|
-
mode: "default",
|
|
6288
|
-
settings: {
|
|
6289
|
-
model,
|
|
6290
|
-
reasoning_effort: effort ?? null,
|
|
6291
|
-
developer_instructions: developerInstructions
|
|
6292
|
-
}
|
|
6293
|
-
}
|
|
6294
|
-
} : {}
|
|
6295
|
-
},
|
|
6296
|
-
tempImagePaths
|
|
6297
|
-
};
|
|
6559
|
+
async runTurn(host, threadId, request, developerInstructions) {
|
|
6560
|
+
const { params, tempImagePaths } = await buildTurnStartParams(threadId, request, developerInstructions);
|
|
6561
|
+
return this.observeTurn(host, threadId, request, async () => {
|
|
6562
|
+
const turnStartResponse = await host.client.request(
|
|
6563
|
+
TURN_START_METHOD,
|
|
6564
|
+
params
|
|
6565
|
+
);
|
|
6566
|
+
return { turn: turnStartResponse.turn, tempImagePaths };
|
|
6567
|
+
});
|
|
6298
6568
|
}
|
|
6299
|
-
async
|
|
6300
|
-
|
|
6301
|
-
|
|
6302
|
-
|
|
6303
|
-
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
return {
|
|
6307
|
-
}
|
|
6308
|
-
const normalizedImages = await normalizeImages(request.images);
|
|
6309
|
-
const tempImagePaths = await saveNormalizedImagesToTempFiles(normalizedImages);
|
|
6310
|
-
input.push(...tempImagePaths.map((path4) => ({
|
|
6311
|
-
type: "localImage",
|
|
6312
|
-
path: path4
|
|
6313
|
-
})));
|
|
6314
|
-
return { input, tempImagePaths };
|
|
6569
|
+
async runGoalTurn(host, threadId, request, objective) {
|
|
6570
|
+
return this.observeTurn(host, threadId, request, async () => {
|
|
6571
|
+
const response = await host.client.request(
|
|
6572
|
+
THREAD_GOAL_SET_METHOD,
|
|
6573
|
+
{ threadId, objective, status: "active" }
|
|
6574
|
+
);
|
|
6575
|
+
this.recordGoalChange(response.goal, true);
|
|
6576
|
+
return { turn: null, tempImagePaths: [] };
|
|
6577
|
+
});
|
|
6315
6578
|
}
|
|
6316
|
-
async
|
|
6579
|
+
async observeTurn(host, threadId, request, startTurn) {
|
|
6317
6580
|
let resolveCompleted;
|
|
6318
6581
|
const completed = new Promise((resolve3) => {
|
|
6319
6582
|
resolveCompleted = resolve3;
|
|
@@ -6333,46 +6596,46 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6333
6596
|
let tempImagePaths = [];
|
|
6334
6597
|
const linearForwarder = new LinearEventForwarder(linearSessionId);
|
|
6335
6598
|
const matchesTurn = (notificationThreadId, notificationTurnId) => notificationThreadId === threadId && (!observedTurnId || notificationTurnId === null || notificationTurnId === observedTurnId);
|
|
6336
|
-
const
|
|
6337
|
-
|
|
6599
|
+
const handlers = {
|
|
6600
|
+
[ACCOUNT_RATE_LIMITS_UPDATED_METHOD]: (notification) => {
|
|
6338
6601
|
this.handleRateLimits(notification.params.rateLimits);
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
return;
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
|
|
6350
|
-
|
|
6351
|
-
|
|
6352
|
-
|
|
6353
|
-
|
|
6602
|
+
},
|
|
6603
|
+
[THREAD_TOKEN_USAGE_UPDATED_METHOD]: (notification) => {
|
|
6604
|
+
if (notification.params.threadId !== threadId) return;
|
|
6605
|
+
this.emitCodexTokenUsage(notification.params.tokenUsage, model);
|
|
6606
|
+
},
|
|
6607
|
+
[THREAD_GOAL_UPDATED_METHOD]: (notification) => {
|
|
6608
|
+
if (notification.params.threadId !== threadId) return;
|
|
6609
|
+
this.recordGoalChange(notification.params.goal);
|
|
6610
|
+
},
|
|
6611
|
+
[THREAD_GOAL_CLEARED_METHOD]: (notification) => {
|
|
6612
|
+
if (notification.params.threadId !== threadId) return;
|
|
6613
|
+
this.recordGoalChange(null);
|
|
6614
|
+
},
|
|
6615
|
+
[THREAD_COMPACTED_METHOD]: (notification) => {
|
|
6616
|
+
if (!matchesTurn(notification.params.threadId, notification.params.turnId)) return;
|
|
6617
|
+
this.setCompacting(false);
|
|
6618
|
+
},
|
|
6619
|
+
[TURN_STARTED_METHOD]: (notification) => {
|
|
6354
6620
|
if (notification.params.threadId !== threadId) return;
|
|
6355
6621
|
observedTurnId = notification.params.turn.id;
|
|
6356
6622
|
this.activeTurnId = notification.params.turn.id;
|
|
6357
6623
|
linearForwarder.sendEvent(convertCodexAspNotification(notification, linearSessionId ?? ""));
|
|
6358
|
-
|
|
6359
|
-
|
|
6360
|
-
if (notification.method === TURN_PLAN_UPDATED_METHOD) {
|
|
6624
|
+
},
|
|
6625
|
+
[TURN_PLAN_UPDATED_METHOD]: (notification) => {
|
|
6361
6626
|
if (!matchesTurn(notification.params.threadId, notification.params.turnId)) return;
|
|
6362
6627
|
this.emitPlanUpdate(notification.params.plan);
|
|
6363
6628
|
linearForwarder.sendPlan(extractPlanFromCodexAspNotification(notification));
|
|
6364
|
-
|
|
6365
|
-
|
|
6366
|
-
if (notification.method === ITEM_STARTED_METHOD) {
|
|
6629
|
+
},
|
|
6630
|
+
[ITEM_STARTED_METHOD]: (notification) => {
|
|
6367
6631
|
if (!matchesTurn(notification.params.threadId, notification.params.turnId)) return;
|
|
6368
6632
|
if (notification.params.item.type === "contextCompaction") {
|
|
6369
6633
|
this.setCompacting(true);
|
|
6370
6634
|
}
|
|
6371
6635
|
this.emitThreadItemLifecycle(notification.params.item, "started");
|
|
6372
6636
|
linearForwarder.sendEvent(convertCodexAspNotification(notification, linearSessionId ?? ""));
|
|
6373
|
-
|
|
6374
|
-
|
|
6375
|
-
if (notification.method === ITEM_COMPLETED_METHOD) {
|
|
6637
|
+
},
|
|
6638
|
+
[ITEM_COMPLETED_METHOD]: (notification) => {
|
|
6376
6639
|
if (!matchesTurn(notification.params.threadId, notification.params.turnId)) return;
|
|
6377
6640
|
completedItems.push(notification.params.item);
|
|
6378
6641
|
if (notification.params.item.type === "contextCompaction") {
|
|
@@ -6380,19 +6643,14 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6380
6643
|
}
|
|
6381
6644
|
this.emitThreadItemLifecycle(notification.params.item, "completed");
|
|
6382
6645
|
linearForwarder.sendEvent(convertCodexAspNotification(notification, linearSessionId ?? ""));
|
|
6383
|
-
|
|
6384
|
-
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
|
|
6388
|
-
|
|
6389
|
-
|
|
6390
|
-
return;
|
|
6391
|
-
}
|
|
6392
|
-
if (notification.method === TURN_COMPLETED_METHOD) {
|
|
6393
|
-
if (notification.params.threadId !== threadId) {
|
|
6394
|
-
return;
|
|
6395
|
-
}
|
|
6646
|
+
},
|
|
6647
|
+
[AGENT_MESSAGE_DELTA_METHOD]: (notification) => {
|
|
6648
|
+
if (!matchesTurn(notification.params.threadId, notification.params.turnId)) return;
|
|
6649
|
+
const currentText = agentMessageDeltas.get(notification.params.itemId) ?? "";
|
|
6650
|
+
agentMessageDeltas.set(notification.params.itemId, currentText + notification.params.delta);
|
|
6651
|
+
},
|
|
6652
|
+
[TURN_COMPLETED_METHOD]: (notification) => {
|
|
6653
|
+
if (notification.params.threadId !== threadId) return;
|
|
6396
6654
|
observedTurnId = notification.params.turn.id;
|
|
6397
6655
|
const turn = notification.params.turn;
|
|
6398
6656
|
const items = turn.items.length > 0 ? [...turn.items] : [];
|
|
@@ -6417,6 +6675,9 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6417
6675
|
resolveCompleted(items.length > 0 ? { ...turn, items, itemsView: "full" } : turn);
|
|
6418
6676
|
}
|
|
6419
6677
|
};
|
|
6678
|
+
const onNotification = (notification) => {
|
|
6679
|
+
dispatchAspNotification(notification, handlers);
|
|
6680
|
+
};
|
|
6420
6681
|
const onServerRequest = (serverRequest) => {
|
|
6421
6682
|
if (serverRequest.method !== COMMAND_APPROVAL_METHOD && serverRequest.method !== FILE_CHANGE_APPROVAL_METHOD) {
|
|
6422
6683
|
return;
|
|
@@ -6434,14 +6695,12 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6434
6695
|
host.client.on("serverRequest", onServerRequest);
|
|
6435
6696
|
host.client.on("dispose", onDispose);
|
|
6436
6697
|
try {
|
|
6437
|
-
const
|
|
6438
|
-
tempImagePaths =
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
observedTurnId = turnStartResponse.turn.id;
|
|
6444
|
-
this.activeTurnId = turnStartResponse.turn.id;
|
|
6698
|
+
const started = await startTurn();
|
|
6699
|
+
tempImagePaths = started.tempImagePaths;
|
|
6700
|
+
if (started.turn) {
|
|
6701
|
+
observedTurnId = started.turn.id;
|
|
6702
|
+
this.activeTurnId = started.turn.id;
|
|
6703
|
+
}
|
|
6445
6704
|
const turn = await Promise.race([completed, disposed]);
|
|
6446
6705
|
linearForwarder.flushThoughtAsResponse();
|
|
6447
6706
|
return turn;
|
|
@@ -6462,10 +6721,10 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6462
6721
|
}
|
|
6463
6722
|
if (lifecycle === "completed" && !this.emittedItemStages.has(`started:${item.id}`)) {
|
|
6464
6723
|
this.emittedItemStages.add(`started:${item.id}`);
|
|
6465
|
-
this.recordAndEmitDrafts(
|
|
6724
|
+
this.recordAndEmitDrafts(itemToAgentEventDrafts(item, "started"));
|
|
6466
6725
|
}
|
|
6467
6726
|
this.emittedItemStages.add(stageKey);
|
|
6468
|
-
this.recordAndEmitDrafts(
|
|
6727
|
+
this.recordAndEmitDrafts(itemToAgentEventDrafts(item, lifecycle));
|
|
6469
6728
|
}
|
|
6470
6729
|
emitTurnCompletedItems(turn) {
|
|
6471
6730
|
for (const item of turn.items) {
|
|
@@ -6484,141 +6743,34 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6484
6743
|
}
|
|
6485
6744
|
}]);
|
|
6486
6745
|
}
|
|
6487
|
-
itemToAgentEventDrafts(item, lifecycle) {
|
|
6488
|
-
if (item.type === "agentMessage") {
|
|
6489
|
-
if (lifecycle !== "completed" || !item.text) return [];
|
|
6490
|
-
return [{
|
|
6491
|
-
type: "response_item",
|
|
6492
|
-
payload: {
|
|
6493
|
-
type: "message",
|
|
6494
|
-
role: "assistant",
|
|
6495
|
-
content: [{
|
|
6496
|
-
type: "output_text",
|
|
6497
|
-
text: item.text
|
|
6498
|
-
}]
|
|
6499
|
-
}
|
|
6500
|
-
}];
|
|
6501
|
-
}
|
|
6502
|
-
if (item.type === "reasoning") {
|
|
6503
|
-
if (lifecycle !== "completed") return [];
|
|
6504
|
-
const text = [...item.summary, ...item.content].filter(Boolean).join("\n").trim();
|
|
6505
|
-
if (!text) return [];
|
|
6506
|
-
return [{
|
|
6507
|
-
type: "event_msg",
|
|
6508
|
-
payload: {
|
|
6509
|
-
type: "agent_reasoning",
|
|
6510
|
-
text
|
|
6511
|
-
}
|
|
6512
|
-
}];
|
|
6513
|
-
}
|
|
6514
|
-
if (item.type === "commandExecution") {
|
|
6515
|
-
if (lifecycle === "started") {
|
|
6516
|
-
return [{
|
|
6517
|
-
type: "response_item",
|
|
6518
|
-
payload: {
|
|
6519
|
-
type: "function_call",
|
|
6520
|
-
name: "exec_command",
|
|
6521
|
-
call_id: item.id,
|
|
6522
|
-
arguments: JSON.stringify({ cmd: item.command })
|
|
6523
|
-
}
|
|
6524
|
-
}];
|
|
6525
|
-
}
|
|
6526
|
-
return [{
|
|
6527
|
-
type: "response_item",
|
|
6528
|
-
payload: {
|
|
6529
|
-
type: "function_call_output",
|
|
6530
|
-
call_id: item.id,
|
|
6531
|
-
output: this.formatCommandOutput(item)
|
|
6532
|
-
}
|
|
6533
|
-
}];
|
|
6534
|
-
}
|
|
6535
|
-
if (item.type === "fileChange") {
|
|
6536
|
-
if (lifecycle === "started") {
|
|
6537
|
-
return [{
|
|
6538
|
-
type: "response_item",
|
|
6539
|
-
payload: {
|
|
6540
|
-
type: "custom_tool_call",
|
|
6541
|
-
name: "apply_patch",
|
|
6542
|
-
call_id: item.id,
|
|
6543
|
-
input: this.fileChangeToPatchInput(item),
|
|
6544
|
-
status: "in_progress"
|
|
6545
|
-
}
|
|
6546
|
-
}];
|
|
6547
|
-
}
|
|
6548
|
-
return [{
|
|
6549
|
-
type: "response_item",
|
|
6550
|
-
payload: {
|
|
6551
|
-
type: "custom_tool_call_output",
|
|
6552
|
-
call_id: item.id,
|
|
6553
|
-
output: JSON.stringify({
|
|
6554
|
-
output: item.status,
|
|
6555
|
-
metadata: { exit_code: item.status === "completed" ? 0 : 1 }
|
|
6556
|
-
})
|
|
6557
|
-
}
|
|
6558
|
-
}];
|
|
6559
|
-
}
|
|
6560
|
-
if (item.type === "mcpToolCall" || item.type === "dynamicToolCall" || item.type === "webSearch") {
|
|
6561
|
-
const tool2 = item.type === "webSearch" ? "web_search" : item.tool;
|
|
6562
|
-
const input = item.type === "webSearch" ? item.query : JSON.stringify(item.arguments);
|
|
6563
|
-
if (lifecycle === "started") {
|
|
6564
|
-
return [{
|
|
6565
|
-
type: "response_item",
|
|
6566
|
-
payload: {
|
|
6567
|
-
type: "custom_tool_call",
|
|
6568
|
-
name: tool2,
|
|
6569
|
-
call_id: item.id,
|
|
6570
|
-
input,
|
|
6571
|
-
status: "in_progress"
|
|
6572
|
-
}
|
|
6573
|
-
}];
|
|
6574
|
-
}
|
|
6575
|
-
const failed = item.type === "mcpToolCall" && item.status === "failed" || item.type === "dynamicToolCall" && item.success === false;
|
|
6576
|
-
return [{
|
|
6577
|
-
type: "response_item",
|
|
6578
|
-
payload: {
|
|
6579
|
-
type: "custom_tool_call_output",
|
|
6580
|
-
call_id: item.id,
|
|
6581
|
-
output: JSON.stringify({
|
|
6582
|
-
output: failed ? "Failed" : "Done",
|
|
6583
|
-
metadata: { exit_code: failed ? 1 : 0 }
|
|
6584
|
-
})
|
|
6585
|
-
}
|
|
6586
|
-
}];
|
|
6587
|
-
}
|
|
6588
|
-
return [];
|
|
6589
|
-
}
|
|
6590
|
-
threadToHistoryEvents(thread) {
|
|
6591
|
-
const events = [];
|
|
6592
|
-
for (const turn of thread.turns) {
|
|
6593
|
-
const startedAt = timestampFromSeconds(turn.startedAt);
|
|
6594
|
-
const completedAt = timestampFromSeconds(turn.completedAt ?? turn.startedAt);
|
|
6595
|
-
for (const item of turn.items) {
|
|
6596
|
-
if (item.type === "userMessage") {
|
|
6597
|
-
const message = item.content.filter((input) => input.type === "text").map((input) => input.text).join("\n");
|
|
6598
|
-
if (message) {
|
|
6599
|
-
events.push({
|
|
6600
|
-
timestamp: startedAt,
|
|
6601
|
-
type: "event_msg",
|
|
6602
|
-
payload: { type: "user_message", message }
|
|
6603
|
-
});
|
|
6604
|
-
}
|
|
6605
|
-
continue;
|
|
6606
|
-
}
|
|
6607
|
-
for (const draft of this.itemToAgentEventDrafts(item, "started")) {
|
|
6608
|
-
events.push({ timestamp: startedAt, ...draft });
|
|
6609
|
-
}
|
|
6610
|
-
for (const draft of this.itemToAgentEventDrafts(item, "completed")) {
|
|
6611
|
-
events.push({ timestamp: completedAt, ...draft });
|
|
6612
|
-
}
|
|
6613
|
-
}
|
|
6614
|
-
}
|
|
6615
|
-
return events;
|
|
6616
|
-
}
|
|
6617
6746
|
seedHistoryFromThread(thread) {
|
|
6618
|
-
const events =
|
|
6747
|
+
const events = threadToHistoryEvents(thread);
|
|
6619
6748
|
if (events.length === 0) return;
|
|
6620
6749
|
this.historyEvents.splice(0, this.historyEvents.length, ...events);
|
|
6621
6750
|
}
|
|
6751
|
+
async refreshThreadGoal(host, threadId) {
|
|
6752
|
+
try {
|
|
6753
|
+
const response = await host.client.request(
|
|
6754
|
+
THREAD_GOAL_GET_METHOD,
|
|
6755
|
+
{ threadId }
|
|
6756
|
+
);
|
|
6757
|
+
this.currentGoal = response.goal ? aspGoalToChatGoal(response.goal) : null;
|
|
6758
|
+
} catch (error) {
|
|
6759
|
+
console.warn("[CodexAspManager] Failed to read ASP thread goal:", error);
|
|
6760
|
+
}
|
|
6761
|
+
}
|
|
6762
|
+
recordGoalChange(goal, force = false) {
|
|
6763
|
+
const nextGoal = goal ? aspGoalToChatGoal(goal) : null;
|
|
6764
|
+
if (!force && JSON.stringify(this.currentGoal) === JSON.stringify(nextGoal)) {
|
|
6765
|
+
return;
|
|
6766
|
+
}
|
|
6767
|
+
this.currentGoal = nextGoal;
|
|
6768
|
+
const event = this.recordHistoryEvent(
|
|
6769
|
+
CHAT_GOAL_EVENT_TYPE,
|
|
6770
|
+
{ goal: nextGoal }
|
|
6771
|
+
);
|
|
6772
|
+
this.onEvent(event);
|
|
6773
|
+
}
|
|
6622
6774
|
recordAndEmitDrafts(drafts) {
|
|
6623
6775
|
for (const draft of drafts) {
|
|
6624
6776
|
const event = this.recordHistoryEvent(draft.type, draft.payload);
|
|
@@ -6675,46 +6827,6 @@ var CodexAspManager = class extends CodingAgentManager {
|
|
|
6675
6827
|
const event = this.emitContextUsage(payload);
|
|
6676
6828
|
this.historyEvents.push(event);
|
|
6677
6829
|
}
|
|
6678
|
-
formatCommandOutput(item) {
|
|
6679
|
-
const exitCode = item.exitCode ?? (item.status === "completed" ? 0 : 1);
|
|
6680
|
-
const output = item.aggregatedOutput ?? "";
|
|
6681
|
-
return output ? `Exit code: ${exitCode}
|
|
6682
|
-
${output}` : `Exit code: ${exitCode}`;
|
|
6683
|
-
}
|
|
6684
|
-
fileChangeToPatchInput(item) {
|
|
6685
|
-
const lines = ["*** Begin Patch"];
|
|
6686
|
-
for (const change of item.changes) {
|
|
6687
|
-
if (change.kind.type === "add") {
|
|
6688
|
-
lines.push(`*** Add File: ${change.path}`);
|
|
6689
|
-
} else if (change.kind.type === "delete") {
|
|
6690
|
-
lines.push(`*** Delete File: ${change.path}`);
|
|
6691
|
-
} else {
|
|
6692
|
-
lines.push(`*** Update File: ${change.path}`);
|
|
6693
|
-
if (change.kind.move_path) {
|
|
6694
|
-
lines.push(`*** Move to: ${change.kind.move_path}`);
|
|
6695
|
-
}
|
|
6696
|
-
}
|
|
6697
|
-
if (change.diff.trim().length > 0) {
|
|
6698
|
-
lines.push(change.diff);
|
|
6699
|
-
}
|
|
6700
|
-
}
|
|
6701
|
-
lines.push("*** End Patch");
|
|
6702
|
-
return lines.join("\n");
|
|
6703
|
-
}
|
|
6704
|
-
formatTurnFailure(turn) {
|
|
6705
|
-
const turnError = turn.error;
|
|
6706
|
-
if (!turnError) {
|
|
6707
|
-
return "Codex ASP turn failed without error details";
|
|
6708
|
-
}
|
|
6709
|
-
const parts = [`Codex ASP turn failed: ${turnError.message}`];
|
|
6710
|
-
if (turnError.codexErrorInfo !== null) {
|
|
6711
|
-
parts.push(`codexErrorInfo=${JSON.stringify(turnError.codexErrorInfo)}`);
|
|
6712
|
-
}
|
|
6713
|
-
if (turnError.additionalDetails) {
|
|
6714
|
-
parts.push(`details=${turnError.additionalDetails}`);
|
|
6715
|
-
}
|
|
6716
|
-
return parts.join(" ");
|
|
6717
|
-
}
|
|
6718
6830
|
};
|
|
6719
6831
|
|
|
6720
6832
|
// src/managers/relay-tools.ts
|
|
@@ -7579,6 +7691,7 @@ var ChatService = class {
|
|
|
7579
7691
|
return {
|
|
7580
7692
|
thread_id: history.thread_id,
|
|
7581
7693
|
events: history.events,
|
|
7694
|
+
goal: history.goal ?? chat.provider.getGoal?.() ?? null,
|
|
7582
7695
|
senders
|
|
7583
7696
|
};
|
|
7584
7697
|
}
|
|
@@ -7664,6 +7777,7 @@ var ChatService = class {
|
|
|
7664
7777
|
processing: chat.provider.isProcessing(),
|
|
7665
7778
|
awaitingInput: chat.provider.isAwaitingInput?.() ?? false,
|
|
7666
7779
|
isCompacting: chat.provider.isCompacting?.() ?? false,
|
|
7780
|
+
goal: chat.provider.getGoal?.() ?? null,
|
|
7667
7781
|
parentChatId: chat.persisted.parentChatId
|
|
7668
7782
|
};
|
|
7669
7783
|
}
|
|
@@ -7706,7 +7820,7 @@ var ChatService = class {
|
|
|
7706
7820
|
}
|
|
7707
7821
|
}).catch(() => {
|
|
7708
7822
|
});
|
|
7709
|
-
if (event.type === "replicas-tool-input-request" || event.type === "replicas-tool-input-resolved" || event.type === "compaction-status") {
|
|
7823
|
+
if (event.type === "replicas-tool-input-request" || event.type === "replicas-tool-input-resolved" || event.type === "compaction-status" || event.type === CHAT_GOAL_EVENT_TYPE) {
|
|
7710
7824
|
this.publish({
|
|
7711
7825
|
type: "chat.updated",
|
|
7712
7826
|
payload: { chat: this.toSummary(chat) }
|
|
@@ -8146,10 +8260,11 @@ import { join as join19 } from "path";
|
|
|
8146
8260
|
|
|
8147
8261
|
// src/services/warm-hook-logs-service.ts
|
|
8148
8262
|
import { createHash as createHash2 } from "crypto";
|
|
8149
|
-
import { mkdir as mkdir12, readFile as readFile11, writeFile as writeFile10, readdir as readdir5 } from "fs/promises";
|
|
8263
|
+
import { mkdir as mkdir12, readFile as readFile11, writeFile as writeFile10, readdir as readdir5, appendFile as appendFile6, unlink as unlink3 } from "fs/promises";
|
|
8150
8264
|
import { homedir as homedir15 } from "os";
|
|
8151
8265
|
import { join as join18 } from "path";
|
|
8152
8266
|
var LOGS_DIR2 = join18(homedir15(), ".replicas", "warm-hook-logs");
|
|
8267
|
+
var CURRENT_RUN_LOG = join18(LOGS_DIR2, "current-run.log");
|
|
8153
8268
|
function sanitizeFilename2(name) {
|
|
8154
8269
|
const safe = name.replace(/[^a-zA-Z0-9._-]/g, "_");
|
|
8155
8270
|
const hash = createHash2("sha256").update(name).digest("hex").slice(0, 8);
|
|
@@ -8233,6 +8348,26 @@ var WarmHookLogsService = class {
|
|
|
8233
8348
|
});
|
|
8234
8349
|
return logs;
|
|
8235
8350
|
}
|
|
8351
|
+
async resetCurrentRunLog() {
|
|
8352
|
+
await this.ensureDir();
|
|
8353
|
+
try {
|
|
8354
|
+
await unlink3(CURRENT_RUN_LOG);
|
|
8355
|
+
} catch (err) {
|
|
8356
|
+
if (err.code !== "ENOENT") throw err;
|
|
8357
|
+
}
|
|
8358
|
+
}
|
|
8359
|
+
async appendCurrentRunLog(chunk) {
|
|
8360
|
+
if (!chunk) return;
|
|
8361
|
+
await appendFile6(CURRENT_RUN_LOG, chunk, "utf-8");
|
|
8362
|
+
}
|
|
8363
|
+
async getCurrentRunLog() {
|
|
8364
|
+
try {
|
|
8365
|
+
return await readFile11(CURRENT_RUN_LOG, "utf-8");
|
|
8366
|
+
} catch (err) {
|
|
8367
|
+
if (err.code === "ENOENT") return null;
|
|
8368
|
+
throw err;
|
|
8369
|
+
}
|
|
8370
|
+
}
|
|
8236
8371
|
async getFullOutput(hookType, hookName) {
|
|
8237
8372
|
const filename = hookType === "global" ? globalFilename() : hookType === "environment" ? environmentFilename() : repoFilename2(hookName);
|
|
8238
8373
|
try {
|
|
@@ -8359,6 +8494,16 @@ async function executeHookScriptStreaming(params) {
|
|
|
8359
8494
|
});
|
|
8360
8495
|
}
|
|
8361
8496
|
async function runWarmHooksStreaming(params) {
|
|
8497
|
+
await warmHookLogsService.resetCurrentRunLog();
|
|
8498
|
+
const originalOnEvent = params.onEvent;
|
|
8499
|
+
const onEvent = (event) => {
|
|
8500
|
+
if (event.type === "output" && event.data) {
|
|
8501
|
+
void warmHookLogsService.appendCurrentRunLog(event.data).catch(() => {
|
|
8502
|
+
});
|
|
8503
|
+
}
|
|
8504
|
+
originalOnEvent(event);
|
|
8505
|
+
};
|
|
8506
|
+
params = { ...params, onEvent };
|
|
8362
8507
|
const outputBlocks = [];
|
|
8363
8508
|
const globalHook = (params.globalWarmHook ?? params.organizationWarmHook)?.trim();
|
|
8364
8509
|
const environmentHook = params.environmentWarmHook?.trim();
|
|
@@ -8952,6 +9097,17 @@ function createV1Routes(deps) {
|
|
|
8952
9097
|
);
|
|
8953
9098
|
}
|
|
8954
9099
|
});
|
|
9100
|
+
app2.get("/warm-hooks/current-run/log", async (c) => {
|
|
9101
|
+
try {
|
|
9102
|
+
const output = await warmHookLogsService.getCurrentRunLog();
|
|
9103
|
+
return c.json({ output: output ?? "" });
|
|
9104
|
+
} catch (error) {
|
|
9105
|
+
return c.json(
|
|
9106
|
+
jsonError("Failed to read current warm hook run log", error instanceof Error ? error.message : "Unknown error"),
|
|
9107
|
+
500
|
|
9108
|
+
);
|
|
9109
|
+
}
|
|
9110
|
+
});
|
|
8955
9111
|
app2.get("/warm-hooks/logs/:hookType/:hookName/full", async (c) => {
|
|
8956
9112
|
try {
|
|
8957
9113
|
const hookType = c.req.param("hookType");
|