@meetopenbot/pi 0.1.1 → 0.1.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.
- package/dist/runtime.js +2 -7
- package/dist/stream.js +35 -55
- package/package.json +2 -2
package/dist/runtime.js
CHANGED
|
@@ -1,17 +1,12 @@
|
|
|
1
1
|
import { resolveConfig } from './config.js';
|
|
2
|
-
import { remapPiError } from './credits.js';
|
|
3
2
|
import { getOrCreatePiSession } from './session.js';
|
|
4
3
|
import { runPiPrompt } from './stream.js';
|
|
5
|
-
export async function runPiTurn({ prompt, handlerCtx, context }) {
|
|
4
|
+
export async function* runPiTurn({ prompt, handlerCtx, context, }) {
|
|
6
5
|
const config = resolveConfig(context, handlerCtx.state.channelDetails?.cwd);
|
|
7
6
|
const { session } = await getOrCreatePiSession({
|
|
8
7
|
config,
|
|
9
8
|
state: handlerCtx.state,
|
|
10
9
|
storage: context.storage,
|
|
11
10
|
});
|
|
12
|
-
|
|
13
|
-
if (text.startsWith('Pi error: ')) {
|
|
14
|
-
return `Pi error: ${remapPiError(text.slice('Pi error: '.length))}`;
|
|
15
|
-
}
|
|
16
|
-
return text;
|
|
11
|
+
yield* runPiPrompt(session, prompt, { streaming: session.isStreaming });
|
|
17
12
|
}
|
package/dist/stream.js
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
|
+
import { createTextReplyBuffer, textReply, yieldFromBackgroundQueue, } from '@meetopenbot/plugin-sdk';
|
|
2
|
+
import { remapPiError } from './credits.js';
|
|
1
3
|
const isAssistantMessage = (message) => message.role === 'assistant';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
20
|
-
if (event.type === 'agent_end') {
|
|
21
|
-
const lastAssistant = [...event.messages].reverse().find(isAssistantMessage);
|
|
22
|
-
if (lastAssistant?.stopReason === 'error' && lastAssistant.errorMessage?.trim()) {
|
|
23
|
-
result = `Pi error: ${lastAssistant.errorMessage.trim()}`;
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
result = assistantText;
|
|
27
|
-
}
|
|
28
|
-
finished = true;
|
|
29
|
-
wakeUp();
|
|
4
|
+
export const classifyPiEvent = (event) => {
|
|
5
|
+
if (event.type === 'message_update') {
|
|
6
|
+
const assistantEvent = event.assistantMessageEvent;
|
|
7
|
+
if (assistantEvent.type === 'text_delta')
|
|
8
|
+
return { type: 'delta', text: assistantEvent.delta };
|
|
9
|
+
return { type: 'skip' };
|
|
10
|
+
}
|
|
11
|
+
if (event.type === 'message_end')
|
|
12
|
+
return { type: 'flush' };
|
|
13
|
+
return { type: 'skip' };
|
|
14
|
+
};
|
|
15
|
+
function* consumePiEvent(event, replies) {
|
|
16
|
+
if (event.type === 'agent_end') {
|
|
17
|
+
yield* replies.end();
|
|
18
|
+
const lastAssistant = [...event.messages].reverse().find(isAssistantMessage);
|
|
19
|
+
if (lastAssistant?.stopReason === 'error' && lastAssistant.errorMessage?.trim()) {
|
|
20
|
+
yield textReply(`Pi error: ${remapPiError(lastAssistant.errorMessage.trim())}`);
|
|
30
21
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
yield* replies.apply(classifyPiEvent(event));
|
|
25
|
+
}
|
|
26
|
+
/** Run a Pi prompt and yield each completed assistant turn. */
|
|
27
|
+
export async function* runPiPrompt(session, prompt, options) {
|
|
28
|
+
const replies = createTextReplyBuffer();
|
|
29
|
+
yield* yieldFromBackgroundQueue(async (enqueue) => {
|
|
30
|
+
const unsubscribe = session.subscribe((event) => {
|
|
31
|
+
for (const item of consumePiEvent(event, replies))
|
|
32
|
+
enqueue(item);
|
|
33
|
+
});
|
|
34
34
|
try {
|
|
35
35
|
if (options?.streaming && session.isStreaming) {
|
|
36
36
|
await session.followUp(prompt);
|
|
@@ -39,30 +39,10 @@ export async function runPiPrompt(session, prompt, options) {
|
|
|
39
39
|
await session.prompt(prompt);
|
|
40
40
|
}
|
|
41
41
|
}
|
|
42
|
-
catch (err) {
|
|
43
|
-
error = err instanceof Error ? err : new Error(String(err));
|
|
44
|
-
}
|
|
45
42
|
finally {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
})();
|
|
50
|
-
try {
|
|
51
|
-
while (!finished) {
|
|
52
|
-
await new Promise((resolve) => {
|
|
53
|
-
if (finished) {
|
|
54
|
-
resolve();
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
wake = resolve;
|
|
58
|
-
});
|
|
43
|
+
unsubscribe();
|
|
44
|
+
for (const item of replies.end())
|
|
45
|
+
enqueue(item);
|
|
59
46
|
}
|
|
60
|
-
|
|
61
|
-
if (error)
|
|
62
|
-
throw error;
|
|
63
|
-
return result.trim();
|
|
64
|
-
}
|
|
65
|
-
finally {
|
|
66
|
-
unsubscribe();
|
|
67
|
-
}
|
|
47
|
+
});
|
|
68
48
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meetopenbot/pi",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "OpenBot agent plugin powered by the Pi coding agent SDK.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@earendil-works/pi-ai": "^0.79.1",
|
|
23
23
|
"@earendil-works/pi-coding-agent": "^0.79.1",
|
|
24
|
-
"@meetopenbot/plugin-sdk": "^0.
|
|
24
|
+
"@meetopenbot/plugin-sdk": "^0.4.0"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"@types/node": "^25.9.2",
|