@nookplot/runtime 0.5.86 → 0.5.88
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/actionCatalog.generated.js +1 -1
- package/dist/actionCatalog.generated.js.map +1 -1
- package/dist/chat/chatEngine.d.ts +89 -0
- package/dist/chat/chatEngine.d.ts.map +1 -0
- package/dist/chat/chatEngine.js +363 -0
- package/dist/chat/chatEngine.js.map +1 -0
- package/dist/chat/index.d.ts +30 -0
- package/dist/chat/index.d.ts.map +1 -0
- package/dist/chat/index.js +29 -0
- package/dist/chat/index.js.map +1 -0
- package/dist/chat/terminal.d.ts +19 -0
- package/dist/chat/terminal.d.ts.map +1 -0
- package/dist/chat/terminal.js +17 -0
- package/dist/chat/terminal.js.map +1 -0
- package/dist/chat/terminals/discordTerminal.d.ts +22 -0
- package/dist/chat/terminals/discordTerminal.d.ts.map +1 -0
- package/dist/chat/terminals/discordTerminal.js +132 -0
- package/dist/chat/terminals/discordTerminal.js.map +1 -0
- package/dist/chat/terminals/openclawTerminal.d.ts +43 -0
- package/dist/chat/terminals/openclawTerminal.d.ts.map +1 -0
- package/dist/chat/terminals/openclawTerminal.js +186 -0
- package/dist/chat/terminals/openclawTerminal.js.map +1 -0
- package/dist/chat/terminals/stdinTerminal.d.ts +18 -0
- package/dist/chat/terminals/stdinTerminal.d.ts.map +1 -0
- package/dist/chat/terminals/stdinTerminal.js +58 -0
- package/dist/chat/terminals/stdinTerminal.js.map +1 -0
- package/dist/chat/terminals/telegramTerminal.d.ts +27 -0
- package/dist/chat/terminals/telegramTerminal.d.ts.map +1 -0
- package/dist/chat/terminals/telegramTerminal.js +123 -0
- package/dist/chat/terminals/telegramTerminal.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -1
- package/package.json +60 -44
- package/dist/cliques.d.ts +0 -89
- package/dist/cliques.d.ts.map +0 -1
- package/dist/cliques.js +0 -102
- package/dist/cliques.js.map +0 -1
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Terminal Chat System — barrel export.
|
|
3
|
+
*
|
|
4
|
+
* Provides ChatEngine (central brain) and pluggable Terminal adapters
|
|
5
|
+
* for stdin, Telegram, Discord, and OpenClaw.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { ChatEngine, StdinTerminal, TelegramTerminal } from "@nookplot/runtime/chat";
|
|
10
|
+
*
|
|
11
|
+
* const engine = new ChatEngine(runtime, { soulPath: "./soul.json" });
|
|
12
|
+
* await engine.loadSoul();
|
|
13
|
+
*
|
|
14
|
+
* const terminals = [new StdinTerminal(engine)];
|
|
15
|
+
* if (process.env.TELEGRAM_BOT_TOKEN) {
|
|
16
|
+
* terminals.push(new TelegramTerminal(engine, process.env.TELEGRAM_BOT_TOKEN));
|
|
17
|
+
* }
|
|
18
|
+
* await Promise.all(terminals.map(t => t.start()));
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @module chat
|
|
22
|
+
*/
|
|
23
|
+
export { ChatEngine } from "./chatEngine.js";
|
|
24
|
+
export type { ChatEngineOptions, ChatContext } from "./chatEngine.js";
|
|
25
|
+
export { Terminal } from "./terminal.js";
|
|
26
|
+
export { StdinTerminal } from "./terminals/stdinTerminal.js";
|
|
27
|
+
export { TelegramTerminal } from "./terminals/telegramTerminal.js";
|
|
28
|
+
export { DiscordTerminal } from "./terminals/discordTerminal.js";
|
|
29
|
+
export { OpenClawTerminal } from "./terminals/openclawTerminal.js";
|
|
30
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/chat/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,YAAY,EAAE,iBAAiB,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Multi-Terminal Chat System — barrel export.
|
|
3
|
+
*
|
|
4
|
+
* Provides ChatEngine (central brain) and pluggable Terminal adapters
|
|
5
|
+
* for stdin, Telegram, Discord, and OpenClaw.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { ChatEngine, StdinTerminal, TelegramTerminal } from "@nookplot/runtime/chat";
|
|
10
|
+
*
|
|
11
|
+
* const engine = new ChatEngine(runtime, { soulPath: "./soul.json" });
|
|
12
|
+
* await engine.loadSoul();
|
|
13
|
+
*
|
|
14
|
+
* const terminals = [new StdinTerminal(engine)];
|
|
15
|
+
* if (process.env.TELEGRAM_BOT_TOKEN) {
|
|
16
|
+
* terminals.push(new TelegramTerminal(engine, process.env.TELEGRAM_BOT_TOKEN));
|
|
17
|
+
* }
|
|
18
|
+
* await Promise.all(terminals.map(t => t.start()));
|
|
19
|
+
* ```
|
|
20
|
+
*
|
|
21
|
+
* @module chat
|
|
22
|
+
*/
|
|
23
|
+
export { ChatEngine } from "./chatEngine.js";
|
|
24
|
+
export { Terminal } from "./terminal.js";
|
|
25
|
+
export { StdinTerminal } from "./terminals/stdinTerminal.js";
|
|
26
|
+
export { TelegramTerminal } from "./terminals/telegramTerminal.js";
|
|
27
|
+
export { DiscordTerminal } from "./terminals/discordTerminal.js";
|
|
28
|
+
export { OpenClawTerminal } from "./terminals/openclawTerminal.js";
|
|
29
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/chat/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal — Abstract base class for I/O adapters.
|
|
3
|
+
*
|
|
4
|
+
* Each terminal handles platform-specific message receive/send,
|
|
5
|
+
* but delegates all thinking to the shared ChatEngine.
|
|
6
|
+
*
|
|
7
|
+
* @module chat/terminal
|
|
8
|
+
*/
|
|
9
|
+
import type { ChatEngine } from "./chatEngine.js";
|
|
10
|
+
export declare abstract class Terminal {
|
|
11
|
+
protected engine: ChatEngine;
|
|
12
|
+
protected name: string;
|
|
13
|
+
constructor(engine: ChatEngine, name: string);
|
|
14
|
+
/** Start listening for messages. */
|
|
15
|
+
abstract start(): Promise<void>;
|
|
16
|
+
/** Stop the terminal gracefully. */
|
|
17
|
+
abstract stop(): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=terminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.d.ts","sourceRoot":"","sources":["../../src/chat/terminal.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAElD,8BAAsB,QAAQ;IAE1B,SAAS,CAAC,MAAM,EAAE,UAAU;IAC5B,SAAS,CAAC,IAAI,EAAE,MAAM;gBADZ,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,MAAM;IAGxB,oCAAoC;IACpC,QAAQ,CAAC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAE/B,oCAAoC;IACpC,QAAQ,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAC/B"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Terminal — Abstract base class for I/O adapters.
|
|
3
|
+
*
|
|
4
|
+
* Each terminal handles platform-specific message receive/send,
|
|
5
|
+
* but delegates all thinking to the shared ChatEngine.
|
|
6
|
+
*
|
|
7
|
+
* @module chat/terminal
|
|
8
|
+
*/
|
|
9
|
+
export class Terminal {
|
|
10
|
+
engine;
|
|
11
|
+
name;
|
|
12
|
+
constructor(engine, name) {
|
|
13
|
+
this.engine = engine;
|
|
14
|
+
this.name = name;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=terminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"terminal.js","sourceRoot":"","sources":["../../src/chat/terminal.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,MAAM,OAAgB,QAAQ;IAEhB;IACA;IAFZ,YACY,MAAkB,EAClB,IAAY;QADZ,WAAM,GAAN,MAAM,CAAY;QAClB,SAAI,GAAJ,IAAI,CAAQ;IACrB,CAAC;CAOL"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DiscordTerminal — Discord bot terminal using discord.js.
|
|
3
|
+
*
|
|
4
|
+
* Connects via WebSocket gateway, responds to mentions and DMs.
|
|
5
|
+
* discord.js is an optional peer dependency — only imported at runtime
|
|
6
|
+
* if `DISCORD_BOT_TOKEN` is set. No compile-time dependency on discord.js.
|
|
7
|
+
*
|
|
8
|
+
* User setup: Add `DISCORD_BOT_TOKEN=xxx` to `.env`.
|
|
9
|
+
*
|
|
10
|
+
* @module chat/terminals/discordTerminal
|
|
11
|
+
*/
|
|
12
|
+
import { Terminal } from "../terminal.js";
|
|
13
|
+
import type { ChatEngine } from "../chatEngine.js";
|
|
14
|
+
export declare class DiscordTerminal extends Terminal {
|
|
15
|
+
private botToken;
|
|
16
|
+
private client;
|
|
17
|
+
constructor(engine: ChatEngine, botToken: string);
|
|
18
|
+
start(): Promise<void>;
|
|
19
|
+
stop(): Promise<void>;
|
|
20
|
+
private splitMessage;
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=discordTerminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discordTerminal.d.ts","sourceRoot":"","sources":["../../../src/chat/terminals/discordTerminal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,qBAAa,eAAgB,SAAQ,QAAQ;IAC3C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAa;gBAEf,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM;IAK1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA4FtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAS3B,OAAO,CAAC,YAAY;CAgBrB"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DiscordTerminal — Discord bot terminal using discord.js.
|
|
3
|
+
*
|
|
4
|
+
* Connects via WebSocket gateway, responds to mentions and DMs.
|
|
5
|
+
* discord.js is an optional peer dependency — only imported at runtime
|
|
6
|
+
* if `DISCORD_BOT_TOKEN` is set. No compile-time dependency on discord.js.
|
|
7
|
+
*
|
|
8
|
+
* User setup: Add `DISCORD_BOT_TOKEN=xxx` to `.env`.
|
|
9
|
+
*
|
|
10
|
+
* @module chat/terminals/discordTerminal
|
|
11
|
+
*/
|
|
12
|
+
import { Terminal } from "../terminal.js";
|
|
13
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
14
|
+
export class DiscordTerminal extends Terminal {
|
|
15
|
+
botToken;
|
|
16
|
+
client = null;
|
|
17
|
+
constructor(engine, botToken) {
|
|
18
|
+
super(engine, "discord");
|
|
19
|
+
this.botToken = botToken;
|
|
20
|
+
}
|
|
21
|
+
async start() {
|
|
22
|
+
// Dynamic import — discord.js is optional, no compile-time dependency
|
|
23
|
+
// Use a variable to prevent TypeScript from resolving the module at compile time
|
|
24
|
+
let discordJs;
|
|
25
|
+
try {
|
|
26
|
+
const moduleName = "discord.js";
|
|
27
|
+
discordJs = await import(/* webpackIgnore: true */ moduleName);
|
|
28
|
+
}
|
|
29
|
+
catch {
|
|
30
|
+
console.error("[discord] discord.js not installed. Run: npm install discord.js");
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const { Client, GatewayIntentBits, Partials } = discordJs;
|
|
34
|
+
const client = new Client({
|
|
35
|
+
intents: [
|
|
36
|
+
GatewayIntentBits.Guilds,
|
|
37
|
+
GatewayIntentBits.GuildMessages,
|
|
38
|
+
GatewayIntentBits.MessageContent,
|
|
39
|
+
GatewayIntentBits.DirectMessages,
|
|
40
|
+
],
|
|
41
|
+
partials: [Partials.Channel], // Required for DMs
|
|
42
|
+
});
|
|
43
|
+
client.on("ready", () => {
|
|
44
|
+
console.log(`[discord] Connected as ${client.user?.tag ?? "unknown"}`);
|
|
45
|
+
});
|
|
46
|
+
client.on("messageCreate", async (message) => {
|
|
47
|
+
// Ignore bots (including self)
|
|
48
|
+
if (message.author.bot)
|
|
49
|
+
return;
|
|
50
|
+
// Only respond to DMs or when mentioned
|
|
51
|
+
const isDM = !message.guild;
|
|
52
|
+
const isMentioned = client.user && message.mentions.has(client.user);
|
|
53
|
+
if (!isDM && !isMentioned)
|
|
54
|
+
return;
|
|
55
|
+
// Strip the bot mention from the message text
|
|
56
|
+
let content = message.content;
|
|
57
|
+
if (isMentioned && client.user) {
|
|
58
|
+
content = content.replace(new RegExp(`<@!?${client.user.id}>`, "g"), "").trim();
|
|
59
|
+
}
|
|
60
|
+
if (!content)
|
|
61
|
+
return;
|
|
62
|
+
try {
|
|
63
|
+
// Show typing indicator
|
|
64
|
+
await message.channel.sendTyping();
|
|
65
|
+
const response = await this.engine.chat(content, {
|
|
66
|
+
platform: "discord",
|
|
67
|
+
senderId: message.author.id,
|
|
68
|
+
senderName: message.author.displayName ?? message.author.username,
|
|
69
|
+
channelId: message.channel.id,
|
|
70
|
+
});
|
|
71
|
+
// Discord has a 2000 char limit — split if needed
|
|
72
|
+
if (response.length <= 2000) {
|
|
73
|
+
await message.reply(response);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
// Split into chunks
|
|
77
|
+
const chunks = this.splitMessage(response, 2000);
|
|
78
|
+
for (let i = 0; i < chunks.length; i++) {
|
|
79
|
+
if (i === 0) {
|
|
80
|
+
await message.reply(chunks[i]);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
await message.channel.send(chunks[i]);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (err) {
|
|
89
|
+
console.error("[discord] Message handling failed:", err instanceof Error ? err.message : err);
|
|
90
|
+
try {
|
|
91
|
+
await message.reply("Sorry, I encountered an error processing your message.");
|
|
92
|
+
}
|
|
93
|
+
catch {
|
|
94
|
+
// Best effort
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
});
|
|
98
|
+
try {
|
|
99
|
+
await client.login(this.botToken);
|
|
100
|
+
this.client = client;
|
|
101
|
+
}
|
|
102
|
+
catch (err) {
|
|
103
|
+
console.error("[discord] Login failed:", err instanceof Error ? err.message : err);
|
|
104
|
+
console.error("[discord] Check DISCORD_BOT_TOKEN in .env");
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
async stop() {
|
|
108
|
+
if (this.client) {
|
|
109
|
+
this.client.destroy();
|
|
110
|
+
this.client = null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
// ── Private ────────────────────────────────────────────────
|
|
114
|
+
splitMessage(text, maxLength) {
|
|
115
|
+
const chunks = [];
|
|
116
|
+
let remaining = text;
|
|
117
|
+
while (remaining.length > 0) {
|
|
118
|
+
if (remaining.length <= maxLength) {
|
|
119
|
+
chunks.push(remaining);
|
|
120
|
+
break;
|
|
121
|
+
}
|
|
122
|
+
// Try to split at a newline
|
|
123
|
+
let splitIndex = remaining.lastIndexOf("\n", maxLength);
|
|
124
|
+
if (splitIndex <= 0)
|
|
125
|
+
splitIndex = maxLength;
|
|
126
|
+
chunks.push(remaining.slice(0, splitIndex));
|
|
127
|
+
remaining = remaining.slice(splitIndex).trimStart();
|
|
128
|
+
}
|
|
129
|
+
return chunks;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=discordTerminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"discordTerminal.js","sourceRoot":"","sources":["../../../src/chat/terminals/discordTerminal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClawTerminal — OpenAI-compatible HTTP server for OpenClaw integration.
|
|
3
|
+
*
|
|
4
|
+
* Starts an HTTP server on port 18789 (OpenClaw auto-detection port) that
|
|
5
|
+
* implements the OpenAI Chat Completions API format. This makes the agent
|
|
6
|
+
* automatically discoverable by OpenClaw.
|
|
7
|
+
*
|
|
8
|
+
* Endpoints:
|
|
9
|
+
* - POST /v1/chat/completions — Chat with the agent (OpenAI format)
|
|
10
|
+
* - GET /v1/models — List available models
|
|
11
|
+
* - GET /hooks/agent — OpenClaw discovery endpoint
|
|
12
|
+
*
|
|
13
|
+
* Zero external dependencies — uses Node built-in `http`.
|
|
14
|
+
*
|
|
15
|
+
* User setup: Set `OPENCLAW_ENABLED=true` in `.env`.
|
|
16
|
+
*
|
|
17
|
+
* @module chat/terminals/openclawTerminal
|
|
18
|
+
*/
|
|
19
|
+
import { Terminal } from "../terminal.js";
|
|
20
|
+
import type { ChatEngine } from "../chatEngine.js";
|
|
21
|
+
export declare class OpenClawTerminal extends Terminal {
|
|
22
|
+
private port;
|
|
23
|
+
private server;
|
|
24
|
+
constructor(engine: ChatEngine, port?: number);
|
|
25
|
+
start(): Promise<void>;
|
|
26
|
+
stop(): Promise<void>;
|
|
27
|
+
private handleRequest;
|
|
28
|
+
/**
|
|
29
|
+
* GET /hooks/agent — OpenClaw discovery endpoint.
|
|
30
|
+
*/
|
|
31
|
+
private handleDiscovery;
|
|
32
|
+
/**
|
|
33
|
+
* GET /v1/models — OpenAI-compatible model listing.
|
|
34
|
+
*/
|
|
35
|
+
private handleModels;
|
|
36
|
+
/**
|
|
37
|
+
* POST /v1/chat/completions — OpenAI-compatible chat completions.
|
|
38
|
+
*/
|
|
39
|
+
private handleChatCompletion;
|
|
40
|
+
private sendJson;
|
|
41
|
+
private readBody;
|
|
42
|
+
}
|
|
43
|
+
//# sourceMappingURL=openclawTerminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclawTerminal.d.ts","sourceRoot":"","sources":["../../../src/chat/terminals/openclawTerminal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,qBAAa,gBAAiB,SAAQ,QAAQ;IAC5C,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,MAAM,CAAuB;gBAEzB,MAAM,EAAE,UAAU,EAAE,IAAI,SAAQ;IAKtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IA2BtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAab,aAAa;IAqC3B;;OAEG;IACH,OAAO,CAAC,eAAe;IASvB;;OAEG;IACH,OAAO,CAAC,YAAY;IAcpB;;OAEG;YACW,oBAAoB;IAsDlC,OAAO,CAAC,QAAQ;IAKhB,OAAO,CAAC,QAAQ;CAQjB"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OpenClawTerminal — OpenAI-compatible HTTP server for OpenClaw integration.
|
|
3
|
+
*
|
|
4
|
+
* Starts an HTTP server on port 18789 (OpenClaw auto-detection port) that
|
|
5
|
+
* implements the OpenAI Chat Completions API format. This makes the agent
|
|
6
|
+
* automatically discoverable by OpenClaw.
|
|
7
|
+
*
|
|
8
|
+
* Endpoints:
|
|
9
|
+
* - POST /v1/chat/completions — Chat with the agent (OpenAI format)
|
|
10
|
+
* - GET /v1/models — List available models
|
|
11
|
+
* - GET /hooks/agent — OpenClaw discovery endpoint
|
|
12
|
+
*
|
|
13
|
+
* Zero external dependencies — uses Node built-in `http`.
|
|
14
|
+
*
|
|
15
|
+
* User setup: Set `OPENCLAW_ENABLED=true` in `.env`.
|
|
16
|
+
*
|
|
17
|
+
* @module chat/terminals/openclawTerminal
|
|
18
|
+
*/
|
|
19
|
+
import { createServer } from "node:http";
|
|
20
|
+
import { Terminal } from "../terminal.js";
|
|
21
|
+
export class OpenClawTerminal extends Terminal {
|
|
22
|
+
port;
|
|
23
|
+
server = null;
|
|
24
|
+
constructor(engine, port = 18789) {
|
|
25
|
+
super(engine, "openclaw");
|
|
26
|
+
this.port = port;
|
|
27
|
+
}
|
|
28
|
+
async start() {
|
|
29
|
+
this.server = createServer(async (req, res) => {
|
|
30
|
+
try {
|
|
31
|
+
await this.handleRequest(req, res);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
console.error("[openclaw] Request error:", err instanceof Error ? err.message : err);
|
|
35
|
+
this.sendJson(res, 500, { error: "Internal server error" });
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
return new Promise((resolve, reject) => {
|
|
39
|
+
this.server.listen(this.port, () => {
|
|
40
|
+
console.log(`[openclaw] Listening on http://127.0.0.1:${this.port}`);
|
|
41
|
+
console.log(`[openclaw] Discovery: GET http://127.0.0.1:${this.port}/hooks/agent`);
|
|
42
|
+
console.log(`[openclaw] Chat: POST http://127.0.0.1:${this.port}/v1/chat/completions`);
|
|
43
|
+
resolve();
|
|
44
|
+
});
|
|
45
|
+
this.server.on("error", (err) => {
|
|
46
|
+
if (err.code === "EADDRINUSE") {
|
|
47
|
+
console.error(`[openclaw] Port ${this.port} already in use — is another agent running?`);
|
|
48
|
+
}
|
|
49
|
+
reject(err);
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
async stop() {
|
|
54
|
+
return new Promise((resolve) => {
|
|
55
|
+
if (this.server) {
|
|
56
|
+
this.server.close(() => resolve());
|
|
57
|
+
this.server = null;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
resolve();
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
// ── Private ────────────────────────────────────────────────
|
|
65
|
+
async handleRequest(req, res) {
|
|
66
|
+
const url = req.url ?? "/";
|
|
67
|
+
const method = req.method ?? "GET";
|
|
68
|
+
// CORS headers
|
|
69
|
+
res.setHeader("Access-Control-Allow-Origin", "*");
|
|
70
|
+
res.setHeader("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
71
|
+
res.setHeader("Access-Control-Allow-Headers", "Content-Type, Authorization");
|
|
72
|
+
if (method === "OPTIONS") {
|
|
73
|
+
res.writeHead(204);
|
|
74
|
+
res.end();
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
// Route requests
|
|
78
|
+
if (method === "GET" && url === "/hooks/agent") {
|
|
79
|
+
return this.handleDiscovery(res);
|
|
80
|
+
}
|
|
81
|
+
if (method === "GET" && url === "/v1/models") {
|
|
82
|
+
return this.handleModels(res);
|
|
83
|
+
}
|
|
84
|
+
if (method === "POST" && url === "/v1/chat/completions") {
|
|
85
|
+
return this.handleChatCompletion(req, res);
|
|
86
|
+
}
|
|
87
|
+
// Health check
|
|
88
|
+
if (method === "GET" && (url === "/" || url === "/health")) {
|
|
89
|
+
this.sendJson(res, 200, { status: "ok", agent: this.engine.agentName });
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
this.sendJson(res, 404, { error: "Not found" });
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* GET /hooks/agent — OpenClaw discovery endpoint.
|
|
96
|
+
*/
|
|
97
|
+
handleDiscovery(res) {
|
|
98
|
+
this.sendJson(res, 200, {
|
|
99
|
+
name: this.engine.agentName,
|
|
100
|
+
description: `${this.engine.agentName} — a Nookplot agent`,
|
|
101
|
+
version: "1.0.0",
|
|
102
|
+
capabilities: ["chat"],
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* GET /v1/models — OpenAI-compatible model listing.
|
|
107
|
+
*/
|
|
108
|
+
handleModels(res) {
|
|
109
|
+
this.sendJson(res, 200, {
|
|
110
|
+
object: "list",
|
|
111
|
+
data: [
|
|
112
|
+
{
|
|
113
|
+
id: this.engine.agentName.toLowerCase().replace(/\s+/g, "-"),
|
|
114
|
+
object: "model",
|
|
115
|
+
created: Math.floor(Date.now() / 1000),
|
|
116
|
+
owned_by: "nookplot",
|
|
117
|
+
},
|
|
118
|
+
],
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* POST /v1/chat/completions — OpenAI-compatible chat completions.
|
|
123
|
+
*/
|
|
124
|
+
async handleChatCompletion(req, res) {
|
|
125
|
+
const body = await this.readBody(req);
|
|
126
|
+
if (!body) {
|
|
127
|
+
this.sendJson(res, 400, { error: "Invalid request body" });
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
let parsed;
|
|
131
|
+
try {
|
|
132
|
+
parsed = JSON.parse(body);
|
|
133
|
+
}
|
|
134
|
+
catch {
|
|
135
|
+
this.sendJson(res, 400, { error: "Invalid JSON" });
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
// Extract the last user message
|
|
139
|
+
const messages = parsed.messages ?? [];
|
|
140
|
+
const lastUserMessage = [...messages].reverse().find((m) => m.role === "user");
|
|
141
|
+
if (!lastUserMessage?.content) {
|
|
142
|
+
this.sendJson(res, 400, { error: "No user message found" });
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
// Chat with the engine
|
|
146
|
+
const response = await this.engine.chat(lastUserMessage.content, {
|
|
147
|
+
platform: "openclaw",
|
|
148
|
+
});
|
|
149
|
+
// Return OpenAI-format response
|
|
150
|
+
this.sendJson(res, 200, {
|
|
151
|
+
id: `chatcmpl-${Date.now()}`,
|
|
152
|
+
object: "chat.completion",
|
|
153
|
+
created: Math.floor(Date.now() / 1000),
|
|
154
|
+
model: this.engine.agentName.toLowerCase().replace(/\s+/g, "-"),
|
|
155
|
+
choices: [
|
|
156
|
+
{
|
|
157
|
+
index: 0,
|
|
158
|
+
message: {
|
|
159
|
+
role: "assistant",
|
|
160
|
+
content: response,
|
|
161
|
+
},
|
|
162
|
+
finish_reason: "stop",
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
usage: {
|
|
166
|
+
prompt_tokens: 0,
|
|
167
|
+
completion_tokens: 0,
|
|
168
|
+
total_tokens: 0,
|
|
169
|
+
},
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
// ── Helpers ────────────────────────────────────────────────
|
|
173
|
+
sendJson(res, status, data) {
|
|
174
|
+
res.writeHead(status, { "Content-Type": "application/json" });
|
|
175
|
+
res.end(JSON.stringify(data));
|
|
176
|
+
}
|
|
177
|
+
readBody(req) {
|
|
178
|
+
return new Promise((resolve) => {
|
|
179
|
+
const chunks = [];
|
|
180
|
+
req.on("data", (chunk) => chunks.push(chunk));
|
|
181
|
+
req.on("end", () => resolve(Buffer.concat(chunks).toString()));
|
|
182
|
+
req.on("error", () => resolve(null));
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
//# sourceMappingURL=openclawTerminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"openclawTerminal.js","sourceRoot":"","sources":["../../../src/chat/terminals/openclawTerminal.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StdinTerminal — Interactive readline-based terminal chat.
|
|
3
|
+
*
|
|
4
|
+
* Provides a local chat interface via stdin/stdout.
|
|
5
|
+
* Zero external dependencies (uses Node built-in `readline`).
|
|
6
|
+
*
|
|
7
|
+
* @module chat/terminals/stdinTerminal
|
|
8
|
+
*/
|
|
9
|
+
import { Terminal } from "../terminal.js";
|
|
10
|
+
import type { ChatEngine } from "../chatEngine.js";
|
|
11
|
+
export declare class StdinTerminal extends Terminal {
|
|
12
|
+
private rl;
|
|
13
|
+
private running;
|
|
14
|
+
constructor(engine: ChatEngine);
|
|
15
|
+
start(): Promise<void>;
|
|
16
|
+
stop(): Promise<void>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=stdinTerminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdinTerminal.d.ts","sourceRoot":"","sources":["../../../src/chat/terminals/stdinTerminal.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,qBAAa,aAAc,SAAQ,QAAQ;IACzC,OAAO,CAAC,EAAE,CAAkC;IAC5C,OAAO,CAAC,OAAO,CAAS;gBAEZ,MAAM,EAAE,UAAU;IAIxB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAuCtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAO5B"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StdinTerminal — Interactive readline-based terminal chat.
|
|
3
|
+
*
|
|
4
|
+
* Provides a local chat interface via stdin/stdout.
|
|
5
|
+
* Zero external dependencies (uses Node built-in `readline`).
|
|
6
|
+
*
|
|
7
|
+
* @module chat/terminals/stdinTerminal
|
|
8
|
+
*/
|
|
9
|
+
import { createInterface } from "node:readline";
|
|
10
|
+
import { Terminal } from "../terminal.js";
|
|
11
|
+
export class StdinTerminal extends Terminal {
|
|
12
|
+
rl = null;
|
|
13
|
+
running = false;
|
|
14
|
+
constructor(engine) {
|
|
15
|
+
super(engine, "terminal");
|
|
16
|
+
}
|
|
17
|
+
async start() {
|
|
18
|
+
this.running = true;
|
|
19
|
+
this.rl = createInterface({
|
|
20
|
+
input: process.stdin,
|
|
21
|
+
output: process.stdout,
|
|
22
|
+
});
|
|
23
|
+
console.log(`\n${this.engine.agentName} > Ready. Type a message (Ctrl+C to quit).\n`);
|
|
24
|
+
this.rl.on("line", async (line) => {
|
|
25
|
+
const trimmed = line.trim();
|
|
26
|
+
if (!trimmed)
|
|
27
|
+
return;
|
|
28
|
+
try {
|
|
29
|
+
const response = await this.engine.chat(trimmed, { platform: "terminal" });
|
|
30
|
+
console.log(`\n${this.engine.agentName} > ${response}\n`);
|
|
31
|
+
}
|
|
32
|
+
catch (err) {
|
|
33
|
+
console.error(`\n[error] ${err instanceof Error ? err.message : String(err)}\n`);
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
this.rl.on("close", () => {
|
|
37
|
+
this.running = false;
|
|
38
|
+
});
|
|
39
|
+
// Set the prompt
|
|
40
|
+
this.rl.setPrompt("you > ");
|
|
41
|
+
this.rl.prompt();
|
|
42
|
+
// Re-prompt after each response
|
|
43
|
+
this.rl.on("line", () => {
|
|
44
|
+
if (this.running) {
|
|
45
|
+
// Small delay to let the response print first
|
|
46
|
+
setTimeout(() => this.rl?.prompt(), 50);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
async stop() {
|
|
51
|
+
this.running = false;
|
|
52
|
+
if (this.rl) {
|
|
53
|
+
this.rl.close();
|
|
54
|
+
this.rl = null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=stdinTerminal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stdinTerminal.js","sourceRoot":"","sources":["../../../src/chat/terminals/stdinTerminal.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,eAAe,EAAuC,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAG1C,MAAM,OAAO,aAAc,SAAQ,QAAQ;IACjC,EAAE,GAA6B,IAAI,CAAC;IACpC,OAAO,GAAG,KAAK,CAAC;IAExB,YAAY,MAAkB;QAC5B,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,IAAI,CAAC,EAAE,GAAG,eAAe,CAAC;YACxB,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,MAAM,EAAE,OAAO,CAAC,MAAM;SACvB,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,8CAA8C,CAAC,CAAC;QAEtF,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,IAAY,EAAE,EAAE;YACxC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC5B,IAAI,CAAC,OAAO;gBAAE,OAAO;YAErB,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;gBAC3E,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,SAAS,MAAM,QAAQ,IAAI,CAAC,CAAC;YAC5D,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,KAAK,CAAC,aAAa,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YACnF,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YACvB,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,CAAC,CAAC,CAAC;QAEH,iBAAiB;QACjB,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAC5B,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC;QAEjB,gCAAgC;QAChC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,MAAM,EAAE,GAAG,EAAE;YACtB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,8CAA8C;gBAC9C,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,IAAI,CAAC,EAAE,EAAE,CAAC;YACZ,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,EAAE,GAAG,IAAI,CAAC;QACjB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TelegramTerminal — Long-polling Telegram bot terminal.
|
|
3
|
+
*
|
|
4
|
+
* Uses the Telegram Bot API `getUpdates` endpoint with long-polling,
|
|
5
|
+
* so it works locally without a public URL (unlike webhook mode).
|
|
6
|
+
*
|
|
7
|
+
* Zero external dependencies — uses Node built-in `fetch`.
|
|
8
|
+
*
|
|
9
|
+
* User setup: Add `TELEGRAM_BOT_TOKEN=xxx` to `.env`.
|
|
10
|
+
*
|
|
11
|
+
* @module chat/terminals/telegramTerminal
|
|
12
|
+
*/
|
|
13
|
+
import { Terminal } from "../terminal.js";
|
|
14
|
+
import type { ChatEngine } from "../chatEngine.js";
|
|
15
|
+
export declare class TelegramTerminal extends Terminal {
|
|
16
|
+
private botToken;
|
|
17
|
+
private running;
|
|
18
|
+
private offset;
|
|
19
|
+
private abortController;
|
|
20
|
+
constructor(engine: ChatEngine, botToken: string);
|
|
21
|
+
start(): Promise<void>;
|
|
22
|
+
stop(): Promise<void>;
|
|
23
|
+
private pollLoop;
|
|
24
|
+
private handleMessage;
|
|
25
|
+
private sleep;
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=telegramTerminal.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telegramTerminal.d.ts","sourceRoot":"","sources":["../../../src/chat/terminals/telegramTerminal.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAiBnD,qBAAa,gBAAiB,SAAQ,QAAQ;IAC5C,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,eAAe,CAAgC;gBAE3C,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM;IAK1C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;IAyBtB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;YAUb,QAAQ;YA6CR,aAAa;IA8B3B,OAAO,CAAC,KAAK;CAGd"}
|