@hwj123weijian/pi-feishu 0.10.1 → 0.10.2

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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/extension.ts +28 -15
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hwj123weijian/pi-feishu",
3
- "version": "0.10.1",
3
+ "version": "0.10.2",
4
4
  "description": "Feishu private-chat and managed-group bridge for Pi",
5
5
  "type": "module",
6
6
  "license": "MIT",
package/src/extension.ts CHANGED
@@ -35,8 +35,13 @@ interface SharedFeishuState {
35
35
  mainSessionFile: string | undefined;
36
36
  /** Pi 进程当前所在的会话文件,随每个事件刷新。 */
37
37
  currentSessionFile: string | undefined;
38
- /** 群绑定相关 switch/newSession 进行中的标记:期间出现的会话文件不得记为主会话。 */
39
- bindingGroupChat: boolean;
38
+ /**
39
+ * 本扩展发起的 switch/newSession 进行中的标记:
40
+ * - 期间出现的会话文件不得记为主会话;
41
+ * - Pi 对旧会话发出的 session_shutdown 是我们自己引起的,
42
+ * 不能据此取消正在等待的飞书轮次(否则群消息必然失败)。
43
+ */
44
+ switchingSession: boolean;
40
45
  }
41
46
 
42
47
  const SHARED_STATE_KEY = "__piFeishuSharedState__";
@@ -58,7 +63,7 @@ function getSharedState(): SharedFeishuState {
58
63
  sendCurrentMessage: undefined,
59
64
  mainSessionFile: undefined,
60
65
  currentSessionFile: undefined,
61
- bindingGroupChat: false,
66
+ switchingSession: false,
62
67
  controller: undefined as unknown as FeishuController,
63
68
  };
64
69
  const proxyAgent: AgentBridge = {
@@ -85,7 +90,7 @@ function getSharedState(): SharedFeishuState {
85
90
  newChatSession: async (chatId) => {
86
91
  const context = state.latestCommandContext;
87
92
  if (!context) return false;
88
- state.bindingGroupChat = true;
93
+ state.switchingSession = true;
89
94
  try {
90
95
  const result = await context.newSession({
91
96
  withSession: async (nextContext) => {
@@ -96,7 +101,7 @@ function getSharedState(): SharedFeishuState {
96
101
  });
97
102
  return !result.cancelled;
98
103
  } finally {
99
- state.bindingGroupChat = false;
104
+ state.switchingSession = false;
100
105
  }
101
106
  },
102
107
  setThinkingLevel: (level) => state.current?.runtime.setThinkingLevel(level) ?? Promise.resolve(false),
@@ -124,7 +129,7 @@ function observeSessionFile(state: SharedFeishuState, context: ExtensionContext)
124
129
  const file = tryGetSessionFile(context);
125
130
  if (!file) return;
126
131
  state.currentSessionFile = file;
127
- if (state.bindingGroupChat) return;
132
+ if (state.switchingSession) return;
128
133
  if (state.controller.isGroupSessionFile(file)) return;
129
134
  state.mainSessionFile = file;
130
135
  }
@@ -157,20 +162,25 @@ async function sendToMainSession(state: SharedFeishuState, prompt: string): Prom
157
162
  // 主会话与当前会话不一致却没有命令上下文:直发会串进群会话,给出可操作的错误更安全。
158
163
  throw new Error("Pi 会话控制尚未就绪,请先在本地执行一次 /feishu status。");
159
164
  }
160
- const result = await context.switchSession(main, {
161
- withSession: async (nextContext) => {
162
- state.latestCommandContext = nextContext;
163
- await nextContext.sendUserMessage(prompt);
164
- },
165
- });
166
- if (result.cancelled) throw new Error("切回主 Pi 会话已取消。");
165
+ state.switchingSession = true;
166
+ try {
167
+ const result = await context.switchSession(main, {
168
+ withSession: async (nextContext) => {
169
+ state.latestCommandContext = nextContext;
170
+ await nextContext.sendUserMessage(prompt);
171
+ },
172
+ });
173
+ if (result.cancelled) throw new Error("切回主 Pi 会话已取消。");
174
+ } finally {
175
+ state.switchingSession = false;
176
+ }
167
177
  }
168
178
 
169
179
  async function sendToChatSession(state: SharedFeishuState, chatId: string, prompt: string): Promise<void> {
170
180
  const context = state.latestCommandContext;
171
181
  if (!context) throw new Error("Pi 会话控制尚未就绪,请先在本地执行一次 /feishu status。");
172
182
 
173
- state.bindingGroupChat = true;
183
+ state.switchingSession = true;
174
184
  try {
175
185
  const sessionFile = state.controller.getChatSessionFile(chatId);
176
186
  if (sessionFile) {
@@ -197,7 +207,7 @@ async function sendToChatSession(state: SharedFeishuState, chatId: string, promp
197
207
  });
198
208
  if (result.cancelled) throw new Error("创建飞书群专属 Pi 会话已取消。");
199
209
  } finally {
200
- state.bindingGroupChat = false;
210
+ state.switchingSession = false;
201
211
  }
202
212
  }
203
213
 
@@ -489,6 +499,9 @@ export default function feishuExtension(pi: ExtensionAPI): void {
489
499
  });
490
500
  pi.on("session_shutdown", () => {
491
501
  // 长连接归全局 controller 保管,本地 /new 切换会话后自动延续。
502
+ // 本扩展为群/私聊路由发起的 switch/newSession 会让 Pi 对旧会话发 shutdown;
503
+ // 那不是真正的会话关闭,此刻轮次刚要开始,绝不能取消,否则回复永远传不回飞书。
504
+ if (state.switchingSession) return;
492
505
  state.activeBridge?.cancel("Pi 会话已关闭。");
493
506
  });
494
507