opencode-feishu 0.7.10 → 0.7.12
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/index.js +85 -49
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -99239,21 +99239,23 @@ function extractErrorFields(error) {
|
|
|
99239
99239
|
if (typeof error === "string") return [error];
|
|
99240
99240
|
if (error && typeof error === "object") {
|
|
99241
99241
|
const e = error;
|
|
99242
|
-
const
|
|
99242
|
+
const explicit = [e.message, e.type, e.name];
|
|
99243
|
+
const enumerable = Object.values(e);
|
|
99244
|
+
const fields = [...explicit, ...enumerable].filter((v) => typeof v === "string" && v.length > 0);
|
|
99243
99245
|
if (e.data && typeof e.data === "object" && "message" in e.data) {
|
|
99244
99246
|
const dataMsg = e.data.message;
|
|
99245
|
-
if (dataMsg) fields.push(
|
|
99247
|
+
if (typeof dataMsg === "string" && dataMsg.length > 0) fields.push(dataMsg);
|
|
99246
99248
|
}
|
|
99247
|
-
return fields;
|
|
99249
|
+
return [...new Set(fields)];
|
|
99248
99250
|
}
|
|
99249
99251
|
return [String(error)];
|
|
99250
99252
|
}
|
|
99251
99253
|
function isModelError(fields) {
|
|
99252
|
-
const
|
|
99253
|
-
|
|
99254
|
-
|
|
99255
|
-
|
|
99256
|
-
|
|
99254
|
+
const patterns = ["model not found", "modelnotfound", "model not supported", "model_not_supported"];
|
|
99255
|
+
return fields.some((f) => {
|
|
99256
|
+
const l = f.toLowerCase();
|
|
99257
|
+
return patterns.some((p) => l.includes(p));
|
|
99258
|
+
});
|
|
99257
99259
|
}
|
|
99258
99260
|
async function handleEvent(event, deps) {
|
|
99259
99261
|
switch (event.type) {
|
|
@@ -99436,6 +99438,7 @@ async function handleChat(ctx, deps) {
|
|
|
99436
99438
|
for (let i = 0; i < autoPrompt.maxIterations; i++) {
|
|
99437
99439
|
await abortableSleep(autoPrompt.intervalSeconds * 1e3, ac.signal);
|
|
99438
99440
|
log("info", "\u53D1\u9001\u81EA\u52A8\u63D0\u793A", { sessionKey, iteration: i + 1 });
|
|
99441
|
+
clearSessionError(activeId);
|
|
99439
99442
|
await client.session.prompt({
|
|
99440
99443
|
path: { id: activeId },
|
|
99441
99444
|
query,
|
|
@@ -99466,6 +99469,7 @@ async function handleChat(ctx, deps) {
|
|
|
99466
99469
|
}
|
|
99467
99470
|
}
|
|
99468
99471
|
try {
|
|
99472
|
+
clearSessionError(session.id);
|
|
99469
99473
|
await client.session.prompt({
|
|
99470
99474
|
path: { id: session.id },
|
|
99471
99475
|
query,
|
|
@@ -99481,30 +99485,52 @@ async function handleChat(ctx, deps) {
|
|
|
99481
99485
|
await replyOrUpdate(feishuClient, chatId, placeholderId, finalText || "\u26A0\uFE0F \u54CD\u5E94\u8D85\u65F6");
|
|
99482
99486
|
await runAutoPromptLoop(session.id);
|
|
99483
99487
|
} catch (err) {
|
|
99484
|
-
|
|
99485
|
-
|
|
99486
|
-
|
|
99487
|
-
|
|
99488
|
-
|
|
99489
|
-
|
|
99490
|
-
|
|
99491
|
-
|
|
99488
|
+
let sessionError;
|
|
99489
|
+
if (err instanceof SessionErrorDetected) {
|
|
99490
|
+
sessionError = err.sessionError;
|
|
99491
|
+
clearSessionError(session.id);
|
|
99492
|
+
} else {
|
|
99493
|
+
await new Promise((r) => setTimeout(r, SSE_RACE_WAIT_MS));
|
|
99494
|
+
sessionError = getSessionError(session.id);
|
|
99495
|
+
clearSessionError(session.id);
|
|
99496
|
+
if (!sessionError) {
|
|
99497
|
+
const thrownFields = extractErrorFields(err);
|
|
99498
|
+
if (isModelError(thrownFields)) {
|
|
99499
|
+
const thrownMsg = err instanceof Error ? err.message : String(err);
|
|
99500
|
+
sessionError = { message: thrownMsg, fields: thrownFields };
|
|
99501
|
+
}
|
|
99492
99502
|
}
|
|
99493
99503
|
}
|
|
99504
|
+
if (sessionError) {
|
|
99505
|
+
log("info", "\u9519\u8BEF\u5B57\u6BB5\u68C0\u67E5", {
|
|
99506
|
+
sessionKey,
|
|
99507
|
+
fields: sessionError.fields,
|
|
99508
|
+
isModel: isModelError(sessionError.fields)
|
|
99509
|
+
});
|
|
99510
|
+
}
|
|
99494
99511
|
if (sessionError && isModelError(sessionError.fields)) {
|
|
99495
99512
|
const attempts = getRetryAttempts(sessionKey);
|
|
99496
99513
|
if (attempts < MAX_RETRY_ATTEMPTS) {
|
|
99497
99514
|
try {
|
|
99498
|
-
|
|
99515
|
+
let modelOverride;
|
|
99516
|
+
try {
|
|
99517
|
+
modelOverride = await getGlobalDefaultModel(client, directory);
|
|
99518
|
+
} catch (configErr) {
|
|
99519
|
+
log("warn", "\u8BFB\u53D6\u5168\u5C40\u6A21\u578B\u914D\u7F6E\u5931\u8D25", {
|
|
99520
|
+
sessionKey,
|
|
99521
|
+
error: configErr instanceof Error ? configErr.message : String(configErr)
|
|
99522
|
+
});
|
|
99523
|
+
}
|
|
99499
99524
|
if (!modelOverride) {
|
|
99500
|
-
log("warn", "\
|
|
99525
|
+
log("warn", "\u5168\u5C40\u9ED8\u8BA4\u6A21\u578B\u672A\u914D\u7F6E\uFF0C\u653E\u5F03\u6062\u590D", { sessionKey });
|
|
99501
99526
|
} else {
|
|
99502
99527
|
setRetryAttempts(sessionKey, attempts + 1);
|
|
99503
|
-
log("info", "\
|
|
99528
|
+
log("info", "\u4F7F\u7528\u5168\u5C40\u9ED8\u8BA4\u6A21\u578B\u6062\u590D", {
|
|
99504
99529
|
sessionKey,
|
|
99505
99530
|
providerID: modelOverride.providerID,
|
|
99506
99531
|
modelID: modelOverride.modelID
|
|
99507
99532
|
});
|
|
99533
|
+
clearSessionError(session.id);
|
|
99508
99534
|
await client.session.prompt({
|
|
99509
99535
|
path: { id: session.id },
|
|
99510
99536
|
query,
|
|
@@ -99528,14 +99554,25 @@ async function handleChat(ctx, deps) {
|
|
|
99528
99554
|
return;
|
|
99529
99555
|
}
|
|
99530
99556
|
} catch (recoveryErr) {
|
|
99531
|
-
const
|
|
99532
|
-
|
|
99533
|
-
|
|
99534
|
-
|
|
99557
|
+
const errMsg = recoveryErr instanceof Error ? recoveryErr.message : String(recoveryErr);
|
|
99558
|
+
if (recoveryErr instanceof SessionErrorDetected) {
|
|
99559
|
+
sessionError = recoveryErr.sessionError;
|
|
99560
|
+
clearSessionError(session.id);
|
|
99561
|
+
} else {
|
|
99562
|
+
await new Promise((r) => setTimeout(r, SSE_RACE_WAIT_MS));
|
|
99563
|
+
const sseError = getSessionError(session.id);
|
|
99564
|
+
if (sseError) {
|
|
99565
|
+
sessionError = sseError;
|
|
99566
|
+
clearSessionError(session.id);
|
|
99567
|
+
} else {
|
|
99568
|
+
const thrownFields = extractErrorFields(recoveryErr);
|
|
99569
|
+
sessionError = { message: errMsg, fields: thrownFields };
|
|
99570
|
+
}
|
|
99571
|
+
}
|
|
99535
99572
|
log("error", "\u6A21\u578B\u6062\u590D\u5931\u8D25", {
|
|
99536
99573
|
sessionId: session.id,
|
|
99537
99574
|
sessionKey,
|
|
99538
|
-
error:
|
|
99575
|
+
error: errMsg
|
|
99539
99576
|
});
|
|
99540
99577
|
}
|
|
99541
99578
|
} else {
|
|
@@ -99562,32 +99599,16 @@ async function handleChat(ctx, deps) {
|
|
|
99562
99599
|
unregisterPending(activeSessionId);
|
|
99563
99600
|
}
|
|
99564
99601
|
}
|
|
99565
|
-
async function
|
|
99566
|
-
const pattern = /model\s*not\s*found:?\s*(\w[\w-]*)\/(\S+)/i;
|
|
99567
|
-
const match = errorFields.map((f) => pattern.exec(f)).find(Boolean);
|
|
99568
|
-
const failedProviderID = match?.[1]?.toLowerCase();
|
|
99569
|
-
const failedModelID = match?.[2]?.replace(/\.$/, "");
|
|
99602
|
+
async function getGlobalDefaultModel(client, directory) {
|
|
99570
99603
|
const query = directory ? { directory } : void 0;
|
|
99571
|
-
const { data } = await client.
|
|
99572
|
-
|
|
99573
|
-
|
|
99574
|
-
|
|
99575
|
-
|
|
99576
|
-
|
|
99577
|
-
|
|
99578
|
-
|
|
99579
|
-
}
|
|
99580
|
-
}
|
|
99581
|
-
for (const pid of connectedProviders) {
|
|
99582
|
-
const provider = data.all?.find((p) => p.id === pid);
|
|
99583
|
-
if (!provider?.models) continue;
|
|
99584
|
-
const candidates = Object.values(provider.models).filter((m) => m.status !== "deprecated" && !(pid === failedProviderID && m.id === failedModelID)).sort((a, b) => b.release_date.localeCompare(a.release_date));
|
|
99585
|
-
if (candidates.length > 0) {
|
|
99586
|
-
const best = candidates.find((m) => m.tool_call) ?? candidates[0];
|
|
99587
|
-
return { providerID: pid, modelID: best.id };
|
|
99588
|
-
}
|
|
99589
|
-
}
|
|
99590
|
-
return void 0;
|
|
99604
|
+
const { data: config } = await client.config.get({ query });
|
|
99605
|
+
const model = config?.model;
|
|
99606
|
+
if (!model || !model.includes("/")) return void 0;
|
|
99607
|
+
const slash = model.indexOf("/");
|
|
99608
|
+
const providerID = model.slice(0, slash).trim();
|
|
99609
|
+
const modelID = model.slice(slash + 1).trim();
|
|
99610
|
+
if (!providerID || !modelID) return void 0;
|
|
99611
|
+
return { providerID, modelID };
|
|
99591
99612
|
}
|
|
99592
99613
|
async function buildPromptParts(feishuClient, messageId, messageType, rawContent, textContent, chatType, senderId, log) {
|
|
99593
99614
|
if (messageType === "text") {
|
|
@@ -99603,6 +99624,13 @@ async function buildPromptParts(feishuClient, messageId, messageType, rawContent
|
|
|
99603
99624
|
}
|
|
99604
99625
|
return parts;
|
|
99605
99626
|
}
|
|
99627
|
+
var SessionErrorDetected = class extends Error {
|
|
99628
|
+
constructor(sessionError) {
|
|
99629
|
+
super(sessionError.message);
|
|
99630
|
+
this.sessionError = sessionError;
|
|
99631
|
+
this.name = "SessionErrorDetected";
|
|
99632
|
+
}
|
|
99633
|
+
};
|
|
99606
99634
|
async function pollForResponse(client, sessionId, opts) {
|
|
99607
99635
|
const { timeout, pollInterval, stablePolls, query, signal } = opts;
|
|
99608
99636
|
const start = Date.now();
|
|
@@ -99614,6 +99642,10 @@ async function pollForResponse(client, sessionId, opts) {
|
|
|
99614
99642
|
} else {
|
|
99615
99643
|
await new Promise((r) => setTimeout(r, pollInterval));
|
|
99616
99644
|
}
|
|
99645
|
+
const sseError = getSessionError(sessionId);
|
|
99646
|
+
if (sseError) {
|
|
99647
|
+
throw new SessionErrorDetected(sseError);
|
|
99648
|
+
}
|
|
99617
99649
|
const { data: messages } = await client.session.messages({ path: { id: sessionId }, query });
|
|
99618
99650
|
const text2 = extractLastAssistantText(messages ?? []);
|
|
99619
99651
|
if (text2 && text2 !== lastText) {
|
|
@@ -99624,6 +99656,10 @@ async function pollForResponse(client, sessionId, opts) {
|
|
|
99624
99656
|
if (sameCount >= stablePolls) break;
|
|
99625
99657
|
}
|
|
99626
99658
|
}
|
|
99659
|
+
const finalSseError = getSessionError(sessionId);
|
|
99660
|
+
if (finalSseError) {
|
|
99661
|
+
throw new SessionErrorDetected(finalSseError);
|
|
99662
|
+
}
|
|
99627
99663
|
const { data: finalMessages } = await client.session.messages({ path: { id: sessionId }, query });
|
|
99628
99664
|
return extractLastAssistantText(finalMessages ?? []) || lastText;
|
|
99629
99665
|
}
|