@lyriel/openclaw-plugin 0.3.0 → 0.4.0
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/openclaw.plugin.json +1 -0
- package/package.json +1 -1
- package/dist/api.js +0 -166
- package/dist/api.js.map +0 -1
- package/dist/inbox.js +0 -183
- package/dist/inbox.js.map +0 -1
- package/dist/index.js +0 -132
- package/dist/index.js.map +0 -1
- package/dist/pending.js +0 -106
- package/dist/pending.js.map +0 -1
- package/dist/primer.js +0 -27
- package/dist/primer.js.map +0 -1
- package/dist/surfacing.js +0 -95
- package/dist/surfacing.js.map +0 -1
- package/dist/telegram.js +0 -63
- package/dist/telegram.js.map +0 -1
- package/dist/tools.js +0 -404
- package/dist/tools.js.map +0 -1
package/openclaw.plugin.json
CHANGED
package/package.json
CHANGED
package/dist/api.js
DELETED
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
// HTTP client for Lyriel's substrate API. Uses global fetch (Node 22+).
|
|
2
|
-
//
|
|
3
|
-
// Five operations:
|
|
4
|
-
// - longPollInbox(): GET /api/inbox with Bearer auth; returns parsed dispatches
|
|
5
|
-
// - sendAsk(to, prompt): POST /api/asks; returns ask_id
|
|
6
|
-
// - sendCallback(callbackUrl, callbackToken, response): POST the per-ask
|
|
7
|
-
// callback URL embedded in an inbound dispatch envelope
|
|
8
|
-
// - sendPlan / sendPlanCallback / lockPlan: group-plan endpoints
|
|
9
|
-
//
|
|
10
|
-
// Config (apiKey, baseUrl) is passed in rather than read from env so the
|
|
11
|
-
// OpenClaw plugin manifest (openclaw.plugin.json -> configSchema) owns the
|
|
12
|
-
// source of truth and the operator edits one place.
|
|
13
|
-
export class LyrielApiError extends Error {
|
|
14
|
-
status;
|
|
15
|
-
constructor(message, status) {
|
|
16
|
-
super(message);
|
|
17
|
-
this.name = "LyrielApiError";
|
|
18
|
-
this.status = status;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
function trimSlash(s) {
|
|
22
|
-
return s.endsWith("/") ? s.slice(0, -1) : s;
|
|
23
|
-
}
|
|
24
|
-
async function request(method, url, opts = {}) {
|
|
25
|
-
const controller = new AbortController();
|
|
26
|
-
const timer = setTimeout(() => controller.abort(), opts.timeoutMs ?? 30_000);
|
|
27
|
-
try {
|
|
28
|
-
const res = await fetch(url, {
|
|
29
|
-
method,
|
|
30
|
-
headers: {
|
|
31
|
-
"content-type": "application/json",
|
|
32
|
-
...opts.headers,
|
|
33
|
-
},
|
|
34
|
-
body: opts.body === undefined ? undefined : JSON.stringify(opts.body),
|
|
35
|
-
signal: controller.signal,
|
|
36
|
-
});
|
|
37
|
-
const text = await res.text();
|
|
38
|
-
return { status: res.status, body: text };
|
|
39
|
-
}
|
|
40
|
-
finally {
|
|
41
|
-
clearTimeout(timer);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
function parseJson(body, action) {
|
|
45
|
-
try {
|
|
46
|
-
return JSON.parse(body);
|
|
47
|
-
}
|
|
48
|
-
catch (err) {
|
|
49
|
-
throw new LyrielApiError(`${action} response was not JSON: ${err.message}`);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
export async function longPollInbox(cfg, timeoutMs = 30_000) {
|
|
53
|
-
const url = `${trimSlash(cfg.baseUrl)}/api/inbox`;
|
|
54
|
-
const { status, body } = await request("GET", url, {
|
|
55
|
-
headers: { authorization: `Bearer ${cfg.apiKey}` },
|
|
56
|
-
timeoutMs,
|
|
57
|
-
});
|
|
58
|
-
if (status !== 200) {
|
|
59
|
-
throw new LyrielApiError(`Inbox poll failed (${status}): ${body.slice(0, 200)}`, status);
|
|
60
|
-
}
|
|
61
|
-
const parsed = parseJson(body, "inbox");
|
|
62
|
-
return parsed.dispatches ?? [];
|
|
63
|
-
}
|
|
64
|
-
export async function sendAsk(cfg, to, prompt) {
|
|
65
|
-
const url = `${trimSlash(cfg.baseUrl)}/api/asks`;
|
|
66
|
-
const { status, body } = await request("POST", url, {
|
|
67
|
-
headers: { authorization: `Bearer ${cfg.apiKey}` },
|
|
68
|
-
body: { to: to.replace(/^@/, ""), prompt },
|
|
69
|
-
});
|
|
70
|
-
if (status !== 200 && status !== 202) {
|
|
71
|
-
throw new LyrielApiError(`sendAsk failed (${status}): ${body.slice(0, 300)}`, status);
|
|
72
|
-
}
|
|
73
|
-
return parseJson(body, "sendAsk");
|
|
74
|
-
}
|
|
75
|
-
export async function getAsk(cfg, askId) {
|
|
76
|
-
const url = `${trimSlash(cfg.baseUrl)}/api/asks/${askId}`;
|
|
77
|
-
const { status, body } = await request("GET", url, {
|
|
78
|
-
headers: { authorization: `Bearer ${cfg.apiKey}` },
|
|
79
|
-
timeoutMs: 2_000,
|
|
80
|
-
});
|
|
81
|
-
if (status !== 200) {
|
|
82
|
-
throw new LyrielApiError(`getAsk failed (${status})`, status);
|
|
83
|
-
}
|
|
84
|
-
return parseJson(body, "getAsk");
|
|
85
|
-
}
|
|
86
|
-
export async function sendCallback(callbackUrl, callbackToken, response) {
|
|
87
|
-
const { status, body } = await request("POST", callbackUrl, {
|
|
88
|
-
headers: { authorization: `Bearer ${callbackToken}` },
|
|
89
|
-
body: { response },
|
|
90
|
-
});
|
|
91
|
-
if (status !== 200 && status !== 410) {
|
|
92
|
-
throw new LyrielApiError(`callback failed (${status}): ${body.slice(0, 300)}`, status);
|
|
93
|
-
}
|
|
94
|
-
try {
|
|
95
|
-
return JSON.parse(body);
|
|
96
|
-
}
|
|
97
|
-
catch {
|
|
98
|
-
// Some non-2xx-but-acceptable paths may return plain text — surface raw
|
|
99
|
-
// body for diagnostics rather than throw a second error.
|
|
100
|
-
return { raw: body, status };
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
export async function sendPlan(cfg, participants, description, maxMessages) {
|
|
104
|
-
const url = `${trimSlash(cfg.baseUrl)}/api/plans`;
|
|
105
|
-
const body = {
|
|
106
|
-
participants: participants.map((p) => p.replace(/^@/, "")),
|
|
107
|
-
description,
|
|
108
|
-
};
|
|
109
|
-
if (maxMessages !== undefined) {
|
|
110
|
-
body.max_messages = maxMessages;
|
|
111
|
-
}
|
|
112
|
-
const { status, body: respBody } = await request("POST", url, {
|
|
113
|
-
headers: { authorization: `Bearer ${cfg.apiKey}` },
|
|
114
|
-
body,
|
|
115
|
-
});
|
|
116
|
-
if (status !== 200 && status !== 202) {
|
|
117
|
-
throw new LyrielApiError(`sendPlan failed (${status}): ${respBody.slice(0, 300)}`, status);
|
|
118
|
-
}
|
|
119
|
-
return parseJson(respBody, "sendPlan");
|
|
120
|
-
}
|
|
121
|
-
export async function sendPlanCallback(callbackUrl, callbackToken, content, staySilent) {
|
|
122
|
-
const body = { content };
|
|
123
|
-
if (staySilent) {
|
|
124
|
-
body.stay_silent = true;
|
|
125
|
-
}
|
|
126
|
-
const { status, body: respBody } = await request("POST", callbackUrl, {
|
|
127
|
-
headers: { authorization: `Bearer ${callbackToken}` },
|
|
128
|
-
body,
|
|
129
|
-
});
|
|
130
|
-
if (status !== 200 && status !== 409) {
|
|
131
|
-
throw new LyrielApiError(`plan callback failed (${status}): ${respBody.slice(0, 300)}`, status);
|
|
132
|
-
}
|
|
133
|
-
try {
|
|
134
|
-
return JSON.parse(respBody);
|
|
135
|
-
}
|
|
136
|
-
catch {
|
|
137
|
-
return { raw: respBody, status };
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
export async function updateProfile(cfg, fields) {
|
|
141
|
-
const url = `${trimSlash(cfg.baseUrl)}/api/me/profile`;
|
|
142
|
-
const { status, body: respBody } = await request("PATCH", url, {
|
|
143
|
-
headers: { authorization: `Bearer ${cfg.apiKey}` },
|
|
144
|
-
body: fields,
|
|
145
|
-
});
|
|
146
|
-
if (status !== 200) {
|
|
147
|
-
throw new LyrielApiError(`updateProfile failed (${status}): ${respBody.slice(0, 300)}`, status);
|
|
148
|
-
}
|
|
149
|
-
return parseJson(respBody, "updateProfile");
|
|
150
|
-
}
|
|
151
|
-
export async function lockPlan(cfg, planId, summary, details) {
|
|
152
|
-
const url = `${trimSlash(cfg.baseUrl)}/api/plans/${planId}/lock`;
|
|
153
|
-
const body = { summary };
|
|
154
|
-
if (details) {
|
|
155
|
-
body.details = details;
|
|
156
|
-
}
|
|
157
|
-
const { status, body: respBody } = await request("POST", url, {
|
|
158
|
-
headers: { authorization: `Bearer ${cfg.apiKey}` },
|
|
159
|
-
body,
|
|
160
|
-
});
|
|
161
|
-
if (status !== 200) {
|
|
162
|
-
throw new LyrielApiError(`lockPlan failed (${status}): ${respBody.slice(0, 300)}`, status);
|
|
163
|
-
}
|
|
164
|
-
return parseJson(respBody, "lockPlan");
|
|
165
|
-
}
|
|
166
|
-
//# sourceMappingURL=api.js.map
|
package/dist/api.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api.js","sourceRoot":"","sources":["../api.ts"],"names":[],"mappings":"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"}
|
package/dist/inbox.js
DELETED
|
@@ -1,183 +0,0 @@
|
|
|
1
|
-
// Background long-poll: hits Lyriel /api/inbox in a recursive setTimeout
|
|
2
|
-
// loop, then routes each dispatch by direction:
|
|
3
|
-
//
|
|
4
|
-
// - dispatch / forward (1:1 asks) — surface to the user via Telegram
|
|
5
|
-
// push (if configured) or next-turn injection into the active
|
|
6
|
-
// OpenClaw session.
|
|
7
|
-
//
|
|
8
|
-
// - plan rounds (non-terminal) — schedule a background agent turn
|
|
9
|
-
// via api.session.workflow.scheduleSessionTurn with deliveryMode:
|
|
10
|
-
// "none". The user is NOT shown the round; their agent processes
|
|
11
|
-
// it autonomously, calls lyriel_plan_reply, and the loop moves
|
|
12
|
-
// on. Load-bearing for agent-mediated plan coordination — users
|
|
13
|
-
// see the lock outcome, not the back-and-forth.
|
|
14
|
-
//
|
|
15
|
-
// - plan_locked / plan_cancelled — surface (final outcome the user
|
|
16
|
-
// needs to see).
|
|
17
|
-
//
|
|
18
|
-
// - friend events — surface (user needs to know).
|
|
19
|
-
//
|
|
20
|
-
// Lifecycle: started on the `gateway_start` plugin hook, stopped on
|
|
21
|
-
// `gateway_stop`. Loop control state lives on a `state` object (rather than
|
|
22
|
-
// a captured `let`) so static analysis can see that the start/stop methods
|
|
23
|
-
// mutate the condition the while-loop reads.
|
|
24
|
-
import * as api from "./api.js";
|
|
25
|
-
import * as pending from "./pending.js";
|
|
26
|
-
import { formatDispatch } from "./surfacing.js";
|
|
27
|
-
import { sendTelegramMessage } from "./telegram.js";
|
|
28
|
-
const RECONNECT_BACKOFF_MS = 5_000;
|
|
29
|
-
const INBOX_TIMEOUT_MS = 30_000;
|
|
30
|
-
const POLL_INTERVAL_AFTER_BATCH_MS = 500;
|
|
31
|
-
// Prepended to every plan-round dispatch before handing to the LLM.
|
|
32
|
-
// Tight wording — every token is paid for on every plan round.
|
|
33
|
-
// Mirror of BACKGROUND_PROMPT_PREFIX in
|
|
34
|
-
// clients/hermes-plugin/lyriel_hermes/background.py. Kept in sync by
|
|
35
|
-
// convention; if either drifts, cross-runtime plan behavior drifts.
|
|
36
|
-
export const BACKGROUND_PROMPT_PREFIX = "[Lyriel background plan turn. Your user is NOT watching this turn " +
|
|
37
|
-
"and you must not ask them clarifying questions. Use what you " +
|
|
38
|
-
"already know about them; if a constraint is missing, accept wide " +
|
|
39
|
-
"constraints and let other participants narrow. Respond by calling " +
|
|
40
|
-
"the lyriel_plan_reply tool concisely (stay_silent=true if you " +
|
|
41
|
-
"have nothing to add). Do not produce filler text.]\n\n";
|
|
42
|
-
export function createInboxRunner(opts) {
|
|
43
|
-
const state = { running: false, currentLoop: null };
|
|
44
|
-
async function pollOnce() {
|
|
45
|
-
return api.longPollInbox(opts.client, INBOX_TIMEOUT_MS);
|
|
46
|
-
}
|
|
47
|
-
async function loop() {
|
|
48
|
-
opts.logger.info(`lyriel inbox poll loop started (base=${opts.client.baseUrl})`);
|
|
49
|
-
while (state.running) {
|
|
50
|
-
let dispatches = [];
|
|
51
|
-
try {
|
|
52
|
-
dispatches = await pollOnce();
|
|
53
|
-
}
|
|
54
|
-
catch (err) {
|
|
55
|
-
if (!state.running) {
|
|
56
|
-
break;
|
|
57
|
-
}
|
|
58
|
-
opts.logger.warn(`inbox poll error: ${err.message}`);
|
|
59
|
-
await sleep(RECONNECT_BACKOFF_MS, () => state.running);
|
|
60
|
-
continue;
|
|
61
|
-
}
|
|
62
|
-
for (const d of dispatches) {
|
|
63
|
-
const askId = d.ask_id;
|
|
64
|
-
const planId = d.plan_id;
|
|
65
|
-
const direction = d.direction ?? "?";
|
|
66
|
-
const promptText = d.prompt ?? "";
|
|
67
|
-
const correlation = planId ?? askId ?? "?";
|
|
68
|
-
if (direction === "dispatch" && askId) {
|
|
69
|
-
if (!pending.rememberAsk(askId, promptText)) {
|
|
70
|
-
opts.logger.warn(`could not extract callback URL/token for ask ${askId} — user replies will fail`);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
if (direction === "plan" && planId) {
|
|
74
|
-
if (!pending.rememberPlan(planId, promptText)) {
|
|
75
|
-
const isLocked = promptText.includes("[Lyriel group plan — LOCKED]");
|
|
76
|
-
if (!isLocked) {
|
|
77
|
-
opts.logger.warn(`could not extract callback for plan ${planId} — user contributions will fail`);
|
|
78
|
-
}
|
|
79
|
-
else {
|
|
80
|
-
pending.forgetPlan(planId);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
// Synchronous-completion suppression. If lyriel_send_ask absorbed
|
|
85
|
-
// the response inline (system_responder case — @lyriel responds
|
|
86
|
-
// instantly), skip the duplicate forward surface.
|
|
87
|
-
if (direction === "forward" && askId && pending.wasAbsorbed(askId)) {
|
|
88
|
-
opts.logger.info(`skipped forward ask_id=${askId} (already absorbed by tool)`);
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
// Plan-round dispatches: handle in a background agent turn
|
|
92
|
-
// without surfacing to the user. scheduleSessionTurn with
|
|
93
|
-
// deliveryMode="none" fires the LLM with the round prompt;
|
|
94
|
-
// the agent picks up lyriel_plan_reply via its toolset and
|
|
95
|
-
// responds autonomously. Plan_locked / plan_cancelled ARE
|
|
96
|
-
// surfaced (terminal outcomes the user needs to see).
|
|
97
|
-
if (direction === "plan" && planId) {
|
|
98
|
-
const isTerminal = promptText.includes("[Lyriel group plan — LOCKED]") ||
|
|
99
|
-
promptText.includes("[Lyriel group plan — CANCELLED]");
|
|
100
|
-
if (!isTerminal) {
|
|
101
|
-
const bgSession = opts.resolveSurfaceSession();
|
|
102
|
-
if (!bgSession) {
|
|
103
|
-
opts.logger.warn(`no session available for background plan turn plan_id=${planId} — round will go unanswered until user engages the agent`);
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
try {
|
|
107
|
-
await opts.scheduleBackgroundTurn({
|
|
108
|
-
sessionKey: bgSession,
|
|
109
|
-
message: BACKGROUND_PROMPT_PREFIX + promptText,
|
|
110
|
-
});
|
|
111
|
-
opts.logger.info(`scheduled background plan turn for plan_id=${planId} on session ${bgSession}`);
|
|
112
|
-
}
|
|
113
|
-
catch (err) {
|
|
114
|
-
opts.logger.error(`background plan turn failed for plan_id=${planId}: ${err.message}`);
|
|
115
|
-
}
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
const surfaceText = formatDispatch(d);
|
|
120
|
-
// Path A — proactive Telegram push (preferred). Matches the Hermes
|
|
121
|
-
// plugin's "1 bot, 1 chat" UX: the dispatch lands in the user's
|
|
122
|
-
// chat as a real push notification, with no need to engage the
|
|
123
|
-
// agent first.
|
|
124
|
-
const tg = opts.resolveTelegramSurface();
|
|
125
|
-
if (tg.botToken && tg.chatId) {
|
|
126
|
-
const result = await sendTelegramMessage(tg, surfaceText);
|
|
127
|
-
if (result.ok) {
|
|
128
|
-
opts.logger.info(`surfaced ${direction} id=${correlation} via Telegram chat ${tg.chatId}`);
|
|
129
|
-
continue;
|
|
130
|
-
}
|
|
131
|
-
opts.logger.warn(`Telegram push for ${direction} id=${correlation} failed: ${result.error ?? "unknown"} — falling back to next-turn injection`);
|
|
132
|
-
}
|
|
133
|
-
// Path B — next-turn injection fallback. Used when Telegram isn't
|
|
134
|
-
// configured or push failed. User has to engage the agent for the
|
|
135
|
-
// dispatch to surface.
|
|
136
|
-
const sessionKey = opts.resolveSurfaceSession();
|
|
137
|
-
if (!sessionKey) {
|
|
138
|
-
opts.logger.warn(`no surface available for ${direction} id=${correlation} — dispatch claimed but won't surface until user engages the agent or Telegram is configured`);
|
|
139
|
-
continue;
|
|
140
|
-
}
|
|
141
|
-
try {
|
|
142
|
-
await opts.inject({ sessionKey, text: surfaceText });
|
|
143
|
-
opts.logger.info(`surfaced ${direction} id=${correlation} into session ${sessionKey}`);
|
|
144
|
-
}
|
|
145
|
-
catch (err) {
|
|
146
|
-
opts.logger.error(`surfacing ${direction} ${correlation} failed: ${err.message}`);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
if (dispatches.length > 0 && state.running) {
|
|
150
|
-
await sleep(POLL_INTERVAL_AFTER_BATCH_MS, () => state.running);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
opts.logger.info("lyriel inbox poll loop exited");
|
|
154
|
-
}
|
|
155
|
-
return {
|
|
156
|
-
start() {
|
|
157
|
-
if (state.running) {
|
|
158
|
-
return;
|
|
159
|
-
}
|
|
160
|
-
state.running = true;
|
|
161
|
-
state.currentLoop = loop().catch((err) => {
|
|
162
|
-
opts.logger.error(`inbox loop crashed: ${err.message}`);
|
|
163
|
-
});
|
|
164
|
-
},
|
|
165
|
-
async stop() {
|
|
166
|
-
state.running = false;
|
|
167
|
-
if (state.currentLoop) {
|
|
168
|
-
await state.currentLoop;
|
|
169
|
-
state.currentLoop = null;
|
|
170
|
-
}
|
|
171
|
-
},
|
|
172
|
-
};
|
|
173
|
-
}
|
|
174
|
-
function sleep(ms, stillRunning) {
|
|
175
|
-
return new Promise((resolve) => {
|
|
176
|
-
if (!stillRunning()) {
|
|
177
|
-
resolve();
|
|
178
|
-
return;
|
|
179
|
-
}
|
|
180
|
-
setTimeout(resolve, ms);
|
|
181
|
-
});
|
|
182
|
-
}
|
|
183
|
-
//# sourceMappingURL=inbox.js.map
|
package/dist/inbox.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../inbox.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,gDAAgD;AAChD,EAAE;AACF,uEAAuE;AACvE,kEAAkE;AAClE,wBAAwB;AACxB,EAAE;AACF,oEAAoE;AACpE,sEAAsE;AACtE,qEAAqE;AACrE,mEAAmE;AACnE,oEAAoE;AACpE,oDAAoD;AACpD,EAAE;AACF,qEAAqE;AACrE,qBAAqB;AACrB,EAAE;AACF,oDAAoD;AACpD,EAAE;AACF,oEAAoE;AACpE,4EAA4E;AAC5E,2EAA2E;AAC3E,6CAA6C;AAE7C,OAAO,KAAK,GAAG,MAAM,UAAU,CAAC;AAChC,OAAO,KAAK,OAAO,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAChD,OAAO,EAAE,mBAAmB,EAA8B,MAAM,eAAe,CAAC;AAEhF,MAAM,oBAAoB,GAAG,KAAK,CAAC;AACnC,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAChC,MAAM,4BAA4B,GAAG,GAAG,CAAC;AASzC,oEAAoE;AACpE,+DAA+D;AAC/D,wCAAwC;AACxC,qEAAqE;AACrE,oEAAoE;AACpE,MAAM,CAAC,MAAM,wBAAwB,GACnC,oEAAoE;IACpE,+DAA+D;IAC/D,mEAAmE;IACnE,oEAAoE;IACpE,gEAAgE;IAChE,wDAAwD,CAAC;AAmB3D,MAAM,UAAU,iBAAiB,CAAC,IAOjC;IACC,MAAM,KAAK,GAAc,EAAE,OAAO,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,CAAC;IAE/D,KAAK,UAAU,QAAQ;QACrB,OAAO,GAAG,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAAC;IAC1D,CAAC;IAED,KAAK,UAAU,IAAI;QACjB,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,wCAAwC,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC,CAAC;QACjF,OAAO,KAAK,CAAC,OAAO,EAAE,CAAC;YACrB,IAAI,UAAU,GAAmB,EAAE,CAAC;YACpC,IAAI,CAAC;gBACH,UAAU,GAAG,MAAM,QAAQ,EAAE,CAAC;YAChC,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC;oBACnB,MAAM;gBACR,CAAC;gBACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,qBAAsB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;gBAChE,MAAM,KAAK,CAAC,oBAAoB,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;gBACvD,SAAS;YACX,CAAC;YAED,KAAK,MAAM,CAAC,IAAI,UAAU,EAAE,CAAC;gBAC3B,MAAM,KAAK,GAAG,CAAC,CAAC,MAAM,CAAC;gBACvB,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,CAAC;gBACzB,MAAM,SAAS,GAAG,CAAC,CAAC,SAAS,IAAI,GAAG,CAAC;gBACrC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,IAAI,EAAE,CAAC;gBAClC,MAAM,WAAW,GAAG,MAAM,IAAI,KAAK,IAAI,GAAG,CAAC;gBAE3C,IAAI,SAAS,KAAK,UAAU,IAAI,KAAK,EAAE,CAAC;oBACtC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,UAAU,CAAC,EAAE,CAAC;wBAC5C,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,gDAAgD,KAAK,2BAA2B,CACjF,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAED,IAAI,SAAS,KAAK,MAAM,IAAI,MAAM,EAAE,CAAC;oBACnC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC;wBAC9C,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,8BAA8B,CAAC,CAAC;wBACrE,IAAI,CAAC,QAAQ,EAAE,CAAC;4BACd,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,uCAAuC,MAAM,iCAAiC,CAC/E,CAAC;wBACJ,CAAC;6BAAM,CAAC;4BACN,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;wBAC7B,CAAC;oBACH,CAAC;gBACH,CAAC;gBAED,kEAAkE;gBAClE,gEAAgE;gBAChE,kDAAkD;gBAClD,IAAI,SAAS,KAAK,SAAS,IAAI,KAAK,IAAI,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;oBACnE,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,0BAA0B,KAAK,6BAA6B,CAAC,CAAC;oBAC/E,SAAS;gBACX,CAAC;gBAED,2DAA2D;gBAC3D,0DAA0D;gBAC1D,2DAA2D;gBAC3D,2DAA2D;gBAC3D,0DAA0D;gBAC1D,sDAAsD;gBACtD,IAAI,SAAS,KAAK,MAAM,IAAI,MAAM,EAAE,CAAC;oBACnC,MAAM,UAAU,GACd,UAAU,CAAC,QAAQ,CAAC,8BAA8B,CAAC;wBACnD,UAAU,CAAC,QAAQ,CAAC,iCAAiC,CAAC,CAAC;oBACzD,IAAI,CAAC,UAAU,EAAE,CAAC;wBAChB,MAAM,SAAS,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;wBAC/C,IAAI,CAAC,SAAS,EAAE,CAAC;4BACf,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,yDAAyD,MAAM,0DAA0D,CAC1H,CAAC;4BACF,SAAS;wBACX,CAAC;wBACD,IAAI,CAAC;4BACH,MAAM,IAAI,CAAC,sBAAsB,CAAC;gCAChC,UAAU,EAAE,SAAS;gCACrB,OAAO,EAAE,wBAAwB,GAAG,UAAU;6BAC/C,CAAC,CAAC;4BACH,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,8CAA8C,MAAM,eAAe,SAAS,EAAE,CAC/E,CAAC;wBACJ,CAAC;wBAAC,OAAO,GAAG,EAAE,CAAC;4BACb,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,2CAA2C,MAAM,KAAM,GAAa,CAAC,OAAO,EAAE,CAC/E,CAAC;wBACJ,CAAC;wBACD,SAAS;oBACX,CAAC;gBACH,CAAC;gBAED,MAAM,WAAW,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;gBAEtC,mEAAmE;gBACnE,gEAAgE;gBAChE,+DAA+D;gBAC/D,eAAe;gBACf,MAAM,EAAE,GAAG,IAAI,CAAC,sBAAsB,EAAE,CAAC;gBACzC,IAAI,EAAE,CAAC,QAAQ,IAAI,EAAE,CAAC,MAAM,EAAE,CAAC;oBAC7B,MAAM,MAAM,GAAG,MAAM,mBAAmB,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;oBAC1D,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;wBACd,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,YAAY,SAAS,OAAO,WAAW,sBAAsB,EAAE,CAAC,MAAM,EAAE,CACzE,CAAC;wBACF,SAAS;oBACX,CAAC;oBACD,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,qBAAqB,SAAS,OAAO,WAAW,YAAY,MAAM,CAAC,KAAK,IAAI,SAAS,wCAAwC,CAC9H,CAAC;gBACJ,CAAC;gBAED,kEAAkE;gBAClE,kEAAkE;gBAClE,uBAAuB;gBACvB,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,EAAE,CAAC;gBAChD,IAAI,CAAC,UAAU,EAAE,CAAC;oBAChB,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,4BAA4B,SAAS,OAAO,WAAW,8FAA8F,CACtJ,CAAC;oBACF,SAAS;gBACX,CAAC;gBAED,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,MAAM,CAAC,EAAE,UAAU,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;oBACrD,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,YAAY,SAAS,OAAO,WAAW,iBAAiB,UAAU,EAAE,CACrE,CAAC;gBACJ,CAAC;gBAAC,OAAO,GAAG,EAAE,CAAC;oBACb,IAAI,CAAC,MAAM,CAAC,KAAK,CACf,aAAa,SAAS,IAAI,WAAW,YAAa,GAAa,CAAC,OAAO,EAAE,CAC1E,CAAC;gBACJ,CAAC;YACH,CAAC;YAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC3C,MAAM,KAAK,CAAC,4BAA4B,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;QACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,+BAA+B,CAAC,CAAC;IACpD,CAAC;IAED,OAAO;QACL,KAAK;YACH,IAAI,KAAK,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO;YACT,CAAC;YACD,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC;YACrB,KAAK,CAAC,WAAW,GAAG,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBACvC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAwB,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;YACrE,CAAC,CAAC,CAAC;QACL,CAAC;QACD,KAAK,CAAC,IAAI;YACR,KAAK,CAAC,OAAO,GAAG,KAAK,CAAC;YACtB,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC;gBACtB,MAAM,KAAK,CAAC,WAAW,CAAC;gBACxB,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;YAC3B,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC;AAED,SAAS,KAAK,CAAC,EAAU,EAAE,YAA2B;IACpD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YACpB,OAAO,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QACD,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/index.js
DELETED
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
// Lyriel plugin for OpenClaw.
|
|
2
|
-
//
|
|
3
|
-
// Wires Lyriel (https://lyriel.ai) into the OpenClaw runtime. Cross-provider
|
|
4
|
-
// parity with clients/hermes-plugin/: a Hermes user and an OpenClaw user can
|
|
5
|
-
// coordinate through Lyriel without either knowing what runtime the other is
|
|
6
|
-
// on, because both runtimes integrate via Lyriel's HTTP substrate API.
|
|
7
|
-
//
|
|
8
|
-
// Three pieces wire up at register():
|
|
9
|
-
//
|
|
10
|
-
// 1. Five LLM tools (lyriel_send_ask, lyriel_reply, lyriel_plan_send,
|
|
11
|
-
// lyriel_plan_reply, lyriel_plan_lock) so the user drives Lyriel in
|
|
12
|
-
// natural language. Schemas live in tools.ts.
|
|
13
|
-
//
|
|
14
|
-
// 2. A background long-poll started on the `gateway_start` lifecycle
|
|
15
|
-
// hook. The loop hits Lyriel's /api/inbox, parses dispatches, stores
|
|
16
|
-
// callback tokens by ask_id / plan_id (so the reply tools have them
|
|
17
|
-
// when the user wants to respond), and pushes a human-readable
|
|
18
|
-
// surface message into the user's active session via
|
|
19
|
-
// api.session.workflow.enqueueNextTurnInjection.
|
|
20
|
-
//
|
|
21
|
-
// 3. A `message_received` hook that tracks the user's most recent
|
|
22
|
-
// session key so the poll loop knows which session to surface into.
|
|
23
|
-
// Operators can pin a specific session via
|
|
24
|
-
// `plugins.entries.lyriel.config.surfaceSessionKey` instead.
|
|
25
|
-
//
|
|
26
|
-
// Required config (plugins.entries.lyriel.config in openclaw config):
|
|
27
|
-
// apiKey — your lyk_... key from /me/agent setup (required)
|
|
28
|
-
// baseUrl — defaults to https://lyriel.ai; override for dev
|
|
29
|
-
// surfaceSessionKey — optional pinned session key (otherwise auto-tracked)
|
|
30
|
-
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
|
|
31
|
-
import { createInboxRunner } from "./inbox.js";
|
|
32
|
-
import { resolveTelegramSurface } from "./telegram.js";
|
|
33
|
-
import { buildToolDescriptors } from "./tools.js";
|
|
34
|
-
function parseConfig(raw) {
|
|
35
|
-
if (!raw || typeof raw !== "object") {
|
|
36
|
-
return {};
|
|
37
|
-
}
|
|
38
|
-
const o = raw;
|
|
39
|
-
return {
|
|
40
|
-
apiKey: typeof o.apiKey === "string" ? o.apiKey : undefined,
|
|
41
|
-
baseUrl: typeof o.baseUrl === "string" ? o.baseUrl : undefined,
|
|
42
|
-
surfaceSessionKey: typeof o.surfaceSessionKey === "string" ? o.surfaceSessionKey : undefined,
|
|
43
|
-
surfaceTelegramChatId: typeof o.surfaceTelegramChatId === "string" ? o.surfaceTelegramChatId : undefined,
|
|
44
|
-
};
|
|
45
|
-
}
|
|
46
|
-
export default definePluginEntry({
|
|
47
|
-
id: "lyriel",
|
|
48
|
-
name: "Lyriel",
|
|
49
|
-
description: "Lyriel plugin for OpenClaw — agent-mediated communication substrate. Long-polls /api/inbox, surfaces dispatches into the active session, and exposes five tools for asks and group plans.",
|
|
50
|
-
register(api) {
|
|
51
|
-
const config = parseConfig(api.pluginConfig);
|
|
52
|
-
const baseUrl = (config.baseUrl ?? "https://lyriel.ai").trim();
|
|
53
|
-
const apiKey = (config.apiKey ?? "").trim();
|
|
54
|
-
if (!apiKey) {
|
|
55
|
-
api.logger.warn("Lyriel plugin: apiKey missing in plugins.entries.lyriel.config — tools and inbox poll will fail until set.");
|
|
56
|
-
}
|
|
57
|
-
const client = { apiKey, baseUrl };
|
|
58
|
-
// ─── LLM tools ──────────────────────────────────────────────────────
|
|
59
|
-
for (const tool of buildToolDescriptors(client)) {
|
|
60
|
-
api.registerTool({
|
|
61
|
-
name: tool.name,
|
|
62
|
-
label: tool.label,
|
|
63
|
-
description: tool.description,
|
|
64
|
-
parameters: tool.parameters,
|
|
65
|
-
execute: tool.execute,
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
// ─── Surface-session tracking ───────────────────────────────────────
|
|
69
|
-
// The user's most recently active session, populated lazily by the
|
|
70
|
-
// message_received hook. Cleared on gateway_stop.
|
|
71
|
-
let mostRecentSessionKey = null;
|
|
72
|
-
api.on("message_received", async (_event, ctx) => {
|
|
73
|
-
const sk = ctx.sessionKey;
|
|
74
|
-
if (sk && typeof sk === "string") {
|
|
75
|
-
mostRecentSessionKey = sk;
|
|
76
|
-
}
|
|
77
|
-
});
|
|
78
|
-
function resolveSurfaceSession() {
|
|
79
|
-
if (config.surfaceSessionKey) {
|
|
80
|
-
return config.surfaceSessionKey;
|
|
81
|
-
}
|
|
82
|
-
return mostRecentSessionKey;
|
|
83
|
-
}
|
|
84
|
-
// ─── Inbox poll loop ────────────────────────────────────────────────
|
|
85
|
-
const childLogger = api.logger;
|
|
86
|
-
const inbox = createInboxRunner({
|
|
87
|
-
client,
|
|
88
|
-
resolveSurfaceSession,
|
|
89
|
-
resolveTelegramSurface() {
|
|
90
|
-
return resolveTelegramSurface(api.config, config.surfaceTelegramChatId);
|
|
91
|
-
},
|
|
92
|
-
logger: childLogger,
|
|
93
|
-
async inject({ sessionKey, text }) {
|
|
94
|
-
await api.session.workflow.enqueueNextTurnInjection({
|
|
95
|
-
sessionKey,
|
|
96
|
-
text,
|
|
97
|
-
placement: "append_context",
|
|
98
|
-
ttlMs: 5 * 60_000,
|
|
99
|
-
});
|
|
100
|
-
},
|
|
101
|
-
// Background plan turn: scheduleSessionTurn with delayMs=0 fires
|
|
102
|
-
// the LLM immediately with the supplied message as the turn
|
|
103
|
-
// input. deliveryMode: "none" suppresses any user-visible
|
|
104
|
-
// notification for the scheduled turn — the agent processes the
|
|
105
|
-
// round, calls lyriel_plan_reply via its toolset, and returns
|
|
106
|
-
// without the user seeing anything until the plan locks.
|
|
107
|
-
async scheduleBackgroundTurn({ sessionKey, message }) {
|
|
108
|
-
await api.session.workflow.scheduleSessionTurn({
|
|
109
|
-
sessionKey,
|
|
110
|
-
message,
|
|
111
|
-
delayMs: 0,
|
|
112
|
-
deliveryMode: "none",
|
|
113
|
-
name: "lyriel.plan-round",
|
|
114
|
-
tag: "lyriel.background",
|
|
115
|
-
});
|
|
116
|
-
},
|
|
117
|
-
});
|
|
118
|
-
api.on("gateway_start", async () => {
|
|
119
|
-
if (!apiKey) {
|
|
120
|
-
api.logger.warn("Lyriel plugin: gateway_start received but apiKey is empty — not starting inbox poll loop.");
|
|
121
|
-
return;
|
|
122
|
-
}
|
|
123
|
-
inbox.start();
|
|
124
|
-
api.logger.info("Lyriel plugin registered: 5 tools (ask, reply, plan_send, plan_reply, plan_lock) + inbox poll loop");
|
|
125
|
-
});
|
|
126
|
-
api.on("gateway_stop", async () => {
|
|
127
|
-
await inbox.stop();
|
|
128
|
-
mostRecentSessionKey = null;
|
|
129
|
-
});
|
|
130
|
-
},
|
|
131
|
-
});
|
|
132
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}
|
package/dist/pending.js
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
// In-process state shared between the inbox poll loop and the LLM tools.
|
|
2
|
-
//
|
|
3
|
-
// Two maps, both lost on Gateway restart (acceptable v0 limitation — same as
|
|
4
|
-
// the Hermes plugin's pending.py). For a long-lived deployment, swap these
|
|
5
|
-
// for api.runtime.state.openKeyedStore so callbacks survive restart.
|
|
6
|
-
//
|
|
7
|
-
// pendingAsks: ask_id -> callback URL + single-use Bearer token
|
|
8
|
-
// pendingPlans: plan_id -> current-round callback (overwritten each round)
|
|
9
|
-
// absorbedAsks: ask_id -> timestamp; tracks asks whose response was inlined
|
|
10
|
-
// into the lyriel_send_ask tool result (system_responder case) so the
|
|
11
|
-
// inbox poll suppresses the duplicate forward surface.
|
|
12
|
-
const pendingAsks = new Map();
|
|
13
|
-
const pendingPlans = new Map();
|
|
14
|
-
const absorbedAsks = new Map();
|
|
15
|
-
const ABSORBED_TTL_MS = 60_000;
|
|
16
|
-
// The sealed-ask envelope (web/src/lib/server/agents/prompt.ts) embeds the
|
|
17
|
-
// callback in plain text: `POST <url>` then `Bearer <token>`. Asks use
|
|
18
|
-
// lct_<...> tokens; plans use plt_<...> tokens.
|
|
19
|
-
const RE_CALLBACK_URL = /POST\s+(https?:\/\/\S+)/;
|
|
20
|
-
const RE_CALLBACK_TOKEN = /Bearer\s+((?:lct|plt)_\S+)/;
|
|
21
|
-
const RE_ASK_TEXT = /The ask:\s*"""\s*([\s\S]+?)\s*"""/;
|
|
22
|
-
const RE_PLAN_DESCRIPTION = /THE PLAN:\s*"""\s*([\s\S]+?)\s*"""/;
|
|
23
|
-
function stripTrailingPunct(s) {
|
|
24
|
-
return s.replace(/[,.;]+$/, "");
|
|
25
|
-
}
|
|
26
|
-
export function rememberAsk(askId, prompt) {
|
|
27
|
-
const urlMatch = prompt.match(RE_CALLBACK_URL);
|
|
28
|
-
const tokenMatch = prompt.match(RE_CALLBACK_TOKEN);
|
|
29
|
-
if (!urlMatch || !tokenMatch) {
|
|
30
|
-
return false;
|
|
31
|
-
}
|
|
32
|
-
const askMatch = prompt.match(RE_ASK_TEXT);
|
|
33
|
-
const excerpt = (askMatch ? askMatch[1].trim() : prompt.slice(0, 80)).trim();
|
|
34
|
-
pendingAsks.set(askId, {
|
|
35
|
-
callbackUrl: stripTrailingPunct(urlMatch[1]),
|
|
36
|
-
callbackToken: stripTrailingPunct(tokenMatch[1]),
|
|
37
|
-
receivedAt: Date.now(),
|
|
38
|
-
promptExcerpt: excerpt.slice(0, 200),
|
|
39
|
-
});
|
|
40
|
-
return true;
|
|
41
|
-
}
|
|
42
|
-
export function takeAsk(askId) {
|
|
43
|
-
const entry = pendingAsks.get(askId);
|
|
44
|
-
if (entry) {
|
|
45
|
-
pendingAsks.delete(askId);
|
|
46
|
-
}
|
|
47
|
-
return entry;
|
|
48
|
-
}
|
|
49
|
-
export function restoreAsk(askId, entry) {
|
|
50
|
-
pendingAsks.set(askId, entry);
|
|
51
|
-
}
|
|
52
|
-
export function listPendingAsks() {
|
|
53
|
-
return Object.fromEntries(pendingAsks);
|
|
54
|
-
}
|
|
55
|
-
export function markAbsorbed(askId) {
|
|
56
|
-
absorbedAsks.set(askId, Date.now());
|
|
57
|
-
pruneAbsorbed();
|
|
58
|
-
}
|
|
59
|
-
export function wasAbsorbed(askId) {
|
|
60
|
-
pruneAbsorbed();
|
|
61
|
-
return absorbedAsks.has(askId);
|
|
62
|
-
}
|
|
63
|
-
function pruneAbsorbed() {
|
|
64
|
-
const cutoff = Date.now() - ABSORBED_TTL_MS;
|
|
65
|
-
for (const [id, ts] of absorbedAsks) {
|
|
66
|
-
if (ts < cutoff) {
|
|
67
|
-
absorbedAsks.delete(id);
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
// Plans are multi-round: each round Lyriel sends a fresh envelope with a
|
|
72
|
-
// fresh single-use callback token. Always overwrite — the previous round's
|
|
73
|
-
// token is dead anyway.
|
|
74
|
-
export function rememberPlan(planId, prompt) {
|
|
75
|
-
const urlMatch = prompt.match(RE_CALLBACK_URL);
|
|
76
|
-
const tokenMatch = prompt.match(RE_CALLBACK_TOKEN);
|
|
77
|
-
if (!urlMatch || !tokenMatch) {
|
|
78
|
-
return false;
|
|
79
|
-
}
|
|
80
|
-
const descMatch = prompt.match(RE_PLAN_DESCRIPTION);
|
|
81
|
-
const excerpt = (descMatch ? descMatch[1].trim() : prompt.slice(0, 80)).trim();
|
|
82
|
-
pendingPlans.set(planId, {
|
|
83
|
-
callbackUrl: stripTrailingPunct(urlMatch[1]),
|
|
84
|
-
callbackToken: stripTrailingPunct(tokenMatch[1]),
|
|
85
|
-
receivedAt: Date.now(),
|
|
86
|
-
promptExcerpt: excerpt.slice(0, 200),
|
|
87
|
-
});
|
|
88
|
-
return true;
|
|
89
|
-
}
|
|
90
|
-
export function takePlan(planId) {
|
|
91
|
-
const entry = pendingPlans.get(planId);
|
|
92
|
-
if (entry) {
|
|
93
|
-
pendingPlans.delete(planId);
|
|
94
|
-
}
|
|
95
|
-
return entry;
|
|
96
|
-
}
|
|
97
|
-
export function restorePlan(planId, entry) {
|
|
98
|
-
pendingPlans.set(planId, entry);
|
|
99
|
-
}
|
|
100
|
-
export function listPendingPlans() {
|
|
101
|
-
return Object.fromEntries(pendingPlans);
|
|
102
|
-
}
|
|
103
|
-
export function forgetPlan(planId) {
|
|
104
|
-
pendingPlans.delete(planId);
|
|
105
|
-
}
|
|
106
|
-
//# sourceMappingURL=pending.js.map
|
package/dist/pending.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pending.js","sourceRoot":"","sources":["../pending.ts"],"names":[],"mappings":"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"}
|
package/dist/primer.js
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
// The canonical Lyriel substrate primer.
|
|
2
|
-
//
|
|
3
|
-
// Loaded into the LLM's bound-tool context via one of the Lyriel tool
|
|
4
|
-
// descriptions (lyriel_send_ask, by convention — it's the simplest
|
|
5
|
-
// and most likely first tool the LLM looks at). The LLM reads tool
|
|
6
|
-
// descriptions when tools are bound, so the primer enters context
|
|
7
|
-
// the moment the Lyriel plugin activates.
|
|
8
|
-
//
|
|
9
|
-
// This must stay in sync with clients/hermes-plugin/lyriel_hermes/primer.py.
|
|
10
|
-
// Any edit here gets mirrored there until we extract a single shared
|
|
11
|
-
// source (see TODO at bottom).
|
|
12
|
-
export const SUBSTRATE_PRIMER = `You are operating on Lyriel — the protocol layer for agent-to-agent communication on behalf of humans. You act for your user, not as them; other agents on Lyriel act for their users. Lyriel handles addressing, authentication, and routing across agent providers so two agents on different runtimes coordinate without either side knowing what runtime the other is on.
|
|
13
|
-
|
|
14
|
-
Every Lyriel user has a Seal: a verified identity tied to an agent endpoint. When you call a Lyriel tool you carry your user's Seal; the receiving agent resolves it before acting. Handles are formatted as @name and are how you reference everyone on Lyriel — never by display name or email.
|
|
15
|
-
|
|
16
|
-
Three primitives. Asks are 1:1 messages between agents (lyriel_send_ask, lyriel_reply). Plans are multi-party coordination rounds (lyriel_plan_send, lyriel_plan_reply, lyriel_plan_lock); Lyriel rounds through participants one turn at a time. Friends gate plans and inbound asks — the friend graph controls who can initiate coordination with your user.
|
|
17
|
-
|
|
18
|
-
Plans run AUTONOMOUSLY in the background. When your plugin receives a plan-round dispatch, you respond on behalf of your user WITHOUT involving them — they are not watching the round. Use what you already know about them (calendar, preferences, dietary, budget). If a constraint is missing on a round, accept wide constraints and let other participants narrow. Before initiating a plan via lyriel_plan_send, check your own context for what you'll need; if a critical constraint is missing, ask your user in a single batched question UPFRONT — never during plan rounds. Reply concisely — every token on every round costs your user real money.
|
|
19
|
-
|
|
20
|
-
Surface OUTCOMES to your user, never the agent-to-agent transcript. They see locked plans, accepted friends, and cancellations — not the negotiation. Do not summarize the negotiation back to them and do not relay other agents' messages verbatim. The product is your user staying focused on outcomes, not on the messy middle.
|
|
21
|
-
|
|
22
|
-
Defaults you observe at all times: never expose LYRIEL_API_KEY (not to your user, not to other agents, not in error output); represent exactly one human; do not commit to plans your user has not approved; treat OAuth-verified providers (GitHub, Google, Twitter) as facts about your user.
|
|
23
|
-
`;
|
|
24
|
-
// TODO: extract to clients/substrate-primer.md and have each plugin's
|
|
25
|
-
// build copy / import from a single source. For v0 the two copies
|
|
26
|
-
// (here and primer.py) are kept in sync by convention.
|
|
27
|
-
//# sourceMappingURL=primer.js.map
|
package/dist/primer.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"primer.js","sourceRoot":"","sources":["../primer.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,sEAAsE;AACtE,mEAAmE;AACnE,mEAAmE;AACnE,kEAAkE;AAClE,0CAA0C;AAC1C,EAAE;AACF,6EAA6E;AAC7E,qEAAqE;AACrE,+BAA+B;AAE/B,MAAM,CAAC,MAAM,gBAAgB,GAAG;;;;;;;;;;;CAW/B,CAAC;AAEF,sEAAsE;AACtE,kEAAkE;AAClE,uDAAuD"}
|
package/dist/surfacing.js
DELETED
|
@@ -1,95 +0,0 @@
|
|
|
1
|
-
// Format inbound Lyriel dispatches as human-readable text and push them into
|
|
2
|
-
// the user's active OpenClaw session via the host's next-turn injection
|
|
3
|
-
// surface.
|
|
4
|
-
//
|
|
5
|
-
// Why next-turn injection (not direct channel send):
|
|
6
|
-
// OpenClaw users connect their agent through many possible channels
|
|
7
|
-
// (Telegram, Signal, Discord, iMessage, etc.). Pushing into one specific
|
|
8
|
-
// channel from a plugin would require channel-specific glue, per-account
|
|
9
|
-
// chat ids, and platform-by-platform send logic. Next-turn injection
|
|
10
|
-
// surfaces the Lyriel dispatch into the agent's next turn for the active
|
|
11
|
-
// session, regardless of which channel the user is talking on. The user's
|
|
12
|
-
// next agent interaction picks it up and the agent surfaces it naturally.
|
|
13
|
-
//
|
|
14
|
-
// Trade-off vs the Hermes plugin's Telegram-direct surfacing: the dispatch
|
|
15
|
-
// doesn't become a free-standing push notification — the user has to engage
|
|
16
|
-
// the agent for it to surface. That's acceptable at v0: AI-native users are
|
|
17
|
-
// already in their agent throughout the day. A truly proactive push path
|
|
18
|
-
// would need per-channel send glue and is deferred until design-partner
|
|
19
|
-
// feedback says it's load-bearing.
|
|
20
|
-
const RE_INITIATOR = /This message is NOT from your human — it is from\s+([\s\S]+?)'s agent/;
|
|
21
|
-
const RE_ASK_TEXT = /The ask:\s*"""\s*([\s\S]+?)\s*"""/;
|
|
22
|
-
const RE_RESPONSE_TEXT = /agent has responded:\s*"""\s*([\s\S]+?)\s*"""/;
|
|
23
|
-
const RE_ORIGINAL_PROMPT = /on behalf of your human \(@\S+\):\s*"""\s*([\s\S]+?)\s*"""/;
|
|
24
|
-
const RE_RECIPIENT_NAME = /([\s\S]+?)'s agent has responded/;
|
|
25
|
-
// Plan envelope parsers
|
|
26
|
-
const RE_PLAN_INITIATOR = /plan initiated by\s+([\s\S]+?)'s agent/;
|
|
27
|
-
const RE_PLAN_DESCRIPTION = /THE PLAN:\s*"""\s*([\s\S]+?)\s*"""/;
|
|
28
|
-
const RE_PLAN_PARTICIPANTS = /PARTICIPANTS \(\d+ agents[^)]*\):\s*\n([\s\S]+?)\n\n/;
|
|
29
|
-
const RE_PLAN_CONVERSATION = /CONVERSATION SO FAR:\s*\n+([\s\S]+?)\n+WHAT TO DO RIGHT NOW/;
|
|
30
|
-
const RE_PLAN_LOCKED_SUMMARY = /LOCKED OUTCOME:\s*"""\s*([\s\S]+?)\s*"""/;
|
|
31
|
-
const RE_PLAN_LOCKED_PROPOSER = /locked\. ([\s\S]+?)'s agent proposed it/;
|
|
32
|
-
function pick(prompt, re, fallback) {
|
|
33
|
-
const m = prompt.match(re);
|
|
34
|
-
return m ? m[1].trim() : fallback;
|
|
35
|
-
}
|
|
36
|
-
export function formatDispatch(d) {
|
|
37
|
-
const askId = d.ask_id ?? "?";
|
|
38
|
-
const planId = d.plan_id;
|
|
39
|
-
const prompt = d.prompt ?? "";
|
|
40
|
-
if (d.direction === "plan" && planId) {
|
|
41
|
-
return formatPlanDispatch(planId, prompt);
|
|
42
|
-
}
|
|
43
|
-
if (d.direction === "dispatch") {
|
|
44
|
-
const sender = pick(prompt, RE_INITIATOR, "someone");
|
|
45
|
-
const askText = pick(prompt, RE_ASK_TEXT, "<could not parse ask>");
|
|
46
|
-
return (`🪶 Lyriel ask from ${sender}:\n\n` +
|
|
47
|
-
`"${askText}"\n\n` +
|
|
48
|
-
`To reply, say something like: ` +
|
|
49
|
-
`reply to Lyriel ask ${askId} with <your response>`);
|
|
50
|
-
}
|
|
51
|
-
if (d.direction === "forward") {
|
|
52
|
-
const respText = pick(prompt, RE_RESPONSE_TEXT, "<could not parse response>");
|
|
53
|
-
const original = pick(prompt, RE_ORIGINAL_PROMPT, "<your earlier ask>");
|
|
54
|
-
const sender = pick(prompt, RE_RECIPIENT_NAME, "someone");
|
|
55
|
-
return (`🪶 Lyriel reply from ${sender}:\n\n` +
|
|
56
|
-
`(in reply to: "${original}")\n\n` +
|
|
57
|
-
respText);
|
|
58
|
-
}
|
|
59
|
-
return `🪶 Lyriel: ${d.direction}\n${prompt.slice(0, 500)}`;
|
|
60
|
-
}
|
|
61
|
-
function formatPlanDispatch(planId, prompt) {
|
|
62
|
-
const isLocked = prompt.includes("[Lyriel group plan — LOCKED]");
|
|
63
|
-
const isInitial = prompt.includes("[Lyriel group plan — round 1");
|
|
64
|
-
const description = pick(prompt, RE_PLAN_DESCRIPTION, "<could not parse plan>");
|
|
65
|
-
const participants = pick(prompt, RE_PLAN_PARTICIPANTS, "<participants unknown>");
|
|
66
|
-
if (isLocked) {
|
|
67
|
-
const summary = pick(prompt, RE_PLAN_LOCKED_SUMMARY, "<could not parse outcome>");
|
|
68
|
-
const proposer = pick(prompt, RE_PLAN_LOCKED_PROPOSER, "someone");
|
|
69
|
-
return (`🪶 Lyriel group plan LOCKED (plan_id ${planId})\n\n` +
|
|
70
|
-
`Plan: "${description}"\n\n` +
|
|
71
|
-
`Outcome (proposed by ${proposer}):\n` +
|
|
72
|
-
` → ${summary}\n\n` +
|
|
73
|
-
`Participants: ${participants}\n\n` +
|
|
74
|
-
`This is final. No further responses needed.`);
|
|
75
|
-
}
|
|
76
|
-
if (isInitial) {
|
|
77
|
-
const initiator = pick(prompt, RE_PLAN_INITIATOR, "someone");
|
|
78
|
-
return (`🪶 Lyriel group plan from ${initiator} (plan_id ${planId})\n\n` +
|
|
79
|
-
`Plan: "${description}"\n\n` +
|
|
80
|
-
`Participants: ${participants}\n\n` +
|
|
81
|
-
`Round 1 — your agent is being asked to contribute. To reply, ` +
|
|
82
|
-
`say something like: 'reply to Lyriel plan ${planId} saying ` +
|
|
83
|
-
`<your thoughts/constraints>'. To skip this round, say: ` +
|
|
84
|
-
`'stay silent on plan ${planId}'.`);
|
|
85
|
-
}
|
|
86
|
-
// plan_message (refinement round)
|
|
87
|
-
const conversation = pick(prompt, RE_PLAN_CONVERSATION, "<conversation unavailable>");
|
|
88
|
-
return (`🪶 Lyriel plan update (plan_id ${planId})\n\n` +
|
|
89
|
-
`Plan: "${description}"\n\n` +
|
|
90
|
-
`Conversation so far:\n${conversation}\n\n` +
|
|
91
|
-
`Refinement round — respond if you have something new to add. ` +
|
|
92
|
-
`To reply: 'reply to Lyriel plan ${planId} saying <your update>'. ` +
|
|
93
|
-
`To pass: 'stay silent on plan ${planId}'.`);
|
|
94
|
-
}
|
|
95
|
-
//# sourceMappingURL=surfacing.js.map
|
package/dist/surfacing.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"surfacing.js","sourceRoot":"","sources":["../surfacing.ts"],"names":[],"mappings":"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"}
|
package/dist/telegram.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
// Direct Telegram Bot API push for proactive surfacing.
|
|
2
|
-
//
|
|
3
|
-
// OpenClaw's plugin-sdk doesn't expose a clean cross-channel "deliver this
|
|
4
|
-
// text to chat X right now" primitive for external plugins — channel-message
|
|
5
|
-
// helpers exist but require a turn context. For v0 we reuse the bot token
|
|
6
|
-
// the user has already configured under `channels.telegram.botToken` and POST
|
|
7
|
-
// directly to api.telegram.org/bot<token>/sendMessage. Matches the
|
|
8
|
-
// surfacing behavior of the standalone Telegram bridge and the Hermes plugin.
|
|
9
|
-
//
|
|
10
|
-
// Chat id resolution (in order):
|
|
11
|
-
// 1. `plugins.entries.lyriel.config.surfaceTelegramChatId` (explicit pin)
|
|
12
|
-
// 2. `channels.telegram.allowFrom[0]` (the first allowlisted user — common
|
|
13
|
-
// single-user setup)
|
|
14
|
-
// 3. `channels.telegram.groupAllowFrom[0]` (group fallback)
|
|
15
|
-
//
|
|
16
|
-
// Returns false and logs a single warning if no chat id can be resolved or
|
|
17
|
-
// the bot token is missing.
|
|
18
|
-
const TELEGRAM_API_BASE = "https://api.telegram.org";
|
|
19
|
-
export function resolveTelegramSurface(openclawConfig, surfaceTelegramChatId) {
|
|
20
|
-
const cfg = openclawConfig;
|
|
21
|
-
const telegram = cfg?.channels?.telegram;
|
|
22
|
-
const botToken = telegram && typeof telegram.botToken === "string" && telegram.botToken ? telegram.botToken : null;
|
|
23
|
-
if (surfaceTelegramChatId) {
|
|
24
|
-
return { botToken, chatId: surfaceTelegramChatId };
|
|
25
|
-
}
|
|
26
|
-
const allowFrom = Array.isArray(telegram?.allowFrom) ? telegram?.allowFrom : [];
|
|
27
|
-
const firstAllow = allowFrom[0];
|
|
28
|
-
if (firstAllow !== undefined && firstAllow !== null) {
|
|
29
|
-
return { botToken, chatId: String(firstAllow) };
|
|
30
|
-
}
|
|
31
|
-
const groupAllowFrom = Array.isArray(telegram?.groupAllowFrom) ? telegram?.groupAllowFrom : [];
|
|
32
|
-
const firstGroup = groupAllowFrom[0];
|
|
33
|
-
if (firstGroup !== undefined && firstGroup !== null) {
|
|
34
|
-
return { botToken, chatId: String(firstGroup) };
|
|
35
|
-
}
|
|
36
|
-
return { botToken, chatId: null };
|
|
37
|
-
}
|
|
38
|
-
export async function sendTelegramMessage(surface, text) {
|
|
39
|
-
if (!surface.botToken || !surface.chatId) {
|
|
40
|
-
return { ok: false, error: "no telegram bot token or chat id configured" };
|
|
41
|
-
}
|
|
42
|
-
const url = `${TELEGRAM_API_BASE}/bot${surface.botToken}/sendMessage`;
|
|
43
|
-
try {
|
|
44
|
-
const res = await fetch(url, {
|
|
45
|
-
method: "POST",
|
|
46
|
-
headers: { "content-type": "application/json" },
|
|
47
|
-
body: JSON.stringify({
|
|
48
|
-
chat_id: surface.chatId,
|
|
49
|
-
text,
|
|
50
|
-
disable_web_page_preview: true,
|
|
51
|
-
}),
|
|
52
|
-
});
|
|
53
|
-
if (!res.ok) {
|
|
54
|
-
const body = await res.text();
|
|
55
|
-
return { ok: false, error: `telegram ${res.status}: ${body.slice(0, 200)}` };
|
|
56
|
-
}
|
|
57
|
-
return { ok: true };
|
|
58
|
-
}
|
|
59
|
-
catch (err) {
|
|
60
|
-
return { ok: false, error: err.message };
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
//# sourceMappingURL=telegram.js.map
|
package/dist/telegram.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"telegram.js","sourceRoot":"","sources":["../telegram.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.js
DELETED
|
@@ -1,404 +0,0 @@
|
|
|
1
|
-
// Five LLM tools the Lyriel plugin exposes to the OpenClaw agent.
|
|
2
|
-
//
|
|
3
|
-
// lyriel_send_ask(to, prompt) — initiate a 1:1 ask
|
|
4
|
-
// lyriel_reply(ask_id, response) — reply to a pending inbound ask
|
|
5
|
-
// lyriel_plan_send(participants, ...) — start a group plan
|
|
6
|
-
// lyriel_plan_reply(plan_id, content) — contribute to an ongoing plan
|
|
7
|
-
// lyriel_plan_lock(plan_id, summary) — initiator locks the outcome
|
|
8
|
-
//
|
|
9
|
-
// Schemas use typebox (OpenClaw's standard). Handlers return JSON in the
|
|
10
|
-
// content[] shape OpenClaw tools use. Errors are returned as
|
|
11
|
-
// {"error": "..."} rather than thrown — the runtime surfaces the JSON back
|
|
12
|
-
// to the LLM, which then explains the failure to the user.
|
|
13
|
-
import { Type } from "typebox";
|
|
14
|
-
import * as api from "./api.js";
|
|
15
|
-
import * as pending from "./pending.js";
|
|
16
|
-
import { SUBSTRATE_PRIMER } from "./primer.js";
|
|
17
|
-
// Synchronous-completion absorption window. See clients/hermes-plugin/tools.py
|
|
18
|
-
// for the long-form reasoning. Short summary: when the ask is to an in-process
|
|
19
|
-
// system agent (today: @lyriel), the response is written to the ask row before
|
|
20
|
-
// POST /api/asks returns. Brief poll on GET /api/asks/:id afterwards so the
|
|
21
|
-
// response shows up inline in the LLM's tool result, and mark the ask
|
|
22
|
-
// "absorbed" so the inbox poll skips the duplicate forward.
|
|
23
|
-
const ABSORB_WINDOW_MS = 2_500;
|
|
24
|
-
const ABSORB_POLL_INTERVAL_MS = 250;
|
|
25
|
-
function asText(payload) {
|
|
26
|
-
return {
|
|
27
|
-
content: [
|
|
28
|
-
{
|
|
29
|
-
type: "text",
|
|
30
|
-
text: JSON.stringify(payload),
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
details: payload,
|
|
34
|
-
};
|
|
35
|
-
}
|
|
36
|
-
export const sendAskSchema = Type.Object({
|
|
37
|
-
to: Type.String({
|
|
38
|
-
description: "Recipient's Lyriel handle, with or without leading @. Examples: 'noor', '@charlie', 'lyriel' (for the system welcome agent).",
|
|
39
|
-
}),
|
|
40
|
-
prompt: Type.String({
|
|
41
|
-
description: "The message body to send. Plain text. The recipient's agent will surface this to their human.",
|
|
42
|
-
}),
|
|
43
|
-
});
|
|
44
|
-
export const replySchema = Type.Object({
|
|
45
|
-
ask_id: Type.String({
|
|
46
|
-
description: "The UUID of the pending ask to reply to.",
|
|
47
|
-
}),
|
|
48
|
-
response: Type.String({
|
|
49
|
-
description: "The user's reply, paraphrased or verbatim.",
|
|
50
|
-
}),
|
|
51
|
-
});
|
|
52
|
-
export const planSendSchema = Type.Object({
|
|
53
|
-
participants: Type.Array(Type.String(), {
|
|
54
|
-
description: "Lyriel handles of the OTHER participants (not the user themselves). With or without leading @. Examples: ['noor', '@maya'].",
|
|
55
|
-
}),
|
|
56
|
-
description: Type.String({
|
|
57
|
-
description: "Free-form description of what the group is coordinating. Include constraints the user already knows. Be specific — every participant's agent reads this verbatim.",
|
|
58
|
-
}),
|
|
59
|
-
max_messages: Type.Optional(Type.Integer({
|
|
60
|
-
description: "Optional cap on conversation length (default 20). Auto-fails if exceeded.",
|
|
61
|
-
})),
|
|
62
|
-
});
|
|
63
|
-
export const planReplySchema = Type.Object({
|
|
64
|
-
plan_id: Type.String({
|
|
65
|
-
description: "The plan_id shown in the surface message.",
|
|
66
|
-
}),
|
|
67
|
-
content: Type.String({
|
|
68
|
-
description: "The user's contribution to the plan conversation. Speak as the user's agent representing them. Pass empty string if stay_silent=true.",
|
|
69
|
-
}),
|
|
70
|
-
stay_silent: Type.Optional(Type.Boolean({
|
|
71
|
-
description: "Set to true to opt out of this round without contributing. Default false.",
|
|
72
|
-
})),
|
|
73
|
-
});
|
|
74
|
-
export const planLockSchema = Type.Object({
|
|
75
|
-
plan_id: Type.String({
|
|
76
|
-
description: "The plan_id to lock.",
|
|
77
|
-
}),
|
|
78
|
-
summary: Type.String({
|
|
79
|
-
description: "Short, human-readable description of the locked outcome (e.g. 'Thursday 7pm at Mission Cantina'). Broadcast to every participant.",
|
|
80
|
-
}),
|
|
81
|
-
});
|
|
82
|
-
export const updateBioSchema = Type.Object({
|
|
83
|
-
bio: Type.String({
|
|
84
|
-
description: "The bio text to set on the user's Lyriel profile. Short and substantive — what the user works on, what they're looking for, anything other agents should know when resolving their Seal. Max 280 chars (server trims and rejects longer values). Pass an empty string to clear the bio.",
|
|
85
|
-
}),
|
|
86
|
-
});
|
|
87
|
-
// All five tools share the same client config — passed in at registration.
|
|
88
|
-
export function makeHandlers(client) {
|
|
89
|
-
async function absorbIfQuick(askId) {
|
|
90
|
-
const deadline = Date.now() + ABSORB_WINDOW_MS;
|
|
91
|
-
while (Date.now() < deadline) {
|
|
92
|
-
try {
|
|
93
|
-
const data = await api.getAsk(client, askId);
|
|
94
|
-
if (data.status === "completed") {
|
|
95
|
-
return typeof data.response === "string" && data.response ? data.response : null;
|
|
96
|
-
}
|
|
97
|
-
if (data.status === "failed") {
|
|
98
|
-
return null;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
catch {
|
|
102
|
-
return null;
|
|
103
|
-
}
|
|
104
|
-
await new Promise((r) => setTimeout(r, ABSORB_POLL_INTERVAL_MS));
|
|
105
|
-
}
|
|
106
|
-
return null;
|
|
107
|
-
}
|
|
108
|
-
async function handleSendAsk(params) {
|
|
109
|
-
const to = (params.to ?? "").trim();
|
|
110
|
-
const prompt = (params.prompt ?? "").trim();
|
|
111
|
-
if (!to || !prompt) {
|
|
112
|
-
return asText({ error: "Both 'to' and 'prompt' are required" });
|
|
113
|
-
}
|
|
114
|
-
let result;
|
|
115
|
-
try {
|
|
116
|
-
result = await api.sendAsk(client, to, prompt);
|
|
117
|
-
}
|
|
118
|
-
catch (err) {
|
|
119
|
-
const e = err;
|
|
120
|
-
return asText({ error: e.message, status: e.status });
|
|
121
|
-
}
|
|
122
|
-
const askId = result.ask_id ?? "?";
|
|
123
|
-
const absorbed = await absorbIfQuick(askId);
|
|
124
|
-
if (absorbed !== null) {
|
|
125
|
-
pending.markAbsorbed(askId);
|
|
126
|
-
return asText({
|
|
127
|
-
success: true,
|
|
128
|
-
ask_id: askId,
|
|
129
|
-
recipient: result.recipient ?? to,
|
|
130
|
-
status: "completed",
|
|
131
|
-
completed_inline: true,
|
|
132
|
-
response: absorbed,
|
|
133
|
-
note: `${to} responded instantly (in-process system agent). The response is inlined below. ` +
|
|
134
|
-
`Summarize or paraphrase it to the user — do NOT wait for a separate Lyriel reply.`,
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
return asText({
|
|
138
|
-
success: true,
|
|
139
|
-
ask_id: askId,
|
|
140
|
-
recipient: result.recipient ?? to,
|
|
141
|
-
status: result.status ?? "dispatched",
|
|
142
|
-
note: `Ask dispatched to ${to}. The recipient's reply will arrive in this chat as a ` +
|
|
143
|
-
`🪶 Lyriel reply (ask_id ${askId}) when their agent responds. Acknowledge briefly — ` +
|
|
144
|
-
`do NOT promise or paraphrase the reply yourself; the surfacing layer delivers it.`,
|
|
145
|
-
});
|
|
146
|
-
}
|
|
147
|
-
async function handleReply(params) {
|
|
148
|
-
const askId = (params.ask_id ?? "").trim();
|
|
149
|
-
const response = (params.response ?? "").trim();
|
|
150
|
-
if (!askId || !response) {
|
|
151
|
-
return asText({ error: "Both 'ask_id' and 'response' are required" });
|
|
152
|
-
}
|
|
153
|
-
const entry = pending.takeAsk(askId);
|
|
154
|
-
if (!entry) {
|
|
155
|
-
const snapshot = pending.listPendingAsks();
|
|
156
|
-
const ids = Object.keys(snapshot);
|
|
157
|
-
if (ids.length === 0) {
|
|
158
|
-
return asText({
|
|
159
|
-
error: `No pending Lyriel asks. ask_id=${askId} either already had a reply sent OR ` +
|
|
160
|
-
`was never received (check the chat for a surface message).`,
|
|
161
|
-
});
|
|
162
|
-
}
|
|
163
|
-
return asText({
|
|
164
|
-
error: `No pending ask with id ${askId}. Currently pending: ${JSON.stringify(ids)}`,
|
|
165
|
-
pending_ids: ids,
|
|
166
|
-
});
|
|
167
|
-
}
|
|
168
|
-
try {
|
|
169
|
-
const result = await api.sendCallback(entry.callbackUrl, entry.callbackToken, response);
|
|
170
|
-
return asText({
|
|
171
|
-
success: true,
|
|
172
|
-
ask_id: askId,
|
|
173
|
-
callback_status: result.status ?? "ok",
|
|
174
|
-
idempotent: result.idempotent ?? false,
|
|
175
|
-
note: "Reply sent through Lyriel.",
|
|
176
|
-
});
|
|
177
|
-
}
|
|
178
|
-
catch (err) {
|
|
179
|
-
pending.restoreAsk(askId, entry);
|
|
180
|
-
const e = err;
|
|
181
|
-
return asText({ error: e.message, status: e.status, retryable: true });
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
async function handlePlanSend(params) {
|
|
185
|
-
const participants = Array.isArray(params.participants) ? params.participants : [];
|
|
186
|
-
const description = (params.description ?? "").trim();
|
|
187
|
-
if (participants.length === 0 || !description) {
|
|
188
|
-
return asText({ error: "Both 'participants' and 'description' are required" });
|
|
189
|
-
}
|
|
190
|
-
try {
|
|
191
|
-
const result = await api.sendPlan(client, participants, description, params.max_messages);
|
|
192
|
-
return asText({
|
|
193
|
-
success: true,
|
|
194
|
-
plan_id: result.plan_id ?? "?",
|
|
195
|
-
participants: result.participants ?? [],
|
|
196
|
-
status: result.status ?? "open",
|
|
197
|
-
note: `Group plan ${result.plan_id} broadcast to participants. Their agents will negotiate. ` +
|
|
198
|
-
`Refinement updates and the final locked outcome will arrive in this chat as 🪶 Lyriel ` +
|
|
199
|
-
`plan updates. When the user wants to lock with a final decision, use lyriel_plan_lock.`,
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
catch (err) {
|
|
203
|
-
const e = err;
|
|
204
|
-
return asText({ error: e.message, status: e.status });
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
async function handlePlanReply(params) {
|
|
208
|
-
const planId = (params.plan_id ?? "").trim();
|
|
209
|
-
const content = (params.content ?? "").trim();
|
|
210
|
-
const staySilent = Boolean(params.stay_silent);
|
|
211
|
-
if (!planId) {
|
|
212
|
-
return asText({ error: "'plan_id' is required" });
|
|
213
|
-
}
|
|
214
|
-
if (!staySilent && !content) {
|
|
215
|
-
return asText({ error: "'content' is required unless stay_silent=true" });
|
|
216
|
-
}
|
|
217
|
-
const entry = pending.takePlan(planId);
|
|
218
|
-
if (!entry) {
|
|
219
|
-
const snapshot = pending.listPendingPlans();
|
|
220
|
-
const ids = Object.keys(snapshot);
|
|
221
|
-
if (ids.length === 0) {
|
|
222
|
-
return asText({
|
|
223
|
-
error: `No pending plan callbacks. plan_id=${planId} either already had a contribution ` +
|
|
224
|
-
`this round, OR the plan locked, OR the envelope wasn't received.`,
|
|
225
|
-
});
|
|
226
|
-
}
|
|
227
|
-
return asText({
|
|
228
|
-
error: `No pending callback for plan ${planId}. Currently pending plans: ${JSON.stringify(ids)}`,
|
|
229
|
-
pending_plan_ids: ids,
|
|
230
|
-
});
|
|
231
|
-
}
|
|
232
|
-
try {
|
|
233
|
-
await api.sendPlanCallback(entry.callbackUrl, entry.callbackToken, content, staySilent);
|
|
234
|
-
return asText({
|
|
235
|
-
success: true,
|
|
236
|
-
plan_id: planId,
|
|
237
|
-
silent: staySilent,
|
|
238
|
-
note: "Contribution sent. The other participants' agents will now consider it in their " +
|
|
239
|
-
"next response. Further refinement rounds and the locked outcome will arrive as " +
|
|
240
|
-
"🪶 Lyriel plan updates.",
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
catch (err) {
|
|
244
|
-
pending.restorePlan(planId, entry);
|
|
245
|
-
const e = err;
|
|
246
|
-
return asText({ error: e.message, status: e.status, retryable: true });
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
async function handlePlanLock(params) {
|
|
250
|
-
const planId = (params.plan_id ?? "").trim();
|
|
251
|
-
const summary = (params.summary ?? "").trim();
|
|
252
|
-
if (!planId || !summary) {
|
|
253
|
-
return asText({ error: "Both 'plan_id' and 'summary' are required" });
|
|
254
|
-
}
|
|
255
|
-
try {
|
|
256
|
-
const result = await api.lockPlan(client, planId, summary);
|
|
257
|
-
pending.forgetPlan(planId);
|
|
258
|
-
return asText({
|
|
259
|
-
success: true,
|
|
260
|
-
plan_id: planId,
|
|
261
|
-
status: result.status ?? "locked",
|
|
262
|
-
locked_at: result.locked_at,
|
|
263
|
-
note: `Plan ${planId} locked: ${summary}. Every participant's agent has been notified and ` +
|
|
264
|
-
`will surface the final outcome to their human.`,
|
|
265
|
-
});
|
|
266
|
-
}
|
|
267
|
-
catch (err) {
|
|
268
|
-
const e = err;
|
|
269
|
-
return asText({ error: e.message, status: e.status });
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
async function handleUpdateBio(params) {
|
|
273
|
-
const bio = typeof params.bio === "string" ? params.bio : null;
|
|
274
|
-
if (bio === null) {
|
|
275
|
-
return asText({ error: "'bio' is required (pass empty string to clear)." });
|
|
276
|
-
}
|
|
277
|
-
try {
|
|
278
|
-
const result = await api.updateProfile(client, { bio });
|
|
279
|
-
const profile = result.profile ?? {};
|
|
280
|
-
return asText({
|
|
281
|
-
success: true,
|
|
282
|
-
bio: profile.bio ?? null,
|
|
283
|
-
note: "Bio updated on Lyriel. Tell the user briefly what you set (or that you cleared it). " +
|
|
284
|
-
"Do NOT ask them to paste it anywhere — it's already live on their profile.",
|
|
285
|
-
});
|
|
286
|
-
}
|
|
287
|
-
catch (err) {
|
|
288
|
-
const e = err;
|
|
289
|
-
return asText({ error: e.message, status: e.status });
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
return {
|
|
293
|
-
handleSendAsk,
|
|
294
|
-
handleReply,
|
|
295
|
-
handlePlanSend,
|
|
296
|
-
handlePlanReply,
|
|
297
|
-
handlePlanLock,
|
|
298
|
-
handleUpdateBio,
|
|
299
|
-
};
|
|
300
|
-
}
|
|
301
|
-
function paramRecord(params) {
|
|
302
|
-
return params && typeof params === "object" && !Array.isArray(params)
|
|
303
|
-
? params
|
|
304
|
-
: {};
|
|
305
|
-
}
|
|
306
|
-
// Defensive narrowing: LLM-emitted tool args are unknown shape; non-string
|
|
307
|
-
// inputs should be treated as empty rather than stringified to
|
|
308
|
-
// "[object Object]". The typebox schema declares each field as a string, but
|
|
309
|
-
// don't trust the validator at this seam.
|
|
310
|
-
function asString(value) {
|
|
311
|
-
return typeof value === "string" ? value : "";
|
|
312
|
-
}
|
|
313
|
-
export function buildToolDescriptors(client) {
|
|
314
|
-
const h = makeHandlers(client);
|
|
315
|
-
return [
|
|
316
|
-
{
|
|
317
|
-
name: "lyriel_send_ask",
|
|
318
|
-
label: "Lyriel: send ask",
|
|
319
|
-
// The substrate primer is prepended here so it loads into the
|
|
320
|
-
// LLM's bound-tool context. Tool-specific instructions follow
|
|
321
|
-
// after a blank line. The other Lyriel tools have shorter,
|
|
322
|
-
// tool-specific descriptions; the primer in this one
|
|
323
|
-
// description is enough to frame the whole toolset.
|
|
324
|
-
description: SUBSTRATE_PRIMER +
|
|
325
|
-
"\n\n" +
|
|
326
|
-
"Tool — send a 1:1 ask. Use this when your user wants to ping exactly one other Lyriel user by handle. Returns an ask_id; the recipient's response arrives later as a 'reply' dispatch in the inbox, surfaced into this chat automatically — you do not need to poll. For multi-party coordination, use lyriel_plan_send instead.",
|
|
327
|
-
parameters: sendAskSchema,
|
|
328
|
-
async execute(_id, params) {
|
|
329
|
-
const p = paramRecord(params);
|
|
330
|
-
return h.handleSendAsk({
|
|
331
|
-
to: asString(p.to),
|
|
332
|
-
prompt: asString(p.prompt),
|
|
333
|
-
});
|
|
334
|
-
},
|
|
335
|
-
},
|
|
336
|
-
{
|
|
337
|
-
name: "lyriel_reply",
|
|
338
|
-
label: "Lyriel: reply",
|
|
339
|
-
description: "Reply to a pending inbound Lyriel ask. Use when the user wants to respond to a previously surfaced ask (you'll see a '🪶 Lyriel ask from X' message with an ask_id). Extract the ask_id exactly. If the user replies without naming an ask_id and only one is pending, use that one.",
|
|
340
|
-
parameters: replySchema,
|
|
341
|
-
async execute(_id, params) {
|
|
342
|
-
const p = paramRecord(params);
|
|
343
|
-
return h.handleReply({
|
|
344
|
-
ask_id: asString(p.ask_id),
|
|
345
|
-
response: asString(p.response),
|
|
346
|
-
});
|
|
347
|
-
},
|
|
348
|
-
},
|
|
349
|
-
{
|
|
350
|
-
name: "lyriel_plan_send",
|
|
351
|
-
label: "Lyriel: start group plan",
|
|
352
|
-
description: "Start a group plan through Lyriel. Each participant's agent negotiates AUTONOMOUSLY on their human's behalf to converge on an outcome. Use when coordinating across multiple verified Lyriel handles — NOT for single 1:1 asks (use lyriel_send_ask). BEFORE calling: check your own context for what you'll need (calendar, preferences, location, dietary, budget). If a critical constraint is missing, ASK YOUR USER ONCE in a single batched question — do NOT ask mid-plan; plan rounds run in the background without involving them. After calling, tell your user briefly that you're coordinating and will notify them when it locks. Returns a plan_id; lock and cancel events arrive later as surface messages.",
|
|
353
|
-
parameters: planSendSchema,
|
|
354
|
-
async execute(_id, params) {
|
|
355
|
-
const p = paramRecord(params);
|
|
356
|
-
return h.handlePlanSend({
|
|
357
|
-
participants: Array.isArray(p.participants)
|
|
358
|
-
? p.participants.filter((x) => typeof x === "string")
|
|
359
|
-
: [],
|
|
360
|
-
description: asString(p.description),
|
|
361
|
-
max_messages: typeof p.max_messages === "number" ? p.max_messages : undefined,
|
|
362
|
-
});
|
|
363
|
-
},
|
|
364
|
-
},
|
|
365
|
-
{
|
|
366
|
-
name: "lyriel_plan_reply",
|
|
367
|
-
label: "Lyriel: contribute to plan",
|
|
368
|
-
description: "Contribute to an ongoing Lyriel group plan. INVOKED AUTONOMOUSLY by your plugin when a plan-round dispatch arrives — you respond on the user's behalf without involving them; the user is not watching this round. Use what you already know about them (calendar, preferences, location, dietary, budget). If a constraint is missing, accept wide constraints and let other participants narrow — do NOT ask the user. Keep `content` concise; every token on every round costs your user money. Pass stay_silent=true if you have nothing new to add.",
|
|
369
|
-
parameters: planReplySchema,
|
|
370
|
-
async execute(_id, params) {
|
|
371
|
-
const p = paramRecord(params);
|
|
372
|
-
return h.handlePlanReply({
|
|
373
|
-
plan_id: asString(p.plan_id),
|
|
374
|
-
content: asString(p.content),
|
|
375
|
-
stay_silent: Boolean(p.stay_silent),
|
|
376
|
-
});
|
|
377
|
-
},
|
|
378
|
-
},
|
|
379
|
-
{
|
|
380
|
-
name: "lyriel_plan_lock",
|
|
381
|
-
label: "Lyriel: lock plan",
|
|
382
|
-
description: "Lock a Lyriel group plan with a final outcome. Only the plan's initiator can lock (Lyriel returns 403 otherwise). The locked outcome is broadcast to every participant's agent.",
|
|
383
|
-
parameters: planLockSchema,
|
|
384
|
-
async execute(_id, params) {
|
|
385
|
-
const p = paramRecord(params);
|
|
386
|
-
return h.handlePlanLock({
|
|
387
|
-
plan_id: asString(p.plan_id),
|
|
388
|
-
summary: asString(p.summary),
|
|
389
|
-
});
|
|
390
|
-
},
|
|
391
|
-
},
|
|
392
|
-
{
|
|
393
|
-
name: "lyriel_update_bio",
|
|
394
|
-
label: "Lyriel: update bio",
|
|
395
|
-
description: "Update the user's public Lyriel bio. Call this when the user asks you to write, rewrite, or update their Lyriel bio (\"write me a Lyriel bio\", \"update my Lyriel bio to mention X\", etc.). You generate the bio yourself based on what you know about the user; DO NOT ask them to copy-paste it back — this tool writes the bio to their profile directly. Bio is plain text, capped at 280 chars on the server. Pass an empty string to clear the bio.",
|
|
396
|
-
parameters: updateBioSchema,
|
|
397
|
-
async execute(_id, params) {
|
|
398
|
-
const p = paramRecord(params);
|
|
399
|
-
return h.handleUpdateBio({ bio: asString(p.bio) });
|
|
400
|
-
},
|
|
401
|
-
},
|
|
402
|
-
];
|
|
403
|
-
}
|
|
404
|
-
//# sourceMappingURL=tools.js.map
|
package/dist/tools.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../tools.ts"],"names":[],"mappings":"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"}
|