opencode-feishu 0.7.10 → 0.7.11

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 CHANGED
@@ -99249,11 +99249,11 @@ function extractErrorFields(error) {
99249
99249
  return [String(error)];
99250
99250
  }
99251
99251
  function isModelError(fields) {
99252
- const check = (s) => {
99253
- const l = s.toLowerCase();
99254
- return l.includes("model not found") || l.includes("modelnotfound");
99255
- };
99256
- return fields.some(check);
99252
+ const patterns = ["model not found", "modelnotfound", "model not supported", "model_not_supported"];
99253
+ return fields.some((f) => {
99254
+ const l = f.toLowerCase();
99255
+ return patterns.some((p) => l.includes(p));
99256
+ });
99257
99257
  }
99258
99258
  async function handleEvent(event, deps) {
99259
99259
  switch (event.type) {
@@ -99436,6 +99436,7 @@ async function handleChat(ctx, deps) {
99436
99436
  for (let i = 0; i < autoPrompt.maxIterations; i++) {
99437
99437
  await abortableSleep(autoPrompt.intervalSeconds * 1e3, ac.signal);
99438
99438
  log("info", "\u53D1\u9001\u81EA\u52A8\u63D0\u793A", { sessionKey, iteration: i + 1 });
99439
+ clearSessionError(activeId);
99439
99440
  await client.session.prompt({
99440
99441
  path: { id: activeId },
99441
99442
  query,
@@ -99466,6 +99467,7 @@ async function handleChat(ctx, deps) {
99466
99467
  }
99467
99468
  }
99468
99469
  try {
99470
+ clearSessionError(session.id);
99469
99471
  await client.session.prompt({
99470
99472
  path: { id: session.id },
99471
99473
  query,
@@ -99481,30 +99483,45 @@ async function handleChat(ctx, deps) {
99481
99483
  await replyOrUpdate(feishuClient, chatId, placeholderId, finalText || "\u26A0\uFE0F \u54CD\u5E94\u8D85\u65F6");
99482
99484
  await runAutoPromptLoop(session.id);
99483
99485
  } catch (err) {
99484
- await new Promise((r) => setTimeout(r, SSE_RACE_WAIT_MS));
99485
- let sessionError = getSessionError(session.id);
99486
- clearSessionError(session.id);
99487
- if (!sessionError) {
99488
- const thrownFields = extractErrorFields(err);
99489
- if (isModelError(thrownFields)) {
99490
- const thrownMsg = err instanceof Error ? err.message : String(err);
99491
- sessionError = { message: thrownMsg, fields: thrownFields };
99486
+ let sessionError;
99487
+ if (err instanceof SessionErrorDetected) {
99488
+ sessionError = err.sessionError;
99489
+ clearSessionError(session.id);
99490
+ } else {
99491
+ await new Promise((r) => setTimeout(r, SSE_RACE_WAIT_MS));
99492
+ sessionError = getSessionError(session.id);
99493
+ clearSessionError(session.id);
99494
+ if (!sessionError) {
99495
+ const thrownFields = extractErrorFields(err);
99496
+ if (isModelError(thrownFields)) {
99497
+ const thrownMsg = err instanceof Error ? err.message : String(err);
99498
+ sessionError = { message: thrownMsg, fields: thrownFields };
99499
+ }
99492
99500
  }
99493
99501
  }
99494
99502
  if (sessionError && isModelError(sessionError.fields)) {
99495
99503
  const attempts = getRetryAttempts(sessionKey);
99496
99504
  if (attempts < MAX_RETRY_ATTEMPTS) {
99497
99505
  try {
99498
- const modelOverride = await resolveLatestModel(client, sessionError.fields, directory);
99506
+ let modelOverride;
99507
+ try {
99508
+ modelOverride = await getGlobalDefaultModel(client, directory);
99509
+ } catch (configErr) {
99510
+ log("warn", "\u8BFB\u53D6\u5168\u5C40\u6A21\u578B\u914D\u7F6E\u5931\u8D25", {
99511
+ sessionKey,
99512
+ error: configErr instanceof Error ? configErr.message : String(configErr)
99513
+ });
99514
+ }
99499
99515
  if (!modelOverride) {
99500
- log("warn", "\u65E0\u4EFB\u4F55\u5DF2\u8FDE\u63A5 provider \u6709\u53EF\u7528\u6A21\u578B\uFF0C\u653E\u5F03\u6062\u590D", { sessionKey });
99516
+ log("warn", "\u5168\u5C40\u9ED8\u8BA4\u6A21\u578B\u672A\u914D\u7F6E\uFF0C\u653E\u5F03\u6062\u590D", { sessionKey });
99501
99517
  } else {
99502
99518
  setRetryAttempts(sessionKey, attempts + 1);
99503
- log("info", "\u5DF2\u89E3\u6790\u53EF\u7528\u6A21\u578B\uFF0C\u5728\u540C\u4E00 session \u4E0A\u91CD\u8BD5", {
99519
+ log("info", "\u4F7F\u7528\u5168\u5C40\u9ED8\u8BA4\u6A21\u578B\u6062\u590D", {
99504
99520
  sessionKey,
99505
99521
  providerID: modelOverride.providerID,
99506
99522
  modelID: modelOverride.modelID
99507
99523
  });
99524
+ clearSessionError(session.id);
99508
99525
  await client.session.prompt({
99509
99526
  path: { id: session.id },
99510
99527
  query,
@@ -99528,14 +99545,25 @@ async function handleChat(ctx, deps) {
99528
99545
  return;
99529
99546
  }
99530
99547
  } catch (recoveryErr) {
99531
- const recoveryErrMsg = recoveryErr instanceof Error ? recoveryErr.message : String(recoveryErr);
99532
- const retryError = getSessionError(session.id);
99533
- if (retryError) clearSessionError(session.id);
99534
- sessionError = retryError ?? { message: recoveryErrMsg, fields: [] };
99548
+ const errMsg = recoveryErr instanceof Error ? recoveryErr.message : String(recoveryErr);
99549
+ if (recoveryErr instanceof SessionErrorDetected) {
99550
+ sessionError = recoveryErr.sessionError;
99551
+ clearSessionError(session.id);
99552
+ } else {
99553
+ await new Promise((r) => setTimeout(r, SSE_RACE_WAIT_MS));
99554
+ const sseError = getSessionError(session.id);
99555
+ if (sseError) {
99556
+ sessionError = sseError;
99557
+ clearSessionError(session.id);
99558
+ } else {
99559
+ const thrownFields = extractErrorFields(recoveryErr);
99560
+ sessionError = { message: errMsg, fields: thrownFields };
99561
+ }
99562
+ }
99535
99563
  log("error", "\u6A21\u578B\u6062\u590D\u5931\u8D25", {
99536
99564
  sessionId: session.id,
99537
99565
  sessionKey,
99538
- error: recoveryErrMsg
99566
+ error: errMsg
99539
99567
  });
99540
99568
  }
99541
99569
  } else {
@@ -99562,32 +99590,16 @@ async function handleChat(ctx, deps) {
99562
99590
  unregisterPending(activeSessionId);
99563
99591
  }
99564
99592
  }
99565
- async function resolveLatestModel(client, errorFields, directory) {
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(/\.$/, "");
99593
+ async function getGlobalDefaultModel(client, directory) {
99570
99594
  const query = directory ? { directory } : void 0;
99571
- const { data } = await client.provider.list({ query });
99572
- if (!data) return void 0;
99573
- const connectedProviders = data.connected ?? [];
99574
- if (connectedProviders.length === 0) return void 0;
99575
- for (const pid of connectedProviders) {
99576
- const defaultModelID = data.default?.[pid];
99577
- if (defaultModelID && !(pid === failedProviderID && defaultModelID === failedModelID)) {
99578
- return { providerID: pid, modelID: defaultModelID };
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;
99595
+ const { data: config } = await client.config.get({ query });
99596
+ const model = config?.model;
99597
+ if (!model || !model.includes("/")) return void 0;
99598
+ const slash = model.indexOf("/");
99599
+ const providerID = model.slice(0, slash).trim();
99600
+ const modelID = model.slice(slash + 1).trim();
99601
+ if (!providerID || !modelID) return void 0;
99602
+ return { providerID, modelID };
99591
99603
  }
99592
99604
  async function buildPromptParts(feishuClient, messageId, messageType, rawContent, textContent, chatType, senderId, log) {
99593
99605
  if (messageType === "text") {
@@ -99603,6 +99615,13 @@ async function buildPromptParts(feishuClient, messageId, messageType, rawContent
99603
99615
  }
99604
99616
  return parts;
99605
99617
  }
99618
+ var SessionErrorDetected = class extends Error {
99619
+ constructor(sessionError) {
99620
+ super(sessionError.message);
99621
+ this.sessionError = sessionError;
99622
+ this.name = "SessionErrorDetected";
99623
+ }
99624
+ };
99606
99625
  async function pollForResponse(client, sessionId, opts) {
99607
99626
  const { timeout, pollInterval, stablePolls, query, signal } = opts;
99608
99627
  const start = Date.now();
@@ -99614,6 +99633,10 @@ async function pollForResponse(client, sessionId, opts) {
99614
99633
  } else {
99615
99634
  await new Promise((r) => setTimeout(r, pollInterval));
99616
99635
  }
99636
+ const sseError = getSessionError(sessionId);
99637
+ if (sseError) {
99638
+ throw new SessionErrorDetected(sseError);
99639
+ }
99617
99640
  const { data: messages } = await client.session.messages({ path: { id: sessionId }, query });
99618
99641
  const text2 = extractLastAssistantText(messages ?? []);
99619
99642
  if (text2 && text2 !== lastText) {
@@ -99624,6 +99647,10 @@ async function pollForResponse(client, sessionId, opts) {
99624
99647
  if (sameCount >= stablePolls) break;
99625
99648
  }
99626
99649
  }
99650
+ const finalSseError = getSessionError(sessionId);
99651
+ if (finalSseError) {
99652
+ throw new SessionErrorDetected(finalSseError);
99653
+ }
99627
99654
  const { data: finalMessages } = await client.session.messages({ path: { id: sessionId }, query });
99628
99655
  return extractLastAssistantText(finalMessages ?? []) || lastText;
99629
99656
  }