lunel-cli 0.1.48 → 0.1.50
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 +4 -0
- package/dist/ai/codex.js +114 -8
- package/package.json +1 -1
package/dist/ai/codex.d.ts
CHANGED
|
@@ -58,6 +58,7 @@ export declare class CodexProvider implements AIProvider {
|
|
|
58
58
|
private ensureAssistantMessage;
|
|
59
59
|
private upsertLocalMessagePart;
|
|
60
60
|
private fetchServerThreads;
|
|
61
|
+
private fetchModels;
|
|
61
62
|
private parseThreadListEntry;
|
|
62
63
|
private hasNextCursor;
|
|
63
64
|
private ingestThreadMetadata;
|
|
@@ -94,6 +95,9 @@ export declare class CodexProvider implements AIProvider {
|
|
|
94
95
|
private isAssistantMessageItem;
|
|
95
96
|
private extractIncomingItem;
|
|
96
97
|
private describeToolPart;
|
|
98
|
+
private normalizeStructuredType;
|
|
99
|
+
private extractStructuredOutput;
|
|
100
|
+
private extractDiffLikePayload;
|
|
97
101
|
private extractToolInput;
|
|
98
102
|
private describeCompletedItemOutput;
|
|
99
103
|
}
|
package/dist/ai/codex.js
CHANGED
|
@@ -119,7 +119,7 @@ export class CodexProvider {
|
|
|
119
119
|
await this.call("turn/start", {
|
|
120
120
|
threadId: session.id,
|
|
121
121
|
input: [{ type: "text", text }],
|
|
122
|
-
...(model ? { model: `${model.providerID}/${model.modelID}` } : {}),
|
|
122
|
+
...(model ? { model: model.providerID === "codex" ? model.modelID : `${model.providerID}/${model.modelID}` } : {}),
|
|
123
123
|
...(agent ? { agent } : {}),
|
|
124
124
|
});
|
|
125
125
|
}
|
|
@@ -145,7 +145,23 @@ export class CodexProvider {
|
|
|
145
145
|
return { agents: [] };
|
|
146
146
|
}
|
|
147
147
|
async providers() {
|
|
148
|
-
|
|
148
|
+
const items = await this.fetchModels();
|
|
149
|
+
const models = Object.fromEntries(items.map((item) => [
|
|
150
|
+
item.model,
|
|
151
|
+
{
|
|
152
|
+
id: item.model,
|
|
153
|
+
name: item.displayName || item.model,
|
|
154
|
+
provider: "codex",
|
|
155
|
+
description: item.description,
|
|
156
|
+
},
|
|
157
|
+
]));
|
|
158
|
+
const defaultModel = items.find((item) => item.isDefault)?.model;
|
|
159
|
+
return {
|
|
160
|
+
providers: items.length > 0
|
|
161
|
+
? [{ id: "codex", name: "Codex", models }]
|
|
162
|
+
: [],
|
|
163
|
+
default: defaultModel ? { codex: defaultModel } : {},
|
|
164
|
+
};
|
|
149
165
|
}
|
|
150
166
|
async setAuth(providerId, key) {
|
|
151
167
|
throw new Error("Codex auth configuration is not supported by Lunel yet");
|
|
@@ -486,10 +502,10 @@ export class CodexProvider {
|
|
|
486
502
|
const turnId = this.extractTurnId(params) ?? session.activeTurnId ?? `session:${session.id}`;
|
|
487
503
|
const messageId = this.ensureAssistantMessage(session, turnId);
|
|
488
504
|
const item = this.extractIncomingItem(params);
|
|
489
|
-
const normalizedType = this.
|
|
505
|
+
const normalizedType = this.normalizeStructuredType(this.readString(item.type) ?? method);
|
|
490
506
|
const itemId = this.extractItemId(params) ?? this.readString(item.id) ?? normalizedType ?? "tool";
|
|
491
507
|
const partId = `${messageId}:tool:${itemId}`;
|
|
492
|
-
const nextText = this.
|
|
508
|
+
const nextText = this.extractStructuredOutput(params, item, normalizedType);
|
|
493
509
|
const prevOutput = this.partTextById.get(partId) ?? "";
|
|
494
510
|
const output = completed
|
|
495
511
|
? nextText ?? prevOutput
|
|
@@ -500,7 +516,7 @@ export class CodexProvider {
|
|
|
500
516
|
const state = completed ? "completed" : "running";
|
|
501
517
|
const name = this.describeToolPart(normalizedType, method, item);
|
|
502
518
|
const input = this.extractToolInput(item, params);
|
|
503
|
-
const outputValue = output || this.describeCompletedItemOutput(item, normalizedType) || undefined;
|
|
519
|
+
const outputValue = output || this.describeCompletedItemOutput(item, params, normalizedType) || undefined;
|
|
504
520
|
const part = {
|
|
505
521
|
id: partId,
|
|
506
522
|
sessionID: session.id,
|
|
@@ -589,7 +605,13 @@ export class CodexProvider {
|
|
|
589
605
|
cursor: nextCursor,
|
|
590
606
|
});
|
|
591
607
|
const payload = this.asRecord(result);
|
|
592
|
-
const page =
|
|
608
|
+
const page = Array.isArray(payload.data)
|
|
609
|
+
? payload.data
|
|
610
|
+
: Array.isArray(payload.items)
|
|
611
|
+
? payload.items
|
|
612
|
+
: Array.isArray(payload.threads)
|
|
613
|
+
? payload.threads
|
|
614
|
+
: [];
|
|
593
615
|
for (const entry of page) {
|
|
594
616
|
const parsed = this.parseThreadListEntry(entry);
|
|
595
617
|
if (parsed)
|
|
@@ -600,6 +622,39 @@ export class CodexProvider {
|
|
|
600
622
|
} while (hasRequestedFirstPage && this.hasNextCursor(nextCursor));
|
|
601
623
|
return threads;
|
|
602
624
|
}
|
|
625
|
+
async fetchModels() {
|
|
626
|
+
const result = await this.call("model/list", {
|
|
627
|
+
cursor: null,
|
|
628
|
+
limit: 50,
|
|
629
|
+
includeHidden: false,
|
|
630
|
+
});
|
|
631
|
+
const payload = this.asRecord(result);
|
|
632
|
+
const items = Array.isArray(payload.items)
|
|
633
|
+
? payload.items
|
|
634
|
+
: Array.isArray(payload.data)
|
|
635
|
+
? payload.data
|
|
636
|
+
: Array.isArray(payload.models)
|
|
637
|
+
? payload.models
|
|
638
|
+
: [];
|
|
639
|
+
return items
|
|
640
|
+
.map((value) => {
|
|
641
|
+
const obj = this.asRecord(value);
|
|
642
|
+
const model = this.readString(obj.model) ?? this.readString(obj.id);
|
|
643
|
+
if (!model)
|
|
644
|
+
return undefined;
|
|
645
|
+
const displayName = this.readString(obj.displayName)
|
|
646
|
+
?? this.readString(obj.display_name)
|
|
647
|
+
?? model;
|
|
648
|
+
return {
|
|
649
|
+
id: this.readString(obj.id) ?? model,
|
|
650
|
+
model,
|
|
651
|
+
displayName,
|
|
652
|
+
description: this.readString(obj.description) ?? "",
|
|
653
|
+
isDefault: Boolean(obj.isDefault ?? obj.is_default),
|
|
654
|
+
};
|
|
655
|
+
})
|
|
656
|
+
.filter((value) => Boolean(value));
|
|
657
|
+
}
|
|
603
658
|
parseThreadListEntry(value) {
|
|
604
659
|
const obj = this.asRecord(value);
|
|
605
660
|
const id = this.extractThreadId(obj);
|
|
@@ -1028,10 +1083,61 @@ export class CodexProvider {
|
|
|
1028
1083
|
}
|
|
1029
1084
|
return this.readString(item.name) ?? method.replace(/^.*\//, "");
|
|
1030
1085
|
}
|
|
1086
|
+
normalizeStructuredType(rawType) {
|
|
1087
|
+
const normalized = this.normalizedItemType(rawType);
|
|
1088
|
+
if (normalized.includes("turndiff") || normalized === "diff")
|
|
1089
|
+
return "diff";
|
|
1090
|
+
if (normalized.includes("filechange"))
|
|
1091
|
+
return "filechange";
|
|
1092
|
+
if (normalized.includes("toolcall"))
|
|
1093
|
+
return "toolcall";
|
|
1094
|
+
if (normalized.includes("commandexecution"))
|
|
1095
|
+
return "commandexecution";
|
|
1096
|
+
return normalized;
|
|
1097
|
+
}
|
|
1098
|
+
extractStructuredOutput(params, item, normalizedType) {
|
|
1099
|
+
if (normalizedType === "filechange" || normalizedType === "toolcall" || normalizedType === "diff") {
|
|
1100
|
+
return this.extractDiffLikePayload(params, item) ?? this.extractTextPayload(params);
|
|
1101
|
+
}
|
|
1102
|
+
return this.extractTextPayload(params);
|
|
1103
|
+
}
|
|
1104
|
+
extractDiffLikePayload(params, item) {
|
|
1105
|
+
const event = this.asRecord(params.event);
|
|
1106
|
+
const nestedItem = this.asRecord(event.item);
|
|
1107
|
+
const sources = [params, item, event, nestedItem];
|
|
1108
|
+
for (const source of sources) {
|
|
1109
|
+
const direct = this.firstString(source, [
|
|
1110
|
+
"diff",
|
|
1111
|
+
"unified_diff",
|
|
1112
|
+
"unifiedDiff",
|
|
1113
|
+
"patch",
|
|
1114
|
+
"text",
|
|
1115
|
+
"message",
|
|
1116
|
+
"summary",
|
|
1117
|
+
"output",
|
|
1118
|
+
"output_text",
|
|
1119
|
+
"outputText",
|
|
1120
|
+
]);
|
|
1121
|
+
if (direct)
|
|
1122
|
+
return direct;
|
|
1123
|
+
}
|
|
1124
|
+
const changes = this.readArray(item.changes ?? params.changes ?? event.changes ?? nestedItem.changes);
|
|
1125
|
+
if (changes.length === 0)
|
|
1126
|
+
return undefined;
|
|
1127
|
+
return changes
|
|
1128
|
+
.map((change) => {
|
|
1129
|
+
const obj = this.asRecord(change);
|
|
1130
|
+
const path = this.readString(obj.path) ?? this.readString(obj.filePath) ?? this.readString(obj.file_path) ?? "file";
|
|
1131
|
+
const kind = this.readString(obj.kind) ?? "change";
|
|
1132
|
+
const diff = this.firstString(obj, ["diff", "unified_diff", "unifiedDiff", "patch"]) ?? "";
|
|
1133
|
+
return diff ? `Path: ${path}\nKind: ${kind}\n\n\`\`\`diff\n${diff}\n\`\`\`` : `Path: ${path}\nKind: ${kind}`;
|
|
1134
|
+
})
|
|
1135
|
+
.join("\n\n---\n\n");
|
|
1136
|
+
}
|
|
1031
1137
|
extractToolInput(item, params) {
|
|
1032
1138
|
return item.input ?? item.command ?? item.path ?? item.args ?? params.command ?? params.path ?? undefined;
|
|
1033
1139
|
}
|
|
1034
|
-
describeCompletedItemOutput(item, normalizedType) {
|
|
1140
|
+
describeCompletedItemOutput(item, params, normalizedType) {
|
|
1035
1141
|
if (normalizedType === "commandexecution") {
|
|
1036
1142
|
return this.firstString(item, ["stdout", "stderr", "text", "message", "summary"]);
|
|
1037
1143
|
}
|
|
@@ -1039,7 +1145,7 @@ export class CodexProvider {
|
|
|
1039
1145
|
return this.decodePlanItemText(item);
|
|
1040
1146
|
}
|
|
1041
1147
|
if (normalizedType === "filechange" || normalizedType === "toolcall" || normalizedType === "diff") {
|
|
1042
|
-
return this.decodeFileLikeItemText(item);
|
|
1148
|
+
return this.extractDiffLikePayload(params, item) ?? this.decodeFileLikeItemText(item);
|
|
1043
1149
|
}
|
|
1044
1150
|
if (normalizedType === "enteredreviewmode") {
|
|
1045
1151
|
return `Reviewing ${this.readString(item.review) ?? "changes"}...`;
|