lark-coding-assistant 0.2.6 → 0.2.7

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.
@@ -3391,6 +3391,7 @@ var AssistantDaemon = class {
3391
3391
  agentSessionId: session.agentSessionId
3392
3392
  }, context.signal));
3393
3393
  await context.stage("state", () => this.commitStartedSession(session, binding));
3394
+ await this.clearSessionExitEvent(sessionId, context.startedAt);
3394
3395
  } catch (error) {
3395
3396
  return fail(isAppError(error) ? error : new AppError("START_FAILED", "failed to persist completed session", { sessionId }, { cause: error }));
3396
3397
  }
@@ -4480,6 +4481,26 @@ ${escapeFence2(output).slice(-6500)}
4480
4481
  }
4481
4482
  await this.store.saveState(this.state);
4482
4483
  }
4484
+ async clearSessionExitEvent(sessionId, before) {
4485
+ const event = this.state.recentSessionExits?.[sessionId];
4486
+ if (!event || event.occurredAt >= before) return;
4487
+ const recentSessionExits = { ...this.state.recentSessionExits };
4488
+ delete recentSessionExits[sessionId];
4489
+ this.state = { ...this.state, recentSessionExits, updatedAt: Date.now() };
4490
+ await this.store.saveState(this.state);
4491
+ }
4492
+ async rememberSessionExitEvent(event) {
4493
+ const cutoff = Date.now() - 24 * 60 * 60 * 1e3;
4494
+ const recentSessionExits = Object.fromEntries(Object.entries(this.state.recentSessionExits ?? {}).filter(([, value]) => value.occurredAt >= cutoff));
4495
+ recentSessionExits[event.sessionId] = event;
4496
+ const retained = Object.entries(recentSessionExits).sort(([, left], [, right]) => right.occurredAt - left.occurredAt).slice(0, 20);
4497
+ this.state = {
4498
+ ...this.state,
4499
+ recentSessionExits: Object.fromEntries(retained),
4500
+ updatedAt: Date.now()
4501
+ };
4502
+ await this.store.saveState(this.state);
4503
+ }
4483
4504
  async resetOwner() {
4484
4505
  this.pendingMessages.length = 0;
4485
4506
  this.pendingInteractionInput = void 0;
@@ -4640,7 +4661,7 @@ ${escapeFence2(output).slice(-6500)}
4640
4661
  `agent session conflict: session=${candidate.sessionId} agent=${candidate.agent} agentSession=${candidate.agentSessionId} owner=${owner.id}`
4641
4662
  );
4642
4663
  setTimeout(() => void this.rejectDuplicateAgentSession(candidate, owner), 100);
4643
- return fail(agentSessionInUse(candidate.sessionId, owner.id));
4664
+ return fail(agentSessionInUse(candidate.sessionId, owner.id, candidate.agentSessionId));
4644
4665
  }
4645
4666
  if (!session) {
4646
4667
  this.pendingAgentSessionClaims.set(candidate.sessionId, candidate);
@@ -4749,7 +4770,7 @@ ${escapeFence2(output).slice(-6500)}
4749
4770
  const owner = this.findAgentSessionOwner(candidate.agent, candidate.agentSessionId, session.id);
4750
4771
  if (owner) {
4751
4772
  this.pendingAgentSessionClaims.delete(session.id);
4752
- return fail(agentSessionInUse(session.id, owner.id));
4773
+ return fail(agentSessionInUse(session.id, owner.id, candidate.agentSessionId));
4753
4774
  }
4754
4775
  session.agentSessionId = candidate.agentSessionId;
4755
4776
  session.updatedAt = Date.now();
@@ -4787,6 +4808,14 @@ ${escapeFence2(output).slice(-6500)}
4787
4808
  return pending ? { id: pending.sessionId } : void 0;
4788
4809
  }
4789
4810
  async rejectDuplicateAgentSession(candidate, owner) {
4811
+ await this.rememberSessionExitEvent({
4812
+ sessionId: candidate.sessionId,
4813
+ agent: candidate.agent,
4814
+ reason: "agent-session-conflict",
4815
+ agentSessionId: candidate.agentSessionId,
4816
+ ownerSessionId: owner.id,
4817
+ occurredAt: Date.now()
4818
+ });
4790
4819
  const duplicate = this.state.sessions?.[candidate.sessionId];
4791
4820
  if (duplicate) await this.stopSession(duplicate.id).catch((error) => this.log(
4792
4821
  `failed to stop duplicate agent session ${duplicate.id}: ${errorMessage3(error)}`
@@ -4799,7 +4828,7 @@ ${escapeFence2(output).slice(-6500)}
4799
4828
  if (this.state.boundChatId) {
4800
4829
  await this.gateway?.sendText(
4801
4830
  this.state.boundChatId,
4802
- `${candidate.agent} \u539F\u751F session \u5DF2\u7531 LCA session\u300C${owner.id}\u300D\u8FDE\u63A5\uFF1B\u5DF2\u505C\u6B62\u91CD\u590D\u521B\u5EFA\u7684\u300C${candidate.sessionId}\u300D\u3002\u8BF7\u7528 /sessions \u8FDE\u63A5\u300C${owner.id}\u300D\u3002`
4831
+ `${candidate.agent} \u539F\u751F session\u300C${candidate.agentSessionId}\u300D\u5DF2\u7531 LCA session\u300C${owner.id}\u300D\u8FDE\u63A5\uFF1B\u5DF2\u505C\u6B62\u91CD\u590D\u521B\u5EFA\u7684\u300C${candidate.sessionId}\u300D\u3002\u8BF7\u7528 /sessions \u8FDE\u63A5\u300C${owner.id}\u300D\u3002`
4803
4832
  ).catch((error) => this.log(`agent session conflict notification failed: ${errorMessage3(error)}`));
4804
4833
  }
4805
4834
  }
@@ -5035,11 +5064,11 @@ function abortableDelay(ms, signal) {
5035
5064
  signal.addEventListener("abort", aborted, { once: true });
5036
5065
  });
5037
5066
  }
5038
- function agentSessionInUse(sessionId, ownerSessionId) {
5067
+ function agentSessionInUse(sessionId, ownerSessionId, agentSessionId) {
5039
5068
  return new AppError(
5040
5069
  "AGENT_SESSION_IN_USE",
5041
5070
  `agent session is already managed by ${ownerSessionId}`,
5042
- { sessionId, ownerSessionId }
5071
+ { sessionId, ownerSessionId, agentSessionId }
5043
5072
  );
5044
5073
  }
5045
5074
  function errorMessage3(error) {