@very_aq/codex-cli-web 0.0.1
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/LICENSE +21 -0
- package/README.md +228 -0
- package/README.zh-CN.md +228 -0
- package/package.json +38 -0
- package/server/dist/admin/userAdminRoutes.d.ts +7 -0
- package/server/dist/admin/userAdminRoutes.js +91 -0
- package/server/dist/admin/userAdminRoutes.js.map +1 -0
- package/server/dist/app.d.ts +22 -0
- package/server/dist/app.js +993 -0
- package/server/dist/app.js.map +1 -0
- package/server/dist/auth/adminInit.d.ts +41 -0
- package/server/dist/auth/adminInit.js +126 -0
- package/server/dist/auth/adminInit.js.map +1 -0
- package/server/dist/auth/bootstrapAdmin.d.ts +6 -0
- package/server/dist/auth/bootstrapAdmin.js +11 -0
- package/server/dist/auth/bootstrapAdmin.js.map +1 -0
- package/server/dist/auth/httpAuth.d.ts +16 -0
- package/server/dist/auth/httpAuth.js +31 -0
- package/server/dist/auth/httpAuth.js.map +1 -0
- package/server/dist/auth/password.d.ts +2 -0
- package/server/dist/auth/password.js +68 -0
- package/server/dist/auth/password.js.map +1 -0
- package/server/dist/auth/requireAdmin.d.ts +2 -0
- package/server/dist/auth/requireAdmin.js +14 -0
- package/server/dist/auth/requireAdmin.js.map +1 -0
- package/server/dist/auth/roles.d.ts +3 -0
- package/server/dist/auth/roles.js +13 -0
- package/server/dist/auth/roles.js.map +1 -0
- package/server/dist/auth/session.d.ts +24 -0
- package/server/dist/auth/session.js +127 -0
- package/server/dist/auth/session.js.map +1 -0
- package/server/dist/auth/sqlite/authDb.d.ts +18 -0
- package/server/dist/auth/sqlite/authDb.js +26 -0
- package/server/dist/auth/sqlite/authDb.js.map +1 -0
- package/server/dist/auth/sqlite/legacyImport.d.ts +22 -0
- package/server/dist/auth/sqlite/legacyImport.js +208 -0
- package/server/dist/auth/sqlite/legacyImport.js.map +1 -0
- package/server/dist/auth/sqlite/schema.d.ts +11 -0
- package/server/dist/auth/sqlite/schema.js +47 -0
- package/server/dist/auth/sqlite/schema.js.map +1 -0
- package/server/dist/auth/sqlite/sqliteUserStore.d.ts +12 -0
- package/server/dist/auth/sqlite/sqliteUserStore.js +194 -0
- package/server/dist/auth/sqlite/sqliteUserStore.js.map +1 -0
- package/server/dist/auth/userStore.d.ts +19 -0
- package/server/dist/auth/userStore.js +26 -0
- package/server/dist/auth/userStore.js.map +1 -0
- package/server/dist/auth/userTypes.d.ts +13 -0
- package/server/dist/auth/userTypes.js +3 -0
- package/server/dist/auth/userTypes.js.map +1 -0
- package/server/dist/chat/attachmentPathRedaction.d.ts +5 -0
- package/server/dist/chat/attachmentPathRedaction.js +67 -0
- package/server/dist/chat/attachmentPathRedaction.js.map +1 -0
- package/server/dist/chat/chatItemEnricher.d.ts +5 -0
- package/server/dist/chat/chatItemEnricher.js +40 -0
- package/server/dist/chat/chatItemEnricher.js.map +1 -0
- package/server/dist/chat/codexEventProjector.d.ts +33 -0
- package/server/dist/chat/codexEventProjector.js +482 -0
- package/server/dist/chat/codexEventProjector.js.map +1 -0
- package/server/dist/chat/contextUsageProjector.d.ts +10 -0
- package/server/dist/chat/contextUsageProjector.js +472 -0
- package/server/dist/chat/contextUsageProjector.js.map +1 -0
- package/server/dist/chat/fileChangeExtractor.d.ts +5 -0
- package/server/dist/chat/fileChangeExtractor.js +121 -0
- package/server/dist/chat/fileChangeExtractor.js.map +1 -0
- package/server/dist/chat/markdown/markdownAst.d.ts +5 -0
- package/server/dist/chat/markdown/markdownAst.js +154 -0
- package/server/dist/chat/markdown/markdownAst.js.map +1 -0
- package/server/dist/chat/systemToolCallSummary.d.ts +10 -0
- package/server/dist/chat/systemToolCallSummary.js +112 -0
- package/server/dist/chat/systemToolCallSummary.js.map +1 -0
- package/server/dist/chat/terminal/terminalPlainText.d.ts +14 -0
- package/server/dist/chat/terminal/terminalPlainText.js +139 -0
- package/server/dist/chat/terminal/terminalPlainText.js.map +1 -0
- package/server/dist/chat/textMetrics.d.ts +9 -0
- package/server/dist/chat/textMetrics.js +24 -0
- package/server/dist/chat/textMetrics.js.map +1 -0
- package/server/dist/chat/threadTurnsProjector.d.ts +12 -0
- package/server/dist/chat/threadTurnsProjector.js +292 -0
- package/server/dist/chat/threadTurnsProjector.js.map +1 -0
- package/server/dist/chat/todoPlanProjector.d.ts +8 -0
- package/server/dist/chat/todoPlanProjector.js +94 -0
- package/server/dist/chat/todoPlanProjector.js.map +1 -0
- package/server/dist/chat/todoPlanTypes.d.ts +21 -0
- package/server/dist/chat/todoPlanTypes.js +3 -0
- package/server/dist/chat/todoPlanTypes.js.map +1 -0
- package/server/dist/chat/types.d.ts +138 -0
- package/server/dist/chat/types.js +3 -0
- package/server/dist/chat/types.js.map +1 -0
- package/server/dist/cli/configArg.d.ts +21 -0
- package/server/dist/cli/configArg.js +70 -0
- package/server/dist/cli/configArg.js.map +1 -0
- package/server/dist/codex/appServerProcess.d.ts +24 -0
- package/server/dist/codex/appServerProcess.js +56 -0
- package/server/dist/codex/appServerProcess.js.map +1 -0
- package/server/dist/codex/cliArgs.d.ts +17 -0
- package/server/dist/codex/cliArgs.js +34 -0
- package/server/dist/codex/cliArgs.js.map +1 -0
- package/server/dist/codex/codexAppServer.d.ts +103 -0
- package/server/dist/codex/codexAppServer.js +206 -0
- package/server/dist/codex/codexAppServer.js.map +1 -0
- package/server/dist/codex/jsonl.d.ts +4 -0
- package/server/dist/codex/jsonl.js +23 -0
- package/server/dist/codex/jsonl.js.map +1 -0
- package/server/dist/codex/jsonrpc.d.ts +43 -0
- package/server/dist/codex/jsonrpc.js +96 -0
- package/server/dist/codex/jsonrpc.js.map +1 -0
- package/server/dist/config/serverConfig.d.ts +150 -0
- package/server/dist/config/serverConfig.js +64 -0
- package/server/dist/config/serverConfig.js.map +1 -0
- package/server/dist/env.d.ts +101 -0
- package/server/dist/env.js +523 -0
- package/server/dist/env.js.map +1 -0
- package/server/dist/history/http/historyRoutes.d.ts +18 -0
- package/server/dist/history/http/historyRoutes.js +67 -0
- package/server/dist/history/http/historyRoutes.js.map +1 -0
- package/server/dist/history/index.d.ts +24 -0
- package/server/dist/history/index.js +30 -0
- package/server/dist/history/index.js.map +1 -0
- package/server/dist/history/ingest/historyIngestService.d.ts +15 -0
- package/server/dist/history/ingest/historyIngestService.js +42 -0
- package/server/dist/history/ingest/historyIngestService.js.map +1 -0
- package/server/dist/history/projector/extractIds.d.ts +36 -0
- package/server/dist/history/projector/extractIds.js +111 -0
- package/server/dist/history/projector/extractIds.js.map +1 -0
- package/server/dist/history/projector/projectCodexEvent.d.ts +27 -0
- package/server/dist/history/projector/projectCodexEvent.js +845 -0
- package/server/dist/history/projector/projectCodexEvent.js.map +1 -0
- package/server/dist/history/query/historyQueryService.d.ts +34 -0
- package/server/dist/history/query/historyQueryService.js +170 -0
- package/server/dist/history/query/historyQueryService.js.map +1 -0
- package/server/dist/history/sqlite/schema.d.ts +11 -0
- package/server/dist/history/sqlite/schema.js +34 -0
- package/server/dist/history/sqlite/schema.js.map +1 -0
- package/server/dist/history/sqlite/sqliteHistoryStore.d.ts +69 -0
- package/server/dist/history/sqlite/sqliteHistoryStore.js +206 -0
- package/server/dist/history/sqlite/sqliteHistoryStore.js.map +1 -0
- package/server/dist/history/types.d.ts +29 -0
- package/server/dist/history/types.js +3 -0
- package/server/dist/history/types.js.map +1 -0
- package/server/dist/index.d.ts +1 -0
- package/server/dist/index.js +166 -0
- package/server/dist/index.js.map +1 -0
- package/server/dist/security/executionPolicy.d.ts +33 -0
- package/server/dist/security/executionPolicy.js +72 -0
- package/server/dist/security/executionPolicy.js.map +1 -0
- package/server/dist/security/origin.d.ts +11 -0
- package/server/dist/security/origin.js +40 -0
- package/server/dist/security/origin.js.map +1 -0
- package/server/dist/settings/sqliteUserSettingsStore.d.ts +12 -0
- package/server/dist/settings/sqliteUserSettingsStore.js +62 -0
- package/server/dist/settings/sqliteUserSettingsStore.js.map +1 -0
- package/server/dist/settings/userSettingsRoutes.d.ts +8 -0
- package/server/dist/settings/userSettingsRoutes.js +55 -0
- package/server/dist/settings/userSettingsRoutes.js.map +1 -0
- package/server/dist/settings/userSettingsStore.d.ts +19 -0
- package/server/dist/settings/userSettingsStore.js +26 -0
- package/server/dist/settings/userSettingsStore.js.map +1 -0
- package/server/dist/settings/userSettingsTypes.d.ts +70 -0
- package/server/dist/settings/userSettingsTypes.js +196 -0
- package/server/dist/settings/userSettingsTypes.js.map +1 -0
- package/server/dist/status/codexTaskTracker.d.ts +21 -0
- package/server/dist/status/codexTaskTracker.js +123 -0
- package/server/dist/status/codexTaskTracker.js.map +1 -0
- package/server/dist/status/threadContextUsage.d.ts +19 -0
- package/server/dist/status/threadContextUsage.js +229 -0
- package/server/dist/status/threadContextUsage.js.map +1 -0
- package/server/dist/threadList/threadListServerCache.d.ts +10 -0
- package/server/dist/threadList/threadListServerCache.js +42 -0
- package/server/dist/threadList/threadListServerCache.js.map +1 -0
- package/server/dist/tools/cwdSuggest.d.ts +11 -0
- package/server/dist/tools/cwdSuggest.js +128 -0
- package/server/dist/tools/cwdSuggest.js.map +1 -0
- package/server/dist/workspace/accessControl.d.ts +16 -0
- package/server/dist/workspace/accessControl.js +82 -0
- package/server/dist/workspace/accessControl.js.map +1 -0
- package/server/dist/workspace/sqliteUserWorkspaceStore.d.ts +12 -0
- package/server/dist/workspace/sqliteUserWorkspaceStore.js +82 -0
- package/server/dist/workspace/sqliteUserWorkspaceStore.js.map +1 -0
- package/server/dist/workspace/threadAccess.d.ts +19 -0
- package/server/dist/workspace/threadAccess.js +22 -0
- package/server/dist/workspace/threadAccess.js.map +1 -0
- package/server/dist/workspace/threadListVisibility.d.ts +25 -0
- package/server/dist/workspace/threadListVisibility.js +104 -0
- package/server/dist/workspace/threadListVisibility.js.map +1 -0
- package/server/dist/workspace/userWorkspaceRoutes.d.ts +7 -0
- package/server/dist/workspace/userWorkspaceRoutes.js +124 -0
- package/server/dist/workspace/userWorkspaceRoutes.js.map +1 -0
- package/server/dist/workspace/userWorkspaceStore.d.ts +12 -0
- package/server/dist/workspace/userWorkspaceStore.js +23 -0
- package/server/dist/workspace/userWorkspaceStore.js.map +1 -0
- package/server/dist/ws/socketIoBridge.d.ts +32 -0
- package/server/dist/ws/socketIoBridge.js +194 -0
- package/server/dist/ws/socketIoBridge.js.map +1 -0
- package/server/dist/ws/types.d.ts +113 -0
- package/server/dist/ws/types.js +3 -0
- package/server/dist/ws/types.js.map +1 -0
- package/server/dist/ws/wsHub.d.ts +119 -0
- package/server/dist/ws/wsHub.js +1259 -0
- package/server/dist/ws/wsHub.js.map +1 -0
- package/web/dist/assets/index-CY6cnwQz.js +174 -0
- package/web/dist/assets/index-DI7kJHr2.css +32 -0
- package/web/dist/favicon-mask.svg +9 -0
- package/web/dist/favicon.svg +26 -0
- package/web/dist/index.html +75 -0
|
@@ -0,0 +1,845 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.projectCodexEvent = projectCodexEvent;
|
|
4
|
+
const fileChangeExtractor_1 = require("../../chat/fileChangeExtractor");
|
|
5
|
+
const attachmentPathRedaction_1 = require("../../chat/attachmentPathRedaction");
|
|
6
|
+
const extractIds_1 = require("./extractIds");
|
|
7
|
+
/**
|
|
8
|
+
* 提取并归一化 `item/completed` 的 item.type,兼容 snake_case / 大小写差异。
|
|
9
|
+
*/
|
|
10
|
+
function resolveCompletedItemType(params) {
|
|
11
|
+
const rawItemType = String(params?.item?.type ?? params?.itemType ?? params?.item_type ?? "");
|
|
12
|
+
return rawItemType.trim().toLowerCase();
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* 聚合 commandExecution 的可展示文本,优先输出 aggregatedOutput。
|
|
16
|
+
*/
|
|
17
|
+
function buildCommandExecutionFinalText(params) {
|
|
18
|
+
const aggregatedOutput = String(params?.item?.aggregatedOutput ?? "");
|
|
19
|
+
if (aggregatedOutput)
|
|
20
|
+
return aggregatedOutput;
|
|
21
|
+
const fallbackText = String(params?.item?.text ?? "");
|
|
22
|
+
if (fallbackText)
|
|
23
|
+
return fallbackText;
|
|
24
|
+
return String(params?.item?.command ?? "");
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* 从 userMessage item 中提取可展示文本,并对附件路径做脱敏。
|
|
28
|
+
*/
|
|
29
|
+
function buildUserMessageFinalText(item) {
|
|
30
|
+
const it = item;
|
|
31
|
+
const directText = typeof it?.text === "string" ? it.text : "";
|
|
32
|
+
if (directText.trim())
|
|
33
|
+
return (0, attachmentPathRedaction_1.redactAttachmentPathsForDisplay)(directText.trim());
|
|
34
|
+
const directMessage = typeof it?.message === "string" ? it.message : "";
|
|
35
|
+
if (directMessage.trim())
|
|
36
|
+
return (0, attachmentPathRedaction_1.redactAttachmentPathsForDisplay)(directMessage.trim());
|
|
37
|
+
const parts = Array.isArray(it?.content)
|
|
38
|
+
? it.content
|
|
39
|
+
: Array.isArray(it?.contentItems)
|
|
40
|
+
? it.contentItems
|
|
41
|
+
: [];
|
|
42
|
+
const rawText = parts
|
|
43
|
+
.map((part) => {
|
|
44
|
+
const record = part;
|
|
45
|
+
if (typeof record === "string")
|
|
46
|
+
return record;
|
|
47
|
+
if (typeof record?.text === "string")
|
|
48
|
+
return record.text;
|
|
49
|
+
if (typeof record?.value === "string")
|
|
50
|
+
return record.value;
|
|
51
|
+
return "";
|
|
52
|
+
})
|
|
53
|
+
.filter(Boolean)
|
|
54
|
+
.join("")
|
|
55
|
+
.trim();
|
|
56
|
+
if (!rawText)
|
|
57
|
+
return "";
|
|
58
|
+
return (0, attachmentPathRedaction_1.redactAttachmentPathsForDisplay)(rawText);
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* 生成 fileChange 的最终展示文本,默认使用稳定标题。
|
|
62
|
+
*/
|
|
63
|
+
function buildFileChangeFinalText(params) {
|
|
64
|
+
const title = String(params?.item?.title ?? "").trim();
|
|
65
|
+
if (title)
|
|
66
|
+
return title;
|
|
67
|
+
const text = String(params?.item?.text ?? "").trim();
|
|
68
|
+
if (text)
|
|
69
|
+
return text;
|
|
70
|
+
return "文件变更";
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 归一化 summaryIndex,兼容非数字与负值输入。
|
|
74
|
+
*/
|
|
75
|
+
function normalizeSummaryIndex(rawSummaryIndex) {
|
|
76
|
+
const parsedSummaryIndex = Number(rawSummaryIndex);
|
|
77
|
+
if (!Number.isFinite(parsedSummaryIndex))
|
|
78
|
+
return 0;
|
|
79
|
+
return Math.max(0, Math.floor(parsedSummaryIndex));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* 将 reasoning completed 的 summary 数组展开为多条 done 消息。
|
|
83
|
+
*/
|
|
84
|
+
function buildReasoningCompletedMessages(threadId, turnId, itemId, params, nowMs) {
|
|
85
|
+
const summaryItems = Array.isArray(params?.item?.summary) ? params.item.summary : [];
|
|
86
|
+
const messages = [];
|
|
87
|
+
for (let summaryIndex = 0; summaryIndex < summaryItems.length; summaryIndex += 1) {
|
|
88
|
+
const finalText = String(summaryItems[summaryIndex] ?? "").trim();
|
|
89
|
+
if (!finalText)
|
|
90
|
+
continue;
|
|
91
|
+
const messageId = (0, extractIds_1.buildReasoningSummaryMessageId)(turnId, itemId, summaryIndex);
|
|
92
|
+
if (!messageId)
|
|
93
|
+
continue;
|
|
94
|
+
messages.push({
|
|
95
|
+
threadId,
|
|
96
|
+
messageId,
|
|
97
|
+
role: "reasoning",
|
|
98
|
+
messageType: "reasoning_summary",
|
|
99
|
+
status: "done",
|
|
100
|
+
finalText,
|
|
101
|
+
finishedAtMs: nowMs,
|
|
102
|
+
updatedAtMs: nowMs,
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
return messages;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 归一化计划步骤状态,兼容 camelCase / snake_case / done。
|
|
109
|
+
*/
|
|
110
|
+
function normalizePlanStepStatus(rawStatus) {
|
|
111
|
+
if (typeof rawStatus !== "string")
|
|
112
|
+
return null;
|
|
113
|
+
const normalizedStatus = rawStatus
|
|
114
|
+
.trim()
|
|
115
|
+
.replace(/([a-z])([A-Z])/g, "$1_$2")
|
|
116
|
+
.toLowerCase()
|
|
117
|
+
.replace(/[\s-]+/g, "_");
|
|
118
|
+
if (!normalizedStatus)
|
|
119
|
+
return null;
|
|
120
|
+
if (normalizedStatus === "pending")
|
|
121
|
+
return "pending";
|
|
122
|
+
if (normalizedStatus === "completed" || normalizedStatus === "done")
|
|
123
|
+
return "completed";
|
|
124
|
+
if (normalizedStatus === "in_progress" || normalizedStatus === "inprogress" || normalizedStatus === "doing")
|
|
125
|
+
return "in_progress";
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* 从未知结构中提取计划步骤文本。
|
|
130
|
+
*/
|
|
131
|
+
function extractPlanStepText(rawStep) {
|
|
132
|
+
if (typeof rawStep === "string")
|
|
133
|
+
return rawStep.trim();
|
|
134
|
+
if (!rawStep || typeof rawStep !== "object")
|
|
135
|
+
return "";
|
|
136
|
+
const stepRecord = rawStep;
|
|
137
|
+
const candidates = [
|
|
138
|
+
stepRecord.step,
|
|
139
|
+
stepRecord.text,
|
|
140
|
+
stepRecord.title,
|
|
141
|
+
stepRecord.description,
|
|
142
|
+
stepRecord.name,
|
|
143
|
+
stepRecord.task,
|
|
144
|
+
stepRecord.label,
|
|
145
|
+
];
|
|
146
|
+
for (const candidate of candidates) {
|
|
147
|
+
if (typeof candidate !== "string")
|
|
148
|
+
continue;
|
|
149
|
+
const normalizedStepText = candidate.trim();
|
|
150
|
+
if (normalizedStepText)
|
|
151
|
+
return normalizedStepText;
|
|
152
|
+
}
|
|
153
|
+
return "";
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* 从 `plan/steps/items` 字段中提取标准化步骤数组。
|
|
157
|
+
*/
|
|
158
|
+
function extractNormalizedPlanSteps(rawContainer) {
|
|
159
|
+
if (!rawContainer || typeof rawContainer !== "object")
|
|
160
|
+
return [];
|
|
161
|
+
const container = rawContainer;
|
|
162
|
+
const sources = [container.plan, container.steps, container.items];
|
|
163
|
+
const normalizedSteps = [];
|
|
164
|
+
for (const rawSource of sources) {
|
|
165
|
+
if (!Array.isArray(rawSource))
|
|
166
|
+
continue;
|
|
167
|
+
for (const rawStep of rawSource) {
|
|
168
|
+
const stepText = extractPlanStepText(rawStep);
|
|
169
|
+
if (!stepText)
|
|
170
|
+
continue;
|
|
171
|
+
const stepRecord = rawStep && typeof rawStep === "object" ? rawStep : {};
|
|
172
|
+
const statusFromStatus = normalizePlanStepStatus(stepRecord.status);
|
|
173
|
+
const statusFromState = normalizePlanStepStatus(stepRecord.state);
|
|
174
|
+
const completedFlag = typeof stepRecord.completed === "boolean" ? stepRecord.completed : null;
|
|
175
|
+
const inProgressFlag = typeof stepRecord.inProgress === "boolean" ? stepRecord.inProgress : null;
|
|
176
|
+
const inProgressSnakeFlag = typeof stepRecord.in_progress === "boolean" ? stepRecord.in_progress : null;
|
|
177
|
+
const resolvedStatus = statusFromStatus ??
|
|
178
|
+
statusFromState ??
|
|
179
|
+
(inProgressFlag || inProgressSnakeFlag ? "in_progress" : null) ??
|
|
180
|
+
(completedFlag === null ? null : completedFlag ? "completed" : "pending") ??
|
|
181
|
+
"pending";
|
|
182
|
+
normalizedSteps.push({
|
|
183
|
+
status: resolvedStatus,
|
|
184
|
+
step: stepText,
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
if (normalizedSteps.length)
|
|
188
|
+
return normalizedSteps;
|
|
189
|
+
}
|
|
190
|
+
return normalizedSteps;
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* 把结构化计划组装为可展示且可解析的 TODO 文本。
|
|
194
|
+
*/
|
|
195
|
+
function buildPlanText(rawPlan) {
|
|
196
|
+
if (!rawPlan || typeof rawPlan !== "object")
|
|
197
|
+
return "";
|
|
198
|
+
const planRecord = rawPlan;
|
|
199
|
+
const explanationFromField = typeof planRecord.explanation === "string" ? planRecord.explanation.trim() : "";
|
|
200
|
+
const summaryFromArray = Array.isArray(planRecord.summary)
|
|
201
|
+
? planRecord.summary
|
|
202
|
+
.map((value) => String(value ?? "").trim())
|
|
203
|
+
.filter(Boolean)
|
|
204
|
+
.join("\n")
|
|
205
|
+
: "";
|
|
206
|
+
const explanation = explanationFromField || summaryFromArray;
|
|
207
|
+
const normalizedSteps = extractNormalizedPlanSteps(planRecord);
|
|
208
|
+
if (!normalizedSteps.length)
|
|
209
|
+
return explanation;
|
|
210
|
+
const stepLines = normalizedSteps.map((step) => `- (${step.status}) ${step.step}`);
|
|
211
|
+
if (!explanation)
|
|
212
|
+
return stepLines.join("\n");
|
|
213
|
+
return `${explanation}\n${stepLines.join("\n")}`.trim();
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* 生成 plan completed 的最终文本,优先使用已有 text。
|
|
217
|
+
*/
|
|
218
|
+
function buildPlanCompletedFinalText(params) {
|
|
219
|
+
const directText = String(params?.item?.text ?? "").trim();
|
|
220
|
+
if (directText)
|
|
221
|
+
return directText;
|
|
222
|
+
return buildPlanText(params?.item ?? {});
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* 生成 turn/plan/updated 的最终文本。
|
|
226
|
+
*/
|
|
227
|
+
function buildTurnPlanUpdatedFinalText(params) {
|
|
228
|
+
return buildPlanText(params ?? {});
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* 安全序列化对象,避免异常中断历史投影。
|
|
232
|
+
*/
|
|
233
|
+
function safeJsonStringify(value) {
|
|
234
|
+
try {
|
|
235
|
+
return JSON.stringify(value);
|
|
236
|
+
}
|
|
237
|
+
catch {
|
|
238
|
+
return String(value ?? "");
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
/**
|
|
242
|
+
* 统一选项标签文本,避免装饰后缀影响匹配。
|
|
243
|
+
*/
|
|
244
|
+
function normalizeUserInputOptionLabel(value) {
|
|
245
|
+
let normalizedLabel = String(value ?? "")
|
|
246
|
+
.replace(/\s+/g, " ")
|
|
247
|
+
.trim();
|
|
248
|
+
normalizedLabel = normalizedLabel.replace(/\s*\((?:recommended|推荐)\)\s*$/i, "").trim();
|
|
249
|
+
normalizedLabel = normalizedLabel.replace(/\s*((?:recommended|推荐))\s*$/i, "").trim();
|
|
250
|
+
return normalizedLabel;
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* 审核记录里的“审核类型”字段标签。
|
|
254
|
+
*/
|
|
255
|
+
const APPROVAL_AUDIT_METHOD_LABEL = "审核类型";
|
|
256
|
+
/**
|
|
257
|
+
* 审核记录里的“审核结论”字段标签。
|
|
258
|
+
*/
|
|
259
|
+
const APPROVAL_AUDIT_DECISION_LABEL = "审核结论";
|
|
260
|
+
/**
|
|
261
|
+
* 从候选值中提取首个非空字符串。
|
|
262
|
+
*/
|
|
263
|
+
function pickFirstNonEmptyString(candidates) {
|
|
264
|
+
for (const candidate of candidates) {
|
|
265
|
+
if (typeof candidate !== "string")
|
|
266
|
+
continue;
|
|
267
|
+
const normalizedValue = candidate.trim();
|
|
268
|
+
if (normalizedValue)
|
|
269
|
+
return normalizedValue;
|
|
270
|
+
}
|
|
271
|
+
return "";
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* 从审核请求参数中提取命令文本(若存在)。
|
|
275
|
+
*/
|
|
276
|
+
function extractApprovalCommand(rawParams) {
|
|
277
|
+
const params = (rawParams ?? {});
|
|
278
|
+
return pickFirstNonEmptyString([params?.item?.command, params?.command, params?.proposed?.command, params?.request?.command]);
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* 从审核请求参数中提取审批理由文本。
|
|
282
|
+
*/
|
|
283
|
+
function extractApprovalReason(rawParams) {
|
|
284
|
+
const params = (rawParams ?? {});
|
|
285
|
+
return pickFirstNonEmptyString([params?.reason, params?.prompt, params?.message, params?.request?.reason, params?.item?.reason]);
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* 从审核请求参数中提取工作目录文本。
|
|
289
|
+
*/
|
|
290
|
+
function extractApprovalCwd(rawParams) {
|
|
291
|
+
const params = (rawParams ?? {});
|
|
292
|
+
return pickFirstNonEmptyString([params?.cwd, params?.workingDirectory, params?.request?.cwd]);
|
|
293
|
+
}
|
|
294
|
+
/**
|
|
295
|
+
* 从审核请求参数中提取被审核 itemId。
|
|
296
|
+
*/
|
|
297
|
+
function extractApprovalItemId(rawParams) {
|
|
298
|
+
const params = (rawParams ?? {});
|
|
299
|
+
return pickFirstNonEmptyString([params?.itemId, params?.item_id, params?.item?.id]);
|
|
300
|
+
}
|
|
301
|
+
/**
|
|
302
|
+
* 从审核请求参数中提取可读上下文。
|
|
303
|
+
*/
|
|
304
|
+
function extractApprovalRequestContext(rawParams) {
|
|
305
|
+
return {
|
|
306
|
+
reason: extractApprovalReason(rawParams),
|
|
307
|
+
command: extractApprovalCommand(rawParams),
|
|
308
|
+
cwd: extractApprovalCwd(rawParams),
|
|
309
|
+
itemId: extractApprovalItemId(rawParams),
|
|
310
|
+
};
|
|
311
|
+
}
|
|
312
|
+
/**
|
|
313
|
+
* 组装审核上下文展示行,帮助定位“审核的具体对象”。
|
|
314
|
+
*/
|
|
315
|
+
function buildApprovalContextLines(rawParams) {
|
|
316
|
+
const approvalContext = extractApprovalRequestContext(rawParams);
|
|
317
|
+
const contextLines = [];
|
|
318
|
+
if (approvalContext.reason)
|
|
319
|
+
contextLines.push(`- reason: ${approvalContext.reason}`);
|
|
320
|
+
if (approvalContext.command)
|
|
321
|
+
contextLines.push(`- command: ${approvalContext.command}`);
|
|
322
|
+
if (approvalContext.cwd)
|
|
323
|
+
contextLines.push(`- cwd: ${approvalContext.cwd}`);
|
|
324
|
+
if (!approvalContext.command && approvalContext.itemId)
|
|
325
|
+
contextLines.push(`- itemId: ${approvalContext.itemId}`);
|
|
326
|
+
return contextLines;
|
|
327
|
+
}
|
|
328
|
+
/**
|
|
329
|
+
* 构造 `web/user_input_required` 的消息类型与可读文本。
|
|
330
|
+
*/
|
|
331
|
+
function buildUserInputRequiredProjection(params) {
|
|
332
|
+
const method = String(params?.method ?? "").trim();
|
|
333
|
+
const rawMethodParams = params?.params ?? {};
|
|
334
|
+
if (method === "item/tool/requestUserInput") {
|
|
335
|
+
const questions = Array.isArray(rawMethodParams?.questions)
|
|
336
|
+
? rawMethodParams.questions
|
|
337
|
+
: [];
|
|
338
|
+
const lines = ["选择题请求"];
|
|
339
|
+
if (questions.length) {
|
|
340
|
+
for (const question of questions) {
|
|
341
|
+
const questionId = String(question?.id ?? "").trim();
|
|
342
|
+
const questionHeader = String(question?.header ?? "").trim();
|
|
343
|
+
const questionText = String(question?.question ?? "").trim();
|
|
344
|
+
const optionLabels = Array.isArray(question?.options)
|
|
345
|
+
? question.options
|
|
346
|
+
.map((option) => String(option?.label ?? "").trim())
|
|
347
|
+
.filter(Boolean)
|
|
348
|
+
: [];
|
|
349
|
+
const title = questionHeader || questionId || "未命名问题";
|
|
350
|
+
lines.push(`- ${title}${questionText ? `: ${questionText}` : ""}`);
|
|
351
|
+
if (optionLabels.length)
|
|
352
|
+
lines.push(` 选项: ${optionLabels.join(" / ")}`);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
else {
|
|
356
|
+
lines.push(`- ${APPROVAL_AUDIT_METHOD_LABEL}: ${method}`);
|
|
357
|
+
lines.push(`- payload: ${safeJsonStringify(rawMethodParams)}`);
|
|
358
|
+
}
|
|
359
|
+
return {
|
|
360
|
+
messageType: "user_input_request",
|
|
361
|
+
finalText: lines.join("\n"),
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
const lines = ["审核请求", `- ${APPROVAL_AUDIT_METHOD_LABEL}: ${method || "unknown"}`];
|
|
365
|
+
lines.push(...buildApprovalContextLines(rawMethodParams));
|
|
366
|
+
return {
|
|
367
|
+
messageType: "approval_request",
|
|
368
|
+
finalText: lines.join("\n"),
|
|
369
|
+
};
|
|
370
|
+
}
|
|
371
|
+
/**
|
|
372
|
+
* 从响应载荷中提取选择题答案列表文本。
|
|
373
|
+
*/
|
|
374
|
+
function extractChoiceAnswerLines(rawResponse) {
|
|
375
|
+
const response = (rawResponse ?? {});
|
|
376
|
+
const answers = response?.answers;
|
|
377
|
+
if (!answers || typeof answers !== "object")
|
|
378
|
+
return [];
|
|
379
|
+
const lines = [];
|
|
380
|
+
for (const [questionId, answerValue] of Object.entries(answers)) {
|
|
381
|
+
const normalizedQuestionId = String(questionId ?? "").trim() || "unknown";
|
|
382
|
+
const rawAnswers = Array.isArray(answerValue?.answers)
|
|
383
|
+
? answerValue.answers
|
|
384
|
+
: Array.isArray(answerValue)
|
|
385
|
+
? answerValue
|
|
386
|
+
: [answerValue];
|
|
387
|
+
const normalizedAnswers = rawAnswers
|
|
388
|
+
.map((value) => String(value ?? "").trim())
|
|
389
|
+
.filter(Boolean);
|
|
390
|
+
if (!normalizedAnswers.length)
|
|
391
|
+
continue;
|
|
392
|
+
const markedAnswers = normalizedAnswers.map((answerText) => {
|
|
393
|
+
if (/[✓✔]$/u.test(answerText))
|
|
394
|
+
return answerText;
|
|
395
|
+
return `${answerText}✓`;
|
|
396
|
+
});
|
|
397
|
+
lines.push(`- ${normalizedQuestionId}`);
|
|
398
|
+
lines.push(` 选项: ${markedAnswers.join(" / ")}`);
|
|
399
|
+
}
|
|
400
|
+
return lines;
|
|
401
|
+
}
|
|
402
|
+
/**
|
|
403
|
+
* 从响应中提取 questionId -> answers 映射。
|
|
404
|
+
*/
|
|
405
|
+
function extractChoiceAnswerMap(rawResponse) {
|
|
406
|
+
const response = (rawResponse ?? {});
|
|
407
|
+
const answers = response?.answers;
|
|
408
|
+
if (!answers || typeof answers !== "object")
|
|
409
|
+
return {};
|
|
410
|
+
const answerMap = {};
|
|
411
|
+
for (const [questionId, answerValue] of Object.entries(answers)) {
|
|
412
|
+
const normalizedQuestionId = String(questionId ?? "").trim();
|
|
413
|
+
if (!normalizedQuestionId)
|
|
414
|
+
continue;
|
|
415
|
+
const rawAnswers = Array.isArray(answerValue?.answers)
|
|
416
|
+
? answerValue.answers
|
|
417
|
+
: Array.isArray(answerValue)
|
|
418
|
+
? answerValue
|
|
419
|
+
: [answerValue];
|
|
420
|
+
const normalizedAnswers = rawAnswers
|
|
421
|
+
.map((value) => normalizeUserInputOptionLabel(value))
|
|
422
|
+
.filter(Boolean);
|
|
423
|
+
if (!normalizedAnswers.length)
|
|
424
|
+
continue;
|
|
425
|
+
answerMap[normalizedQuestionId] = normalizedAnswers;
|
|
426
|
+
}
|
|
427
|
+
return answerMap;
|
|
428
|
+
}
|
|
429
|
+
/**
|
|
430
|
+
* 按问题选项输出带勾选标记的结果行。
|
|
431
|
+
*/
|
|
432
|
+
function extractChoiceAnswerLinesWithOptions(rawResponse, requestParams) {
|
|
433
|
+
const params = (requestParams ?? {});
|
|
434
|
+
const questions = Array.isArray(params?.questions) ? params.questions : [];
|
|
435
|
+
if (!questions.length)
|
|
436
|
+
return extractChoiceAnswerLines(rawResponse);
|
|
437
|
+
const answerMap = extractChoiceAnswerMap(rawResponse);
|
|
438
|
+
const lines = [];
|
|
439
|
+
for (const question of questions) {
|
|
440
|
+
const questionId = String(question?.id ?? "").trim();
|
|
441
|
+
if (!questionId)
|
|
442
|
+
continue;
|
|
443
|
+
const questionHeader = String(question?.header ?? "").trim();
|
|
444
|
+
const questionText = String(question?.question ?? "").trim();
|
|
445
|
+
const title = questionHeader || questionId;
|
|
446
|
+
const selectedAnswers = new Set((answerMap[questionId] ?? []).map((answer) => normalizeUserInputOptionLabel(answer)));
|
|
447
|
+
const optionLabels = Array.isArray(question?.options)
|
|
448
|
+
? question.options
|
|
449
|
+
.map((option) => String(option?.label ?? "").trim())
|
|
450
|
+
.filter(Boolean)
|
|
451
|
+
: [];
|
|
452
|
+
lines.push(`- ${title}${questionText ? `: ${questionText}` : ""}`);
|
|
453
|
+
if (optionLabels.length) {
|
|
454
|
+
// 选项标签在 map 阶段显式标注为 string,避免隐式 any。
|
|
455
|
+
const markedOptions = optionLabels.map((optionLabel) => {
|
|
456
|
+
const normalizedOptionLabel = normalizeUserInputOptionLabel(optionLabel);
|
|
457
|
+
if (selectedAnswers.has(normalizedOptionLabel))
|
|
458
|
+
return `${optionLabel}✓`;
|
|
459
|
+
return optionLabel;
|
|
460
|
+
});
|
|
461
|
+
lines.push(` 选项: ${markedOptions.join(" / ")}`);
|
|
462
|
+
continue;
|
|
463
|
+
}
|
|
464
|
+
if (selectedAnswers.size) {
|
|
465
|
+
lines.push(` 选项: ${Array.from(selectedAnswers).join(" / ")}✓`);
|
|
466
|
+
continue;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
if (!lines.length)
|
|
470
|
+
return extractChoiceAnswerLines(rawResponse);
|
|
471
|
+
return lines;
|
|
472
|
+
}
|
|
473
|
+
/**
|
|
474
|
+
* 从响应载荷中提取审核决策字符串。
|
|
475
|
+
*/
|
|
476
|
+
function extractApprovalDecision(rawResponse) {
|
|
477
|
+
const response = (rawResponse ?? {});
|
|
478
|
+
const decision = response?.decision;
|
|
479
|
+
if (typeof decision === "string")
|
|
480
|
+
return decision.trim();
|
|
481
|
+
if (decision && typeof decision === "object" && !Array.isArray(decision)) {
|
|
482
|
+
if (decision.acceptWithExecpolicyAmendment)
|
|
483
|
+
return "acceptWithExecpolicyAmendment";
|
|
484
|
+
if (decision.approved_execpolicy_amendment)
|
|
485
|
+
return "approved_execpolicy_amendment";
|
|
486
|
+
return safeJsonStringify(decision);
|
|
487
|
+
}
|
|
488
|
+
return "";
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* 根据审批方法返回可选决策列表。
|
|
492
|
+
*/
|
|
493
|
+
function approvalDecisionOptionsByMethod(method) {
|
|
494
|
+
if (method === "item/commandExecution/requestApproval") {
|
|
495
|
+
return ["accept", "acceptForSession", "acceptWithExecpolicyAmendment", "decline", "cancel"];
|
|
496
|
+
}
|
|
497
|
+
if (method === "item/fileChange/requestApproval") {
|
|
498
|
+
return ["accept", "acceptForSession", "decline", "cancel"];
|
|
499
|
+
}
|
|
500
|
+
if (method === "applyPatchApproval" || method === "execCommandApproval") {
|
|
501
|
+
return ["approved", "approved_for_session", "approved_execpolicy_amendment", "denied", "abort"];
|
|
502
|
+
}
|
|
503
|
+
return [];
|
|
504
|
+
}
|
|
505
|
+
/**
|
|
506
|
+
* 构造 `web/user_input_resolved` 的消息类型与可读文本。
|
|
507
|
+
*/
|
|
508
|
+
function buildUserInputResolvedProjection(params) {
|
|
509
|
+
const method = String(params?.method ?? "").trim();
|
|
510
|
+
const mappedResponse = params?.mappedResponse ?? params?.response ?? {};
|
|
511
|
+
const requestParams = params?.requestParams ?? {};
|
|
512
|
+
if (method === "item/tool/requestUserInput") {
|
|
513
|
+
const lines = ["选择题结果"];
|
|
514
|
+
const answerLines = extractChoiceAnswerLinesWithOptions(mappedResponse, requestParams);
|
|
515
|
+
if (answerLines.length) {
|
|
516
|
+
lines.push(...answerLines);
|
|
517
|
+
}
|
|
518
|
+
else {
|
|
519
|
+
lines.push(`- ${APPROVAL_AUDIT_METHOD_LABEL}: ${method}`);
|
|
520
|
+
lines.push(`- payload: ${safeJsonStringify(mappedResponse)}`);
|
|
521
|
+
}
|
|
522
|
+
return {
|
|
523
|
+
messageType: "user_input_response",
|
|
524
|
+
finalText: lines.join("\n"),
|
|
525
|
+
};
|
|
526
|
+
}
|
|
527
|
+
const decision = extractApprovalDecision(mappedResponse);
|
|
528
|
+
const lines = ["审核结果", `- ${APPROVAL_AUDIT_METHOD_LABEL}: ${method || "unknown"}`];
|
|
529
|
+
lines.push(...buildApprovalContextLines(requestParams));
|
|
530
|
+
if (decision) {
|
|
531
|
+
lines.push(`- ${APPROVAL_AUDIT_DECISION_LABEL}: ${decision}`);
|
|
532
|
+
const optionLabels = approvalDecisionOptionsByMethod(method);
|
|
533
|
+
if (decision && optionLabels.length && !optionLabels.includes(decision))
|
|
534
|
+
optionLabels.push(decision);
|
|
535
|
+
if (optionLabels.length) {
|
|
536
|
+
const markedOptions = optionLabels.map((optionLabel) => (optionLabel === decision ? `${optionLabel}✓` : optionLabel));
|
|
537
|
+
lines.push(` 选项: ${markedOptions.join(" / ")}`);
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
lines.push(`- payload: ${safeJsonStringify(mappedResponse)}`);
|
|
542
|
+
}
|
|
543
|
+
return {
|
|
544
|
+
messageType: "approval_response",
|
|
545
|
+
finalText: lines.join("\n"),
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* 将 Codex 事件投影为结构化消息与增量片段。
|
|
550
|
+
*/
|
|
551
|
+
function projectCodexEvent(input) {
|
|
552
|
+
// 统一做 method 归一化,降低上游字段类型波动带来的分支误判。
|
|
553
|
+
const method = String(input.event?.method ?? "").trim();
|
|
554
|
+
const params = (input.event?.params ?? {});
|
|
555
|
+
if (method === "item/started") {
|
|
556
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
557
|
+
const itemId = (0, extractIds_1.extractItemId)(params);
|
|
558
|
+
const item = params?.item ?? null;
|
|
559
|
+
const itemType = typeof item?.type === "string" ? String(item.type).trim() : "";
|
|
560
|
+
const normalizedItemType = itemType.toLowerCase().replace(/[_\s-]+/g, "");
|
|
561
|
+
if (normalizedItemType === "usermessage") {
|
|
562
|
+
const messageId = (0, extractIds_1.buildUserMessageId)(turnId, itemId);
|
|
563
|
+
const finalText = buildUserMessageFinalText(item);
|
|
564
|
+
if (!messageId || !finalText)
|
|
565
|
+
return {};
|
|
566
|
+
return {
|
|
567
|
+
message: {
|
|
568
|
+
threadId: input.threadId,
|
|
569
|
+
messageId,
|
|
570
|
+
role: "user",
|
|
571
|
+
messageType: "user_message",
|
|
572
|
+
status: "done",
|
|
573
|
+
finalText,
|
|
574
|
+
finishedAtMs: input.nowMs,
|
|
575
|
+
updatedAtMs: input.nowMs,
|
|
576
|
+
},
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
if (method === "item/agentMessage/delta") {
|
|
581
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
582
|
+
const itemId = (0, extractIds_1.extractItemId)(params);
|
|
583
|
+
const messageId = (0, extractIds_1.buildAgentMessageId)(turnId, itemId);
|
|
584
|
+
const deltaText = String(params?.delta ?? "");
|
|
585
|
+
if (!messageId || !deltaText)
|
|
586
|
+
return {};
|
|
587
|
+
return {
|
|
588
|
+
message: {
|
|
589
|
+
threadId: input.threadId,
|
|
590
|
+
messageId,
|
|
591
|
+
role: "assistant",
|
|
592
|
+
messageType: "assistant_text",
|
|
593
|
+
status: "streaming",
|
|
594
|
+
startedAtMs: input.nowMs,
|
|
595
|
+
updatedAtMs: input.nowMs,
|
|
596
|
+
},
|
|
597
|
+
};
|
|
598
|
+
}
|
|
599
|
+
if (method === "item/plan/delta") {
|
|
600
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
601
|
+
const itemId = (0, extractIds_1.extractItemId)(params);
|
|
602
|
+
const messageId = (0, extractIds_1.buildPlanMessageId)(turnId, itemId);
|
|
603
|
+
const deltaText = String(params?.delta ?? "");
|
|
604
|
+
if (!messageId || !deltaText)
|
|
605
|
+
return {};
|
|
606
|
+
return {
|
|
607
|
+
message: {
|
|
608
|
+
threadId: input.threadId,
|
|
609
|
+
messageId,
|
|
610
|
+
role: "assistant",
|
|
611
|
+
messageType: "plan",
|
|
612
|
+
status: "streaming",
|
|
613
|
+
startedAtMs: input.nowMs,
|
|
614
|
+
updatedAtMs: input.nowMs,
|
|
615
|
+
},
|
|
616
|
+
};
|
|
617
|
+
}
|
|
618
|
+
if (method === "item/commandExecution/outputDelta") {
|
|
619
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
620
|
+
const itemId = (0, extractIds_1.extractItemId)(params);
|
|
621
|
+
const messageId = (0, extractIds_1.buildCommandExecutionMessageId)(turnId, itemId);
|
|
622
|
+
const deltaText = String(params?.delta ?? "");
|
|
623
|
+
if (!messageId || !deltaText)
|
|
624
|
+
return {};
|
|
625
|
+
return {
|
|
626
|
+
message: {
|
|
627
|
+
threadId: input.threadId,
|
|
628
|
+
messageId,
|
|
629
|
+
role: "system",
|
|
630
|
+
messageType: "command_execution",
|
|
631
|
+
status: "streaming",
|
|
632
|
+
startedAtMs: input.nowMs,
|
|
633
|
+
updatedAtMs: input.nowMs,
|
|
634
|
+
},
|
|
635
|
+
};
|
|
636
|
+
}
|
|
637
|
+
if (method === "item/fileChange/outputDelta") {
|
|
638
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
639
|
+
const itemId = (0, extractIds_1.extractItemId)(params);
|
|
640
|
+
const messageId = (0, extractIds_1.buildFileChangeMessageId)(turnId, itemId);
|
|
641
|
+
const deltaText = String(params?.delta ?? "");
|
|
642
|
+
if (!messageId || !deltaText)
|
|
643
|
+
return {};
|
|
644
|
+
return {
|
|
645
|
+
message: {
|
|
646
|
+
threadId: input.threadId,
|
|
647
|
+
messageId,
|
|
648
|
+
role: "system",
|
|
649
|
+
messageType: "file_change",
|
|
650
|
+
status: "streaming",
|
|
651
|
+
diffOutputDelta: deltaText,
|
|
652
|
+
startedAtMs: input.nowMs,
|
|
653
|
+
updatedAtMs: input.nowMs,
|
|
654
|
+
},
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
if (method === "item/reasoning/summaryTextDelta") {
|
|
658
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
659
|
+
const itemId = (0, extractIds_1.extractItemId)(params);
|
|
660
|
+
const summaryIndex = normalizeSummaryIndex(params?.summaryIndex);
|
|
661
|
+
const messageId = (0, extractIds_1.buildReasoningSummaryMessageId)(turnId, itemId, summaryIndex);
|
|
662
|
+
const deltaText = String(params?.delta ?? "");
|
|
663
|
+
if (!messageId || !deltaText)
|
|
664
|
+
return {};
|
|
665
|
+
return {
|
|
666
|
+
message: {
|
|
667
|
+
threadId: input.threadId,
|
|
668
|
+
messageId,
|
|
669
|
+
role: "reasoning",
|
|
670
|
+
messageType: "reasoning_summary",
|
|
671
|
+
status: "streaming",
|
|
672
|
+
startedAtMs: input.nowMs,
|
|
673
|
+
updatedAtMs: input.nowMs,
|
|
674
|
+
},
|
|
675
|
+
};
|
|
676
|
+
}
|
|
677
|
+
if (method === "web/user_input_required") {
|
|
678
|
+
const projection = buildUserInputRequiredProjection(params);
|
|
679
|
+
const messageId = (0, extractIds_1.buildUserInputAuditMessageId)(input.threadId, params?.requestId, "required");
|
|
680
|
+
return {
|
|
681
|
+
message: {
|
|
682
|
+
threadId: input.threadId,
|
|
683
|
+
messageId,
|
|
684
|
+
role: "system",
|
|
685
|
+
messageType: projection.messageType,
|
|
686
|
+
status: "done",
|
|
687
|
+
finalText: projection.finalText,
|
|
688
|
+
finishedAtMs: input.nowMs,
|
|
689
|
+
updatedAtMs: input.nowMs,
|
|
690
|
+
},
|
|
691
|
+
};
|
|
692
|
+
}
|
|
693
|
+
if (method === "web/user_input_resolved") {
|
|
694
|
+
const projection = buildUserInputResolvedProjection(params);
|
|
695
|
+
const messageId = (0, extractIds_1.buildUserInputAuditMessageId)(input.threadId, params?.requestId, "resolved");
|
|
696
|
+
return {
|
|
697
|
+
message: {
|
|
698
|
+
threadId: input.threadId,
|
|
699
|
+
messageId,
|
|
700
|
+
role: "system",
|
|
701
|
+
messageType: projection.messageType,
|
|
702
|
+
status: "done",
|
|
703
|
+
finalText: projection.finalText,
|
|
704
|
+
finishedAtMs: input.nowMs,
|
|
705
|
+
updatedAtMs: input.nowMs,
|
|
706
|
+
},
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
if (method === "item/completed") {
|
|
710
|
+
const itemType = resolveCompletedItemType(params);
|
|
711
|
+
if (itemType === "usermessage") {
|
|
712
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
713
|
+
const itemId = (0, extractIds_1.extractItemId)(params);
|
|
714
|
+
const messageId = (0, extractIds_1.buildUserMessageId)(turnId, itemId);
|
|
715
|
+
if (!messageId)
|
|
716
|
+
return {};
|
|
717
|
+
const item = params?.item ?? null;
|
|
718
|
+
const finalText = buildUserMessageFinalText(item);
|
|
719
|
+
if (!finalText)
|
|
720
|
+
return {};
|
|
721
|
+
return {
|
|
722
|
+
message: {
|
|
723
|
+
threadId: input.threadId,
|
|
724
|
+
messageId,
|
|
725
|
+
role: "user",
|
|
726
|
+
messageType: "user_message",
|
|
727
|
+
status: "done",
|
|
728
|
+
finalText,
|
|
729
|
+
finishedAtMs: input.nowMs,
|
|
730
|
+
updatedAtMs: input.nowMs,
|
|
731
|
+
},
|
|
732
|
+
};
|
|
733
|
+
}
|
|
734
|
+
if (itemType === "agentmessage") {
|
|
735
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
736
|
+
const itemId = (0, extractIds_1.extractItemId)(params);
|
|
737
|
+
const messageId = (0, extractIds_1.buildAgentMessageId)(turnId, itemId);
|
|
738
|
+
if (!messageId)
|
|
739
|
+
return {};
|
|
740
|
+
return {
|
|
741
|
+
message: {
|
|
742
|
+
threadId: input.threadId,
|
|
743
|
+
messageId,
|
|
744
|
+
role: "assistant",
|
|
745
|
+
messageType: "assistant_text",
|
|
746
|
+
status: "done",
|
|
747
|
+
finalText: String(params?.item?.text ?? ""),
|
|
748
|
+
finishedAtMs: input.nowMs,
|
|
749
|
+
updatedAtMs: input.nowMs,
|
|
750
|
+
},
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
if (itemType === "commandexecution") {
|
|
754
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
755
|
+
const itemId = (0, extractIds_1.extractItemId)(params);
|
|
756
|
+
const messageId = (0, extractIds_1.buildCommandExecutionMessageId)(turnId, itemId);
|
|
757
|
+
if (!messageId)
|
|
758
|
+
return {};
|
|
759
|
+
return {
|
|
760
|
+
message: {
|
|
761
|
+
threadId: input.threadId,
|
|
762
|
+
messageId,
|
|
763
|
+
role: "system",
|
|
764
|
+
messageType: "command_execution",
|
|
765
|
+
status: "done",
|
|
766
|
+
finalText: buildCommandExecutionFinalText(params),
|
|
767
|
+
finishedAtMs: input.nowMs,
|
|
768
|
+
updatedAtMs: input.nowMs,
|
|
769
|
+
},
|
|
770
|
+
};
|
|
771
|
+
}
|
|
772
|
+
if (itemType === "plan") {
|
|
773
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
774
|
+
const itemId = (0, extractIds_1.extractItemId)(params);
|
|
775
|
+
const messageId = (0, extractIds_1.buildPlanMessageId)(turnId, itemId);
|
|
776
|
+
if (!messageId)
|
|
777
|
+
return {};
|
|
778
|
+
return {
|
|
779
|
+
message: {
|
|
780
|
+
threadId: input.threadId,
|
|
781
|
+
messageId,
|
|
782
|
+
role: "assistant",
|
|
783
|
+
messageType: "plan",
|
|
784
|
+
status: "done",
|
|
785
|
+
finalText: buildPlanCompletedFinalText(params),
|
|
786
|
+
finishedAtMs: input.nowMs,
|
|
787
|
+
updatedAtMs: input.nowMs,
|
|
788
|
+
},
|
|
789
|
+
};
|
|
790
|
+
}
|
|
791
|
+
if (itemType === "filechange") {
|
|
792
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
793
|
+
const itemId = (0, extractIds_1.extractItemId)(params);
|
|
794
|
+
const messageId = (0, extractIds_1.buildFileChangeMessageId)(turnId, itemId);
|
|
795
|
+
if (!messageId)
|
|
796
|
+
return {};
|
|
797
|
+
const item = params?.item ?? params;
|
|
798
|
+
const changes = (0, fileChangeExtractor_1.extractFileChangesFromAny)(item);
|
|
799
|
+
const diffChangesJson = changes.length ? JSON.stringify(changes) : "";
|
|
800
|
+
const diffTitle = buildFileChangeFinalText(params);
|
|
801
|
+
return {
|
|
802
|
+
message: {
|
|
803
|
+
threadId: input.threadId,
|
|
804
|
+
messageId,
|
|
805
|
+
role: "system",
|
|
806
|
+
messageType: "file_change",
|
|
807
|
+
status: "done",
|
|
808
|
+
finalText: diffTitle,
|
|
809
|
+
diffTitle,
|
|
810
|
+
diffChangesJson,
|
|
811
|
+
finishedAtMs: input.nowMs,
|
|
812
|
+
updatedAtMs: input.nowMs,
|
|
813
|
+
},
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
if (itemType === "reasoning") {
|
|
817
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
818
|
+
const itemId = (0, extractIds_1.extractItemId)(params);
|
|
819
|
+
const messages = buildReasoningCompletedMessages(input.threadId, turnId, itemId, params, input.nowMs);
|
|
820
|
+
if (!messages.length)
|
|
821
|
+
return {};
|
|
822
|
+
return { messages };
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
if (method === "turn/plan/updated") {
|
|
826
|
+
const turnId = (0, extractIds_1.extractTurnId)(params);
|
|
827
|
+
const messageId = (0, extractIds_1.buildPlanMessageId)(turnId, "todo");
|
|
828
|
+
if (!messageId)
|
|
829
|
+
return {};
|
|
830
|
+
return {
|
|
831
|
+
message: {
|
|
832
|
+
threadId: input.threadId,
|
|
833
|
+
messageId,
|
|
834
|
+
role: "assistant",
|
|
835
|
+
messageType: "plan",
|
|
836
|
+
status: "done",
|
|
837
|
+
finalText: buildTurnPlanUpdatedFinalText(params),
|
|
838
|
+
finishedAtMs: input.nowMs,
|
|
839
|
+
updatedAtMs: input.nowMs,
|
|
840
|
+
},
|
|
841
|
+
};
|
|
842
|
+
}
|
|
843
|
+
return {};
|
|
844
|
+
}
|
|
845
|
+
//# sourceMappingURL=projectCodexEvent.js.map
|