@relaymessenger/pi 0.1.4-staging.12 → 0.1.4-staging.14
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/README.md +16 -0
- package/dist/index.js +15 -5
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -15,3 +15,19 @@ pi install npm:@relaymessenger/pi
|
|
|
15
15
|
|
|
16
16
|
Set `RELAY_AGENT_TOKEN` before using `/relay-connect`. Set
|
|
17
17
|
`RELAY_BASE_URL` when the Agent belongs to a non-default API environment.
|
|
18
|
+
|
|
19
|
+
## Selection, coming soon
|
|
20
|
+
|
|
21
|
+
These are local candidate sources, not a claim that the published package or
|
|
22
|
+
hosted API supports selection yet.
|
|
23
|
+
|
|
24
|
+
End the final Pi answer with a `selection` JSON fence after the question.
|
|
25
|
+
The RPC prompt preserves ordered rich parts, `selected_values`, and `reply_to`
|
|
26
|
+
as data. FULL sync still fails closed rather than discarding skipped context.
|
|
27
|
+
|
|
28
|
+
New human reply text is literal `• ` + each selected source label joined with
|
|
29
|
+
`\n`, followed by `selection_response` metadata in source-option order. Dispatch
|
|
30
|
+
with `selected_values` and the explicit source target, never label parsing.
|
|
31
|
+
Exact legacy comma-joined text remains a server compatibility input. Tapping a
|
|
32
|
+
selected option deselects it locally; the sole submit action is a centered
|
|
33
|
+
compact light-blue Send button. iOS checked circles are presentation only.
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import { createInterface } from "node:readline";
|
|
3
|
-
import Relay, { BUTTONS_BLOCK_INSTRUCTION, BUTTONS_GUIDANCE, LINK_LINE_INSTRUCTION, answerMessages as splitAnswer, } from "@relaymessenger/sdk";
|
|
3
|
+
import Relay, { BUTTONS_BLOCK_INSTRUCTION, BUTTONS_GUIDANCE, selectionReply, selectionReplyContext, SELECTION_GUIDANCE, SELECTION_BLOCK_INSTRUCTION, LINK_LINE_INSTRUCTION, answerMessages as splitAnswer, } from "@relaymessenger/sdk";
|
|
4
4
|
class ChildPiProcess {
|
|
5
5
|
#child;
|
|
6
6
|
constructor(command, args) { this.#child = spawn(command, [...args], { stdio: ["pipe", "pipe", "pipe"] }); this.#child.stderr.resume(); }
|
|
@@ -11,16 +11,22 @@ class ChildPiProcess {
|
|
|
11
11
|
const textFromEvent = (event) => {
|
|
12
12
|
if (event.event_type !== "message.received" || event.data.direction !== "inbound")
|
|
13
13
|
return null;
|
|
14
|
-
|
|
14
|
+
const text = event.data.parts
|
|
15
15
|
.flatMap((part) => part.type === "text" || part.type === "link" ? [part.value] : [])
|
|
16
|
-
.join("\n").trim()
|
|
16
|
+
.join("\n").trim();
|
|
17
|
+
const context = selectionReplyContext(selectionReply(event.data.parts, event.data.reply_to), {
|
|
18
|
+
parts: event.data.parts, ...(event.data.reply_to ? { reply_to: event.data.reply_to } : {}),
|
|
19
|
+
});
|
|
20
|
+
if (!text && !context)
|
|
21
|
+
return null;
|
|
22
|
+
return [text, context].filter(Boolean).join("\n\n");
|
|
17
23
|
};
|
|
18
24
|
/**
|
|
19
25
|
* The prompt pi is given for one message: the words, then how to answer.
|
|
20
26
|
* This process sends pi's final text for it, and the same buttons and link
|
|
21
27
|
* rules every other runtime carries.
|
|
22
28
|
*/
|
|
23
|
-
export const piPrompt = (message) => `${message}\n\nWrite your answer as your final message. Relay sends that answer to the chat for you, so do not send it yourself. Write chat text. Inline Markdown draws: bold, italic, strikethrough, code, links. Headings, lists and code fences show as written.\n\n${BUTTONS_BLOCK_INSTRUCTION} ${LINK_LINE_INSTRUCTION} ${BUTTONS_GUIDANCE}`;
|
|
29
|
+
export const piPrompt = (message) => `${message}\n\nWrite your answer as your final message. Relay sends that answer to the chat for you, so do not send it yourself. Write chat text. Inline Markdown draws: bold, italic, strikethrough, code, links. Headings, lists and code fences show as written.\n\n${BUTTONS_BLOCK_INSTRUCTION} ${LINK_LINE_INSTRUCTION} ${BUTTONS_GUIDANCE} ${SELECTION_BLOCK_INSTRUCTION} ${SELECTION_GUIDANCE}`;
|
|
24
30
|
/**
|
|
25
31
|
* The messages an answer becomes: each link written alone on a line as its
|
|
26
32
|
* own message, text in chunks the API takes, and the buttons its fenced block
|
|
@@ -123,6 +129,10 @@ export class PiChannel {
|
|
|
123
129
|
stop() { for (const session of this.#sessions.values())
|
|
124
130
|
session.stop(); this.#sessions.clear(); }
|
|
125
131
|
async #handle(event, signal) {
|
|
132
|
+
// Concurrent redelivery must await the original handoff, not ACK early.
|
|
133
|
+
const inflight = this.#inflight.get(event.event_id);
|
|
134
|
+
if (inflight)
|
|
135
|
+
return inflight;
|
|
126
136
|
if (this.#seen.has(event.event_id))
|
|
127
137
|
return;
|
|
128
138
|
const message = textFromEvent(event);
|
|
@@ -164,7 +174,7 @@ export class PiChannel {
|
|
|
164
174
|
throw new Error("Pi returned no final text answer");
|
|
165
175
|
const messages = answerMessages(answer);
|
|
166
176
|
if (messages[0]?.error)
|
|
167
|
-
console.error(`Relay: the
|
|
177
|
+
console.error(`Relay: the component block in pi's answer was left as text: ${messages[0].error}.`);
|
|
168
178
|
for (const [index, message] of messages.entries())
|
|
169
179
|
await this.#relay.chats.messages.send(data.chat.id, { message: { parts: message.parts, idempotency_key: `pi-${event.event_id}-${index}` } });
|
|
170
180
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@relaymessenger/pi",
|
|
3
|
-
"version": "0.1.4-staging.
|
|
3
|
+
"version": "0.1.4-staging.14",
|
|
4
4
|
"description": "Relay Messenger channel for Pi over Relay v1 WebSocket delivery.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -34,7 +34,7 @@
|
|
|
34
34
|
"test": "vitest run"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@relaymessenger/sdk": "0.3.6-staging.
|
|
37
|
+
"@relaymessenger/sdk": "0.3.6-staging.14"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@earendil-works/pi-coding-agent": "0.86.0",
|