lunel-cli 0.1.51 → 0.1.53
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/ai/codex.d.ts +5 -0
- package/dist/ai/codex.js +142 -58
- package/package.json +1 -1
package/dist/ai/codex.d.ts
CHANGED
|
@@ -96,8 +96,13 @@ export declare class CodexProvider implements AIProvider {
|
|
|
96
96
|
private extractIncomingItem;
|
|
97
97
|
private describeToolPart;
|
|
98
98
|
private normalizeStructuredType;
|
|
99
|
+
private isFileChangeStructuredItem;
|
|
99
100
|
private extractStructuredOutput;
|
|
100
101
|
private extractDiffLikePayload;
|
|
102
|
+
private renderFileChangeEntriesBody;
|
|
103
|
+
private renderUnifiedDiffBody;
|
|
104
|
+
private extractCanonicalPatch;
|
|
105
|
+
private normalizedFileChangeStatus;
|
|
101
106
|
private extractToolInput;
|
|
102
107
|
private describeCompletedItemOutput;
|
|
103
108
|
}
|
package/dist/ai/codex.js
CHANGED
|
@@ -374,10 +374,12 @@ export class CodexProvider {
|
|
|
374
374
|
case "codex/event/read":
|
|
375
375
|
case "codex/event/search":
|
|
376
376
|
case "codex/event/list_files":
|
|
377
|
+
this.emitStructuredToolPart(session, method, params, false);
|
|
378
|
+
return;
|
|
377
379
|
case "turn/diff/updated":
|
|
378
380
|
case "codex/event/turn_diff_updated":
|
|
379
381
|
case "codex/event/turn_diff":
|
|
380
|
-
this.emitStructuredToolPart(session, method, params,
|
|
382
|
+
this.emitStructuredToolPart(session, method, params, true);
|
|
381
383
|
return;
|
|
382
384
|
case "item/completed":
|
|
383
385
|
case "codex/event/item_completed":
|
|
@@ -504,7 +506,11 @@ export class CodexProvider {
|
|
|
504
506
|
const item = this.extractIncomingItem(params);
|
|
505
507
|
const normalizedType = this.normalizeStructuredType(this.readString(item.type) ?? method);
|
|
506
508
|
const itemId = this.extractItemId(params) ?? this.readString(item.id) ?? normalizedType ?? "tool";
|
|
507
|
-
const
|
|
509
|
+
const fileChangeLike = this.isFileChangeStructuredItem(normalizedType, item, params);
|
|
510
|
+
const emittedPartType = normalizedType === "plan"
|
|
511
|
+
? "reasoning"
|
|
512
|
+
: (fileChangeLike ? "file-change" : "tool");
|
|
513
|
+
const partId = `${messageId}:${emittedPartType}:${itemId}`;
|
|
508
514
|
const nextText = this.extractStructuredOutput(params, item, normalizedType);
|
|
509
515
|
const prevOutput = this.partTextById.get(partId) ?? "";
|
|
510
516
|
const output = completed
|
|
@@ -517,14 +523,17 @@ export class CodexProvider {
|
|
|
517
523
|
const name = this.describeToolPart(normalizedType, method, item);
|
|
518
524
|
const input = this.extractToolInput(item, params);
|
|
519
525
|
const outputValue = output || this.describeCompletedItemOutput(item, params, normalizedType) || undefined;
|
|
526
|
+
const patch = emittedPartType === "file-change"
|
|
527
|
+
? this.extractCanonicalPatch(params, item)
|
|
528
|
+
: undefined;
|
|
520
529
|
const part = {
|
|
521
530
|
id: partId,
|
|
522
531
|
sessionID: session.id,
|
|
523
532
|
messageID: messageId,
|
|
524
|
-
type:
|
|
525
|
-
...(
|
|
533
|
+
type: emittedPartType,
|
|
534
|
+
...(emittedPartType === "reasoning"
|
|
526
535
|
? { text: outputValue ?? "Planning..." }
|
|
527
|
-
: { name, toolName: name, input, output: outputValue, state }),
|
|
536
|
+
: { name, toolName: name, input, output: outputValue, state, ...(patch ? { patch } : {}) }),
|
|
528
537
|
};
|
|
529
538
|
this.upsertLocalMessagePart(session, messageId, part);
|
|
530
539
|
this.emitMessagePartEvent(session.id, messageId, "assistant", part);
|
|
@@ -814,16 +823,23 @@ export class CodexProvider {
|
|
|
814
823
|
const output = this.decodeFileLikeItemText(itemObject);
|
|
815
824
|
if (!output)
|
|
816
825
|
continue;
|
|
826
|
+
const emittedPartType = this.isFileChangeStructuredItem(type, itemObject)
|
|
827
|
+
? "file-change"
|
|
828
|
+
: "tool";
|
|
829
|
+
const patch = emittedPartType === "file-change"
|
|
830
|
+
? this.extractCanonicalPatch({}, itemObject)
|
|
831
|
+
: undefined;
|
|
817
832
|
messages.push({
|
|
818
833
|
id: itemId,
|
|
819
834
|
role: "assistant",
|
|
820
835
|
parts: [{
|
|
821
|
-
id: `${itemId}
|
|
822
|
-
type:
|
|
836
|
+
id: `${itemId}:${emittedPartType}`,
|
|
837
|
+
type: emittedPartType,
|
|
823
838
|
name: type,
|
|
824
839
|
toolName: type,
|
|
825
840
|
output,
|
|
826
841
|
state: "completed",
|
|
842
|
+
...(patch ? { patch } : {}),
|
|
827
843
|
sessionID: threadId,
|
|
828
844
|
messageID: itemId,
|
|
829
845
|
}],
|
|
@@ -874,11 +890,16 @@ export class CodexProvider {
|
|
|
874
890
|
return `${this.normalizedCommandPhase(status)} ${this.shortCommand(command)}`;
|
|
875
891
|
}
|
|
876
892
|
decodeFileLikeItemText(itemObject) {
|
|
893
|
+
const status = this.normalizedFileChangeStatus(itemObject, true);
|
|
894
|
+
const changesBody = this.renderFileChangeEntriesBody(itemObject.changes);
|
|
895
|
+
if (changesBody) {
|
|
896
|
+
return `Status: ${status}\n\n${changesBody}`;
|
|
897
|
+
}
|
|
898
|
+
const diff = this.firstString(itemObject, ["diff", "unified_diff", "unifiedDiff", "patch"]);
|
|
899
|
+
if (diff?.trim()) {
|
|
900
|
+
return this.renderUnifiedDiffBody(diff, status);
|
|
901
|
+
}
|
|
877
902
|
const direct = this.firstString(itemObject, [
|
|
878
|
-
"diff",
|
|
879
|
-
"unified_diff",
|
|
880
|
-
"unifiedDiff",
|
|
881
|
-
"patch",
|
|
882
903
|
"text",
|
|
883
904
|
"message",
|
|
884
905
|
"summary",
|
|
@@ -887,20 +908,10 @@ export class CodexProvider {
|
|
|
887
908
|
"output_text",
|
|
888
909
|
"outputText",
|
|
889
910
|
]);
|
|
890
|
-
if (direct?.trim())
|
|
891
|
-
return direct.trim()
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
return undefined;
|
|
895
|
-
return changes
|
|
896
|
-
.map((change) => {
|
|
897
|
-
const obj = this.asRecord(change);
|
|
898
|
-
const path = this.readString(obj.path) ?? this.readString(obj.filePath) ?? this.readString(obj.file_path) ?? "file";
|
|
899
|
-
const kind = this.readString(obj.kind) ?? "change";
|
|
900
|
-
const diff = this.readString(obj.diff) ?? this.readString(obj.patch) ?? "";
|
|
901
|
-
return diff ? `${kind}: ${path}\n${diff}` : `${kind}: ${path}`;
|
|
902
|
-
})
|
|
903
|
-
.join("\n\n");
|
|
911
|
+
if (direct?.trim()) {
|
|
912
|
+
return `Status: ${status}\n\n${direct.trim()}`;
|
|
913
|
+
}
|
|
914
|
+
return undefined;
|
|
904
915
|
}
|
|
905
916
|
normalizedCommandPhase(rawStatus) {
|
|
906
917
|
const normalized = rawStatus.trim().toLowerCase();
|
|
@@ -1104,52 +1115,125 @@ export class CodexProvider {
|
|
|
1104
1115
|
return "commandexecution";
|
|
1105
1116
|
return normalized;
|
|
1106
1117
|
}
|
|
1118
|
+
isFileChangeStructuredItem(normalizedType, item, params) {
|
|
1119
|
+
if (normalizedType === "filechange" || normalizedType === "diff") {
|
|
1120
|
+
return true;
|
|
1121
|
+
}
|
|
1122
|
+
if (normalizedType !== "toolcall") {
|
|
1123
|
+
return false;
|
|
1124
|
+
}
|
|
1125
|
+
const event = this.asRecord(params?.event);
|
|
1126
|
+
const nestedItem = this.asRecord(event.item);
|
|
1127
|
+
const sources = [item, params ?? {}, event, nestedItem];
|
|
1128
|
+
for (const source of sources) {
|
|
1129
|
+
if (this.firstString(source, ["diff", "unified_diff", "unifiedDiff", "patch"])) {
|
|
1130
|
+
return true;
|
|
1131
|
+
}
|
|
1132
|
+
if (this.readArray(source.changes).length > 0) {
|
|
1133
|
+
return true;
|
|
1134
|
+
}
|
|
1135
|
+
}
|
|
1136
|
+
const toolName = this.firstString(item, ["name", "toolName", "tool_name", "title"])?.toLowerCase() ?? "";
|
|
1137
|
+
return toolName.includes("patch") || toolName.includes("edit") || toolName.includes("write");
|
|
1138
|
+
}
|
|
1107
1139
|
extractStructuredOutput(params, item, normalizedType) {
|
|
1108
1140
|
if (normalizedType === "filechange" || normalizedType === "toolcall" || normalizedType === "diff") {
|
|
1109
|
-
return this.extractDiffLikePayload(params, item) ?? this.extractTextPayload(params);
|
|
1141
|
+
return this.extractDiffLikePayload(params, item, normalizedType) ?? this.extractTextPayload(params);
|
|
1110
1142
|
}
|
|
1111
1143
|
return this.extractTextPayload(params);
|
|
1112
1144
|
}
|
|
1113
|
-
extractDiffLikePayload(params, item) {
|
|
1145
|
+
extractDiffLikePayload(params, item, normalizedType) {
|
|
1114
1146
|
const event = this.asRecord(params.event);
|
|
1115
1147
|
const nestedItem = this.asRecord(event.item);
|
|
1116
1148
|
const sources = [params, item, event, nestedItem];
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
"unifiedDiff",
|
|
1122
|
-
"patch",
|
|
1123
|
-
]);
|
|
1124
|
-
if (direct)
|
|
1125
|
-
return direct;
|
|
1149
|
+
const status = this.normalizedFileChangeStatus(item, false);
|
|
1150
|
+
const changesBody = this.renderFileChangeEntriesBody(item.changes ?? params.changes ?? event.changes ?? nestedItem.changes);
|
|
1151
|
+
if (changesBody) {
|
|
1152
|
+
return `Status: ${status}\n\n${changesBody}`;
|
|
1126
1153
|
}
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
.
|
|
1131
|
-
|
|
1132
|
-
const path = this.readString(obj.path) ?? this.readString(obj.filePath) ?? this.readString(obj.file_path) ?? "file";
|
|
1133
|
-
const kind = this.readString(obj.kind) ?? "change";
|
|
1134
|
-
const diff = this.firstString(obj, ["diff", "unified_diff", "unifiedDiff", "patch"]) ?? "";
|
|
1135
|
-
return diff ? `Path: ${path}\nKind: ${kind}\n\n\`\`\`diff\n${diff}\n\`\`\`` : `Path: ${path}\nKind: ${kind}`;
|
|
1136
|
-
})
|
|
1137
|
-
.join("\n\n---\n\n");
|
|
1154
|
+
for (const source of sources) {
|
|
1155
|
+
const diff = this.firstString(source, ["diff", "unified_diff", "unifiedDiff", "patch"]);
|
|
1156
|
+
if (diff) {
|
|
1157
|
+
return this.renderUnifiedDiffBody(diff, status);
|
|
1158
|
+
}
|
|
1138
1159
|
}
|
|
1139
1160
|
for (const source of sources) {
|
|
1140
|
-
const direct = this.firstString(source, [
|
|
1141
|
-
|
|
1142
|
-
"
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
]);
|
|
1148
|
-
if (direct)
|
|
1149
|
-
return direct;
|
|
1161
|
+
const direct = this.firstString(source, ["text", "message", "summary", "output", "output_text", "outputText"]);
|
|
1162
|
+
if (direct) {
|
|
1163
|
+
if (normalizedType === "toolcall" && !this.isFileChangeStructuredItem("toolcall", item, params)) {
|
|
1164
|
+
return direct;
|
|
1165
|
+
}
|
|
1166
|
+
return `Status: ${status}\n\n${direct}`;
|
|
1167
|
+
}
|
|
1150
1168
|
}
|
|
1151
1169
|
return undefined;
|
|
1152
1170
|
}
|
|
1171
|
+
renderFileChangeEntriesBody(rawChanges) {
|
|
1172
|
+
const changes = this.readArray(rawChanges);
|
|
1173
|
+
if (changes.length === 0)
|
|
1174
|
+
return undefined;
|
|
1175
|
+
const rendered = changes
|
|
1176
|
+
.map((change) => {
|
|
1177
|
+
const obj = this.asRecord(change);
|
|
1178
|
+
const path = this.firstString(obj, [
|
|
1179
|
+
"path",
|
|
1180
|
+
"file",
|
|
1181
|
+
"file_path",
|
|
1182
|
+
"filePath",
|
|
1183
|
+
"relative_path",
|
|
1184
|
+
"relativePath",
|
|
1185
|
+
"new_path",
|
|
1186
|
+
"newPath",
|
|
1187
|
+
"to",
|
|
1188
|
+
"target",
|
|
1189
|
+
"name",
|
|
1190
|
+
"old_path",
|
|
1191
|
+
"oldPath",
|
|
1192
|
+
"from",
|
|
1193
|
+
]) ?? "file";
|
|
1194
|
+
const kind = this.firstString(obj, ["kind", "type", "action", "status"]) ?? "change";
|
|
1195
|
+
const diff = this.firstString(obj, ["diff", "unified_diff", "unifiedDiff", "patch"]) ?? "";
|
|
1196
|
+
return diff
|
|
1197
|
+
? `Path: ${path}\nKind: ${kind}\n\n\`\`\`diff\n${diff}\n\`\`\``
|
|
1198
|
+
: `Path: ${path}\nKind: ${kind}`;
|
|
1199
|
+
})
|
|
1200
|
+
.filter(Boolean);
|
|
1201
|
+
return rendered.length > 0 ? rendered.join("\n\n---\n\n") : undefined;
|
|
1202
|
+
}
|
|
1203
|
+
renderUnifiedDiffBody(diff, status) {
|
|
1204
|
+
return `Status: ${status}\n\n\`\`\`diff\n${diff.trim()}\n\`\`\``;
|
|
1205
|
+
}
|
|
1206
|
+
extractCanonicalPatch(params, item) {
|
|
1207
|
+
const event = this.asRecord(params.event);
|
|
1208
|
+
const nestedItem = this.asRecord(event.item);
|
|
1209
|
+
const sources = [item, params, event, nestedItem];
|
|
1210
|
+
for (const source of sources) {
|
|
1211
|
+
const diff = this.firstString(source, ["diff", "unified_diff", "unifiedDiff", "patch"]);
|
|
1212
|
+
if (diff?.trim()) {
|
|
1213
|
+
return diff.trim();
|
|
1214
|
+
}
|
|
1215
|
+
}
|
|
1216
|
+
const changes = this.readArray(item.changes ?? params.changes ?? event.changes ?? nestedItem.changes);
|
|
1217
|
+
if (changes.length === 0)
|
|
1218
|
+
return undefined;
|
|
1219
|
+
const patch = changes
|
|
1220
|
+
.map((change) => {
|
|
1221
|
+
const obj = this.asRecord(change);
|
|
1222
|
+
return this.firstString(obj, ["diff", "unified_diff", "unifiedDiff", "patch"]) ?? "";
|
|
1223
|
+
})
|
|
1224
|
+
.filter((value) => value.trim().length > 0)
|
|
1225
|
+
.join("\n");
|
|
1226
|
+
return patch.trim() || undefined;
|
|
1227
|
+
}
|
|
1228
|
+
normalizedFileChangeStatus(itemObject, isCompleted) {
|
|
1229
|
+
const status = this.readString(itemObject.status)
|
|
1230
|
+
?? this.readString(this.asRecord(itemObject.status).type)
|
|
1231
|
+
?? this.readString(itemObject.state)
|
|
1232
|
+
?? this.readString(this.asRecord(itemObject.state).type);
|
|
1233
|
+
if (status)
|
|
1234
|
+
return status;
|
|
1235
|
+
return isCompleted ? "completed" : "inProgress";
|
|
1236
|
+
}
|
|
1153
1237
|
extractToolInput(item, params) {
|
|
1154
1238
|
return item.input ?? item.command ?? item.path ?? item.args ?? params.command ?? params.path ?? undefined;
|
|
1155
1239
|
}
|
|
@@ -1161,7 +1245,7 @@ export class CodexProvider {
|
|
|
1161
1245
|
return this.decodePlanItemText(item);
|
|
1162
1246
|
}
|
|
1163
1247
|
if (normalizedType === "filechange" || normalizedType === "toolcall" || normalizedType === "diff") {
|
|
1164
|
-
return this.extractDiffLikePayload(params, item) ?? this.decodeFileLikeItemText(item);
|
|
1248
|
+
return this.extractDiffLikePayload(params, item, normalizedType) ?? this.decodeFileLikeItemText(item);
|
|
1165
1249
|
}
|
|
1166
1250
|
if (normalizedType === "enteredreviewmode") {
|
|
1167
1251
|
return `Reviewing ${this.readString(item.review) ?? "changes"}...`;
|