@hwj123weijian/pi-feishu 0.12.0 → 0.12.1

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/group-agent.ts +39 -9
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hwj123weijian/pi-feishu",
3
- "version": "0.12.0",
3
+ "version": "0.12.1",
4
4
  "description": "Feishu private-chat and managed-group bridge for Pi",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -20,9 +20,16 @@ export interface GroupAgentRunOptions {
20
20
 
21
21
  const DEFAULT_TIMEOUT_MS = 15 * 60 * 1000;
22
22
 
23
+ interface AssistantStreamEvent {
24
+ type?: string;
25
+ delta?: string;
26
+ contentIndex?: number;
27
+ }
28
+
23
29
  interface PrintEvent {
24
30
  type?: string;
25
31
  message?: { role?: string; content?: unknown };
32
+ assistantMessageEvent?: AssistantStreamEvent;
26
33
  toolName?: string;
27
34
  }
28
35
 
@@ -80,6 +87,7 @@ export class GroupAgentRunner {
80
87
  let stdoutBuffer = "";
81
88
  let stderrBuffer = "";
82
89
  let latestAssistantText = "";
90
+ let streamedText = "";
83
91
  let settled = false;
84
92
  const timer = setTimeout(() => {
85
93
  child.kill("SIGTERM");
@@ -97,14 +105,21 @@ export class GroupAgentRunner {
97
105
  resolve({ text: latestAssistantText, exitCode: child.exitCode });
98
106
  };
99
107
 
108
+ const emitText = (text: string) => {
109
+ latestAssistantText = text;
110
+ observer?.onText?.(text);
111
+ };
112
+
100
113
  child.stdout?.on("data", (chunk: Buffer) => {
101
114
  stdoutBuffer += chunk.toString("utf8");
102
115
  let newlineIndex = stdoutBuffer.indexOf("\n");
103
116
  while (newlineIndex !== -1) {
104
117
  const line = stdoutBuffer.slice(0, newlineIndex).trim();
105
118
  stdoutBuffer = stdoutBuffer.slice(newlineIndex + 1);
106
- this.handleJsonLine(line, observer, (text) => {
107
- latestAssistantText = text;
119
+ this.handleJsonLine(line, observer, emitText, () => {
120
+ streamedText = "";
121
+ }, () => streamedText, (next) => {
122
+ streamedText = next;
108
123
  });
109
124
  newlineIndex = stdoutBuffer.indexOf("\n");
110
125
  }
@@ -117,7 +132,7 @@ export class GroupAgentRunner {
117
132
  });
118
133
  child.on("close", (code) => {
119
134
  if (code === 0) {
120
- observer?.onText?.(latestAssistantText);
135
+ if (!latestAssistantText && streamedText) emitText(streamedText);
121
136
  finish();
122
137
  return;
123
138
  }
@@ -130,7 +145,10 @@ export class GroupAgentRunner {
130
145
  private handleJsonLine(
131
146
  line: string,
132
147
  observer: AgentProgressObserver | undefined,
133
- setLatest: (text: string) => void,
148
+ emitText: (text: string) => void,
149
+ resetStream: () => void,
150
+ getStream: () => string,
151
+ setStream: (text: string) => void,
134
152
  ): void {
135
153
  if (!line) return;
136
154
  let event: PrintEvent;
@@ -144,11 +162,23 @@ export class GroupAgentRunner {
144
162
  observer?.onActivity?.({ kind: "tool", toolName });
145
163
  return;
146
164
  }
147
- if (event.type !== "message_update" || event.message?.role !== "assistant") return;
148
- const text = extractText(event.message.content);
149
- if (text) {
150
- setLatest(text);
151
- observer?.onText?.(text);
165
+ // 实测事件形状:message_update 携带 assistantMessageEvent(text_start/text_delta/text_end),
166
+ // 完整的助手文本在 message_end.message.content 里(权威值,用于最终回复)。
167
+ if (event.type === "message_update") {
168
+ const streamEvent = event.assistantMessageEvent;
169
+ if (streamEvent?.type === "text_start") {
170
+ resetStream();
171
+ return;
172
+ }
173
+ if (streamEvent?.type === "text_delta" && typeof streamEvent.delta === "string") {
174
+ setStream(getStream() + streamEvent.delta);
175
+ emitText(getStream());
176
+ }
177
+ return;
178
+ }
179
+ if (event.type === "message_end" && event.message?.role === "assistant") {
180
+ const text = extractText(event.message.content);
181
+ if (text) emitText(text);
152
182
  }
153
183
  }
154
184
  }