@cremini/skillpack 1.0.8 → 1.0.9-im.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/README.md +3 -1
  2. package/dist/cli.js +45 -11
  3. package/package.json +3 -2
  4. package/runtime/server/dist/adapters/markdown.js +74 -0
  5. package/runtime/server/dist/adapters/markdown.js.map +1 -0
  6. package/runtime/server/dist/adapters/slack.js +369 -0
  7. package/runtime/server/dist/adapters/slack.js.map +1 -0
  8. package/runtime/server/dist/adapters/telegram.js +199 -0
  9. package/runtime/server/dist/adapters/telegram.js.map +1 -0
  10. package/runtime/server/dist/adapters/types.js +2 -0
  11. package/runtime/server/dist/adapters/types.js.map +1 -0
  12. package/runtime/server/dist/adapters/web.js +168 -0
  13. package/runtime/server/dist/adapters/web.js.map +1 -0
  14. package/runtime/server/dist/agent.js +219 -0
  15. package/runtime/server/dist/agent.js.map +1 -0
  16. package/runtime/server/dist/config.js +73 -0
  17. package/runtime/server/dist/config.js.map +1 -0
  18. package/runtime/server/dist/index.js +122 -0
  19. package/runtime/server/dist/index.js.map +1 -0
  20. package/runtime/server/package-lock.json +2768 -121
  21. package/runtime/server/package.json +13 -3
  22. package/runtime/start.bat +2 -2
  23. package/runtime/start.sh +1 -1
  24. package/runtime/web/index.html +58 -15
  25. package/runtime/web/js/api.js +13 -0
  26. package/runtime/web/{app.js → js/chat.js} +126 -193
  27. package/runtime/web/js/config.js +15 -0
  28. package/runtime/web/js/main.js +47 -0
  29. package/runtime/web/js/settings.js +132 -0
  30. package/runtime/web/styles.css +171 -0
  31. package/runtime/server/chat-proxy.js +0 -161
  32. package/runtime/server/index.js +0 -63
  33. package/runtime/server/routes.js +0 -104
@@ -0,0 +1,199 @@
1
+ import TelegramBot from "node-telegram-bot-api";
2
+ import { formatTelegramMessage } from "./markdown.js";
3
+ const COMMANDS = {
4
+ "/clear": "clear",
5
+ "/restart": "restart",
6
+ "/shutdown": "shutdown",
7
+ };
8
+ const MAX_MESSAGE_LENGTH = 4096;
9
+ const ACK_REACTION = {
10
+ type: "emoji",
11
+ emoji: "👀",
12
+ };
13
+ // ---------------------------------------------------------------------------
14
+ // TelegramAdapter
15
+ // ---------------------------------------------------------------------------
16
+ export class TelegramAdapter {
17
+ name = "telegram";
18
+ bot = null;
19
+ agent = null;
20
+ options;
21
+ constructor(options) {
22
+ this.options = options;
23
+ }
24
+ async start(ctx) {
25
+ this.agent = ctx.agent;
26
+ this.bot = new TelegramBot(this.options.token, { polling: true });
27
+ this.bot.on("message", (msg) => {
28
+ this.handleTelegramMessage(msg).catch((err) => {
29
+ console.error("[Telegram] Error handling message:", err);
30
+ });
31
+ });
32
+ // Register bot commands with Telegram
33
+ await this.bot.setMyCommands([
34
+ { command: "clear", description: "Clear current session and start new" },
35
+ { command: "restart", description: "Restart the server process" },
36
+ { command: "shutdown", description: "Shut down the server process" },
37
+ ]);
38
+ const me = await this.bot.getMe();
39
+ console.log(`[TelegramAdapter] Started as @${me.username}`);
40
+ }
41
+ async stop() {
42
+ if (this.bot) {
43
+ await this.bot.stopPolling();
44
+ this.bot = null;
45
+ }
46
+ console.log("[TelegramAdapter] Stopped");
47
+ }
48
+ // -------------------------------------------------------------------------
49
+ // Message handler
50
+ // -------------------------------------------------------------------------
51
+ async handleTelegramMessage(msg) {
52
+ if (!this.bot || !this.agent)
53
+ return;
54
+ const chatId = msg.chat.id;
55
+ const messageId = msg.message_id;
56
+ const text = msg.text?.trim();
57
+ if (!text)
58
+ return;
59
+ const channelId = `telegram-${chatId}`;
60
+ await this.tryAckReaction(chatId, messageId);
61
+ // --- Command handling ---
62
+ const commandKey = text.split(/\s/)[0].toLowerCase();
63
+ const command = COMMANDS[commandKey];
64
+ if (command) {
65
+ const result = await this.agent.handleCommand(command, channelId);
66
+ await this.sendSafe(chatId, result.message || `/${command} executed.`);
67
+ return;
68
+ }
69
+ // --- Regular message → agent ---
70
+ // Send a "thinking" indicator
71
+ await this.bot.sendChatAction(chatId, "typing");
72
+ let finalText = "";
73
+ let hasError = false;
74
+ let errorMessage = "";
75
+ const onEvent = (event) => {
76
+ // Only collect final text; skip thinking/tool intermediate events
77
+ switch (event.type) {
78
+ case "text_delta":
79
+ finalText += event.delta;
80
+ break;
81
+ // We intentionally ignore thinking_delta, tool_start, tool_end
82
+ }
83
+ };
84
+ try {
85
+ const result = await this.agent.handleMessage(channelId, text, onEvent);
86
+ if (result.errorMessage) {
87
+ hasError = true;
88
+ errorMessage = result.errorMessage;
89
+ }
90
+ }
91
+ catch (err) {
92
+ hasError = true;
93
+ errorMessage = String(err);
94
+ }
95
+ // --- Send response ---
96
+ if (hasError) {
97
+ await this.sendSafe(chatId, `❌ Error: ${errorMessage}`);
98
+ return;
99
+ }
100
+ if (!finalText.trim()) {
101
+ await this.sendSafe(chatId, "(No response generated)");
102
+ return;
103
+ }
104
+ // Split and send the final text
105
+ await this.sendLongMessage(chatId, finalText);
106
+ }
107
+ // -------------------------------------------------------------------------
108
+ // Send helpers
109
+ // -------------------------------------------------------------------------
110
+ /**
111
+ * Send a message, splitting into chunks if too long.
112
+ */
113
+ async sendLongMessage(chatId, text) {
114
+ const chunks = this.splitMessage(text);
115
+ for (const chunk of chunks) {
116
+ await this.sendWithRetry(chatId, chunk);
117
+ }
118
+ }
119
+ /**
120
+ * React to the incoming message to show the bot has started processing it.
121
+ */
122
+ async tryAckReaction(chatId, messageId) {
123
+ try {
124
+ await this.bot?.setMessageReaction(chatId, messageId, {
125
+ reaction: [ACK_REACTION],
126
+ is_big: false,
127
+ });
128
+ }
129
+ catch (err) {
130
+ console.error("[Telegram] Failed to add ack reaction:", err);
131
+ }
132
+ }
133
+ /**
134
+ * Split text into chunks respecting Telegram's message length limit.
135
+ * Tries to split at paragraph boundaries.
136
+ */
137
+ splitMessage(text) {
138
+ if (text.length <= MAX_MESSAGE_LENGTH) {
139
+ return [text];
140
+ }
141
+ const chunks = [];
142
+ let remaining = text;
143
+ while (remaining.length > 0) {
144
+ if (remaining.length <= MAX_MESSAGE_LENGTH) {
145
+ chunks.push(remaining);
146
+ break;
147
+ }
148
+ // Find a good split point (paragraph break, then line break, then space)
149
+ let splitAt = remaining.lastIndexOf("\n\n", MAX_MESSAGE_LENGTH);
150
+ if (splitAt < MAX_MESSAGE_LENGTH * 0.5) {
151
+ splitAt = remaining.lastIndexOf("\n", MAX_MESSAGE_LENGTH);
152
+ }
153
+ if (splitAt < MAX_MESSAGE_LENGTH * 0.3) {
154
+ splitAt = remaining.lastIndexOf(" ", MAX_MESSAGE_LENGTH);
155
+ }
156
+ if (splitAt < 1) {
157
+ splitAt = MAX_MESSAGE_LENGTH;
158
+ }
159
+ chunks.push(remaining.slice(0, splitAt));
160
+ remaining = remaining.slice(splitAt).trimStart();
161
+ }
162
+ return chunks;
163
+ }
164
+ /**
165
+ * Send a message with automatic retry on 429 (rate limit).
166
+ */
167
+ async sendWithRetry(chatId, text, maxRetries = 3) {
168
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
169
+ try {
170
+ await this.bot.sendMessage(chatId, formatTelegramMessage(text), {
171
+ parse_mode: "HTML",
172
+ });
173
+ return;
174
+ }
175
+ catch (err) {
176
+ if (err?.response?.statusCode === 429 &&
177
+ attempt < maxRetries) {
178
+ const retryAfter = err.response?.body?.parameters?.retry_after || 5;
179
+ console.log(`[Telegram] Rate limited, retrying after ${retryAfter}s...`);
180
+ await new Promise((resolve) => setTimeout(resolve, retryAfter * 1000));
181
+ continue;
182
+ }
183
+ throw err;
184
+ }
185
+ }
186
+ }
187
+ /**
188
+ * Safe send that catches and logs errors.
189
+ */
190
+ async sendSafe(chatId, text) {
191
+ try {
192
+ await this.sendWithRetry(chatId, text);
193
+ }
194
+ catch (err) {
195
+ console.error("[Telegram] Failed to send message:", err);
196
+ }
197
+ }
198
+ }
199
+ //# sourceMappingURL=telegram.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"telegram.js","sourceRoot":"","sources":["../../src/adapters/telegram.ts"],"names":[],"mappings":"AAAA,OAAO,WAAW,MAAM,uBAAuB,CAAC;AAShD,OAAO,EAAE,qBAAqB,EAAE,MAAM,eAAe,CAAC;AAUtD,MAAM,QAAQ,GAA+B;IAC3C,QAAQ,EAAE,OAAO;IACjB,UAAU,EAAE,SAAS;IACrB,WAAW,EAAE,UAAU;CACxB,CAAC;AAEF,MAAM,kBAAkB,GAAG,IAAI,CAAC;AAChC,MAAM,YAAY,GAAG;IACnB,IAAI,EAAE,OAAgB;IACtB,KAAK,EAAE,IAAa;CACrB,CAAC;AAEF,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,MAAM,OAAO,eAAe;IACjB,IAAI,GAAG,UAAU,CAAC;IAEnB,GAAG,GAAuB,IAAI,CAAC;IAC/B,KAAK,GAAsB,IAAI,CAAC;IAChC,OAAO,CAAyB;IAExC,YAAY,OAA+B;QACzC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,KAAK,CAAC,GAAmB;QAC7B,IAAI,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;QAEvB,IAAI,CAAC,GAAG,GAAG,IAAI,WAAW,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAElE,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,GAAG,EAAE,EAAE;YAC7B,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC5C,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;YAC3D,CAAC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,sCAAsC;QACtC,MAAM,IAAI,CAAC,GAAG,CAAC,aAAa,CAAC;YAC3B,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,EAAE,qCAAqC,EAAE;YACxE,EAAE,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,4BAA4B,EAAE;YACjE,EAAE,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,8BAA8B,EAAE;SACrE,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;YAC7B,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;IAC3C,CAAC;IAED,4EAA4E;IAC5E,kBAAkB;IAClB,4EAA4E;IAEpE,KAAK,CAAC,qBAAqB,CAAC,GAAwB;QAC1D,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK;YAAE,OAAO;QAErC,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAG,GAAG,CAAC,UAAU,CAAC;QACjC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC;QAC9B,IAAI,CAAC,IAAI;YAAE,OAAO;QAElB,MAAM,SAAS,GAAG,YAAY,MAAM,EAAE,CAAC;QAEvC,MAAM,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAE7C,2BAA2B;QAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACrD,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;QAErC,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;YAClE,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,OAAO,IAAI,IAAI,OAAO,YAAY,CAAC,CAAC;YACvE,OAAO;QACT,CAAC;QAED,kCAAkC;QAClC,8BAA8B;QAC9B,MAAM,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;QAEhD,IAAI,SAAS,GAAG,EAAE,CAAC;QACnB,IAAI,QAAQ,GAAG,KAAK,CAAC;QACrB,IAAI,YAAY,GAAG,EAAE,CAAC;QAEtB,MAAM,OAAO,GAAG,CAAC,KAAiB,EAAE,EAAE;YACpC,kEAAkE;YAClE,QAAQ,KAAK,CAAC,IAAI,EAAE,CAAC;gBACnB,KAAK,YAAY;oBACf,SAAS,IAAI,KAAK,CAAC,KAAK,CAAC;oBACzB,MAAM;gBACR,+DAA+D;YACjE,CAAC;QACH,CAAC,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;YAExE,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;gBACxB,QAAQ,GAAG,IAAI,CAAC;gBAChB,YAAY,GAAG,MAAM,CAAC,YAAY,CAAC;YACrC,CAAC;QACH,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,GAAG,IAAI,CAAC;YAChB,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;QAED,wBAAwB;QACxB,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,YAAY,YAAY,EAAE,CAAC,CAAC;YACxD,OAAO;QACT,CAAC;QAED,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC;YACtB,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;YACvD,OAAO;QACT,CAAC;QAED,gCAAgC;QAChC,MAAM,IAAI,CAAC,eAAe,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAChD,CAAC;IAED,4EAA4E;IAC5E,eAAe;IACf,4EAA4E;IAE5E;;OAEG;IACK,KAAK,CAAC,eAAe,CAAC,MAAc,EAAE,IAAY;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAEvC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC1C,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,cAAc,CAC1B,MAAc,EACd,SAAiB;QAEjB,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,GAAG,EAAE,kBAAkB,CAAC,MAAM,EAAE,SAAS,EAAE;gBACpD,QAAQ,EAAE,CAAC,YAAY,CAAC;gBACxB,MAAM,EAAE,KAAK;aACd,CAAC,CAAC;QACL,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,wCAAwC,EAAE,GAAG,CAAC,CAAC;QAC/D,CAAC;IACH,CAAC;IAED;;;OAGG;IACK,YAAY,CAAC,IAAY;QAC/B,IAAI,IAAI,CAAC,MAAM,IAAI,kBAAkB,EAAE,CAAC;YACtC,OAAO,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;QAED,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,IAAI,SAAS,GAAG,IAAI,CAAC;QAErB,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,IAAI,SAAS,CAAC,MAAM,IAAI,kBAAkB,EAAE,CAAC;gBAC3C,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;gBACvB,MAAM;YACR,CAAC;YAED,yEAAyE;YACzE,IAAI,OAAO,GAAG,SAAS,CAAC,WAAW,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;YAChE,IAAI,OAAO,GAAG,kBAAkB,GAAG,GAAG,EAAE,CAAC;gBACvC,OAAO,GAAG,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,kBAAkB,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,OAAO,GAAG,kBAAkB,GAAG,GAAG,EAAE,CAAC;gBACvC,OAAO,GAAG,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,kBAAkB,CAAC,CAAC;YAC3D,CAAC;YACD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;gBAChB,OAAO,GAAG,kBAAkB,CAAC;YAC/B,CAAC;YAED,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;YACzC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,CAAC;QACnD,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,aAAa,CACzB,MAAc,EACd,IAAY,EACZ,UAAU,GAAG,CAAC;QAEd,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;YACvD,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,GAAI,CAAC,WAAW,CAAC,MAAM,EAAE,qBAAqB,CAAC,IAAI,CAAC,EAAE;oBAC/D,UAAU,EAAE,MAAM;iBACnB,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAClB,IACE,GAAG,EAAE,QAAQ,EAAE,UAAU,KAAK,GAAG;oBACjC,OAAO,GAAG,UAAU,EACpB,CAAC;oBACD,MAAM,UAAU,GACd,GAAG,CAAC,QAAQ,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,IAAI,CAAC,CAAC;oBACnD,OAAO,CAAC,GAAG,CACT,2CAA2C,UAAU,MAAM,CAC5D,CAAC;oBACF,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAC5B,UAAU,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI,CAAC,CACvC,CAAC;oBACF,SAAS;gBACX,CAAC;gBACD,MAAM,GAAG,CAAC;YACZ,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,QAAQ,CAAC,MAAc,EAAE,IAAY;QACjD,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QACzC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,oCAAoC,EAAE,GAAG,CAAC,CAAC;QAC3D,CAAC;IACH,CAAC;CACF"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,168 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { WebSocketServer } from "ws";
4
+ import { configManager } from "../config.js";
5
+ // ---------------------------------------------------------------------------
6
+ // Helpers
7
+ // ---------------------------------------------------------------------------
8
+ function getPackConfig(rootDir) {
9
+ const raw = fs.readFileSync(path.join(rootDir, "skillpack.json"), "utf-8");
10
+ return JSON.parse(raw);
11
+ }
12
+ const COMMANDS = {
13
+ "/clear": "clear",
14
+ "/restart": "restart",
15
+ "/shutdown": "shutdown",
16
+ };
17
+ function parseCommand(text) {
18
+ const trimmed = text.trim().toLowerCase();
19
+ return COMMANDS[trimmed] ?? null;
20
+ }
21
+ // ---------------------------------------------------------------------------
22
+ // WebAdapter
23
+ // ---------------------------------------------------------------------------
24
+ export class WebAdapter {
25
+ name = "web";
26
+ wss = null;
27
+ agent = null;
28
+ async start(ctx) {
29
+ const { agent, server, app, rootDir } = ctx;
30
+ this.agent = agent;
31
+ // -- API key & provider (in-memory, can be overridden by frontend) ------
32
+ const currentConf = configManager.getConfig();
33
+ let apiKey = currentConf.apiKey || "";
34
+ let currentProvider = currentConf.provider || "openai";
35
+ // -- HTTP API routes ----------------------------------------------------
36
+ app.get("/api/config", (_req, res) => {
37
+ const config = getPackConfig(rootDir);
38
+ const conf = configManager.getConfig();
39
+ res.json({
40
+ name: config.name,
41
+ description: config.description,
42
+ prompts: config.prompts || [],
43
+ skills: config.skills || [],
44
+ hasApiKey: !!conf.apiKey,
45
+ provider: conf.provider || "openai",
46
+ adapters: conf.adapters || {}
47
+ });
48
+ });
49
+ app.get("/api/skills", (_req, res) => {
50
+ const config = getPackConfig(rootDir);
51
+ res.json(config.skills || []);
52
+ });
53
+ app.post("/api/config/update", (req, res) => {
54
+ const { key, provider, adapters } = req.body;
55
+ const updates = {};
56
+ if (key !== undefined) {
57
+ updates.apiKey = key;
58
+ apiKey = key;
59
+ }
60
+ if (provider !== undefined) {
61
+ updates.provider = provider;
62
+ currentProvider = provider;
63
+ }
64
+ if (adapters !== undefined) {
65
+ updates.adapters = adapters;
66
+ }
67
+ configManager.save(rootDir, updates);
68
+ // Note: PackAgent instances need to be recreated or have their keys updated dynamically,
69
+ // but if the design is to restart to take effect or if we only need it persisted, this covers the save.
70
+ // Depending on agent implementation, we might need agent.updateConfig({ apiKey: key, provider: currentProvider })
71
+ const newConf = configManager.getConfig();
72
+ res.json({ success: true, provider: newConf.provider, adapters: newConf.adapters });
73
+ });
74
+ app.delete("/api/chat", (_req, res) => {
75
+ res.json({ success: true });
76
+ });
77
+ // -- Reserved: session history endpoints (stub) -------------------------
78
+ app.get("/api/sessions", (_req, res) => {
79
+ const sessions = agent.listSessions();
80
+ res.json(sessions);
81
+ });
82
+ app.get("/api/sessions/:id", (_req, res) => {
83
+ // TODO: restore session by id
84
+ res.status(501).json({ error: "Not implemented yet" });
85
+ });
86
+ // -- WebSocket ----------------------------------------------------------
87
+ this.wss = new WebSocketServer({ noServer: true });
88
+ server.on("upgrade", (request, socket, head) => {
89
+ if (request.url?.startsWith("/api/chat")) {
90
+ this.wss.handleUpgrade(request, socket, head, (ws) => {
91
+ this.wss.emit("connection", ws, request);
92
+ });
93
+ }
94
+ else {
95
+ socket.destroy();
96
+ }
97
+ });
98
+ this.wss.on("connection", (ws, request) => {
99
+ const url = new URL(request.url ?? "/", `http://${request.headers.host || "127.0.0.1"}`);
100
+ const _reqProvider = url.searchParams.get("provider") || currentProvider;
101
+ if (!apiKey) {
102
+ ws.send(JSON.stringify({ error: "Please set an API key first" }));
103
+ ws.close();
104
+ return;
105
+ }
106
+ // Each WebSocket connection maps to a unique channel
107
+ const channelId = `web-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
108
+ this.handleWsConnection(ws, channelId, agent);
109
+ });
110
+ console.log("[WebAdapter] Started");
111
+ }
112
+ async stop() {
113
+ if (this.wss) {
114
+ for (const client of this.wss.clients) {
115
+ client.close();
116
+ }
117
+ this.wss.close();
118
+ this.wss = null;
119
+ }
120
+ console.log("[WebAdapter] Stopped");
121
+ }
122
+ // -------------------------------------------------------------------------
123
+ // WebSocket message handler
124
+ // -------------------------------------------------------------------------
125
+ handleWsConnection(ws, channelId, agent) {
126
+ ws.on("message", async (data) => {
127
+ try {
128
+ const payload = JSON.parse(data.toString());
129
+ if (!payload.text)
130
+ return;
131
+ const text = payload.text;
132
+ // Check for bot commands
133
+ const command = parseCommand(text);
134
+ if (command) {
135
+ const result = await agent.handleCommand(command, channelId);
136
+ ws.send(JSON.stringify({
137
+ type: "command_result",
138
+ command,
139
+ ...result,
140
+ }));
141
+ if (command === "clear") {
142
+ ws.send(JSON.stringify({ done: true }));
143
+ }
144
+ return;
145
+ }
146
+ // Regular message → stream events via WebSocket
147
+ const onEvent = (event) => {
148
+ if (ws.readyState !== ws.OPEN)
149
+ return;
150
+ ws.send(JSON.stringify(event));
151
+ };
152
+ const result = await agent.handleMessage(channelId, text, onEvent);
153
+ if (result.errorMessage) {
154
+ ws.send(JSON.stringify({ error: result.errorMessage }));
155
+ return;
156
+ }
157
+ ws.send(JSON.stringify({ done: true }));
158
+ }
159
+ catch (err) {
160
+ ws.send(JSON.stringify({ error: String(err) }));
161
+ }
162
+ });
163
+ ws.on("close", () => {
164
+ agent.dispose(channelId);
165
+ });
166
+ }
167
+ }
168
+ //# sourceMappingURL=web.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/adapters/web.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,219 @@
1
+ import path from "node:path";
2
+ import { AuthStorage, createAgentSession, ModelRegistry, SessionManager, DefaultResourceLoader, } from "@mariozechner/pi-coding-agent";
3
+ const DEBUG = true;
4
+ const log = (...args) => DEBUG && console.log(...args);
5
+ const write = (data) => DEBUG && process.stdout.write(data);
6
+ function getAssistantDiagnostics(message) {
7
+ if (!message || message.role !== "assistant") {
8
+ return null;
9
+ }
10
+ const stopReason = message.stopReason ?? "unknown";
11
+ const errorMessage = message.errorMessage ||
12
+ (stopReason === "error" || stopReason === "aborted"
13
+ ? `Request ${stopReason}`
14
+ : "");
15
+ const content = Array.isArray(message.content) ? message.content : [];
16
+ const text = content
17
+ .filter((item) => item?.type === "text")
18
+ .map((item) => item.text || "")
19
+ .join("")
20
+ .trim();
21
+ const toolCalls = content.filter((item) => item?.type === "toolCall").length;
22
+ return { stopReason, errorMessage, hasText: text.length > 0, toolCalls };
23
+ }
24
+ // ---------------------------------------------------------------------------
25
+ // PackAgent
26
+ // ---------------------------------------------------------------------------
27
+ export class PackAgent {
28
+ options;
29
+ channels = new Map();
30
+ constructor(options) {
31
+ this.options = options;
32
+ }
33
+ /**
34
+ * Lazily create (or return existing) session for a channel.
35
+ */
36
+ async getOrCreateSession(channelId) {
37
+ const existing = this.channels.get(channelId);
38
+ if (existing)
39
+ return existing;
40
+ const { apiKey, rootDir, provider, modelId } = this.options;
41
+ const authStorage = AuthStorage.inMemory({
42
+ [provider]: { type: "api_key", key: apiKey },
43
+ });
44
+ authStorage.setRuntimeApiKey(provider, apiKey);
45
+ const modelRegistry = new ModelRegistry(authStorage);
46
+ const model = modelRegistry.find(provider, modelId);
47
+ const sessionManager = SessionManager.inMemory();
48
+ const skillsPath = path.resolve(rootDir, "skills");
49
+ log(`[PackAgent] Loading skills from: ${skillsPath}`);
50
+ const resourceLoader = new DefaultResourceLoader({
51
+ cwd: rootDir,
52
+ additionalSkillPaths: [skillsPath],
53
+ });
54
+ await resourceLoader.reload();
55
+ const { session } = await createAgentSession({
56
+ cwd: rootDir,
57
+ authStorage,
58
+ modelRegistry,
59
+ sessionManager,
60
+ resourceLoader,
61
+ model,
62
+ });
63
+ const channelSession = { session, running: false };
64
+ this.channels.set(channelId, channelSession);
65
+ return channelSession;
66
+ }
67
+ async handleMessage(channelId, text, onEvent) {
68
+ const cs = await this.getOrCreateSession(channelId);
69
+ cs.running = true;
70
+ let turnHadVisibleOutput = false;
71
+ // Subscribe to agent events and forward to adapter
72
+ const unsubscribe = cs.session.subscribe((event) => {
73
+ switch (event.type) {
74
+ case "agent_start":
75
+ log("\n=== [AGENT SESSION START] ===");
76
+ log("System Prompt:\n", cs.session.systemPrompt);
77
+ log("============================\n");
78
+ onEvent({ type: "agent_start" });
79
+ break;
80
+ case "message_start":
81
+ log(`\n--- [Message Start: ${event.message?.role}] ---`);
82
+ if (event.message?.role === "user") {
83
+ log(JSON.stringify(event.message.content, null, 2));
84
+ }
85
+ onEvent({ type: "message_start", role: event.message?.role ?? "" });
86
+ break;
87
+ case "message_update":
88
+ if (event.assistantMessageEvent?.type === "text_delta") {
89
+ turnHadVisibleOutput = true;
90
+ write(event.assistantMessageEvent.delta);
91
+ onEvent({
92
+ type: "text_delta",
93
+ delta: event.assistantMessageEvent.delta,
94
+ });
95
+ }
96
+ else if (event.assistantMessageEvent?.type === "thinking_delta") {
97
+ turnHadVisibleOutput = true;
98
+ onEvent({
99
+ type: "thinking_delta",
100
+ delta: event.assistantMessageEvent.delta,
101
+ });
102
+ }
103
+ break;
104
+ case "message_end":
105
+ log(`\n--- [Message End: ${event.message?.role}] ---`);
106
+ if (event.message?.role === "assistant") {
107
+ const diagnostics = getAssistantDiagnostics(event.message);
108
+ if (diagnostics) {
109
+ log(`[Assistant Diagnostics] stopReason=${diagnostics.stopReason} text=${diagnostics.hasText ? "yes" : "no"} toolCalls=${diagnostics.toolCalls}`);
110
+ if (diagnostics.errorMessage) {
111
+ log(`[Assistant Error] ${diagnostics.errorMessage}`);
112
+ }
113
+ }
114
+ }
115
+ onEvent({ type: "message_end", role: event.message?.role ?? "" });
116
+ break;
117
+ case "tool_execution_start":
118
+ turnHadVisibleOutput = true;
119
+ log(`\n>>> [Tool Start: ${event.toolName}] >>>`);
120
+ log("Args:", JSON.stringify(event.args, null, 2));
121
+ onEvent({
122
+ type: "tool_start",
123
+ toolName: event.toolName,
124
+ toolInput: event.args,
125
+ });
126
+ break;
127
+ case "tool_execution_end":
128
+ turnHadVisibleOutput = true;
129
+ log(`<<< [Tool End: ${event.toolName}] <<<`);
130
+ log(`Error: ${event.isError ? "Yes" : "No"}`);
131
+ onEvent({
132
+ type: "tool_end",
133
+ toolName: event.toolName,
134
+ isError: event.isError,
135
+ result: event.result,
136
+ });
137
+ break;
138
+ case "agent_end":
139
+ log("\n=== [AGENT SESSION END] ===\n");
140
+ onEvent({ type: "agent_end" });
141
+ break;
142
+ }
143
+ });
144
+ try {
145
+ await cs.session.prompt(text);
146
+ const lastMessage = cs.session.state.messages.at(-1);
147
+ const diagnostics = getAssistantDiagnostics(lastMessage);
148
+ if (diagnostics?.errorMessage) {
149
+ return {
150
+ stopReason: diagnostics.stopReason,
151
+ errorMessage: diagnostics.errorMessage,
152
+ };
153
+ }
154
+ if (diagnostics &&
155
+ !diagnostics.hasText &&
156
+ diagnostics.toolCalls === 0 &&
157
+ !turnHadVisibleOutput) {
158
+ return {
159
+ stopReason: diagnostics.stopReason,
160
+ errorMessage: "Assistant returned no visible output. Check the server logs for details.",
161
+ };
162
+ }
163
+ return { stopReason: diagnostics?.stopReason ?? "unknown" };
164
+ }
165
+ finally {
166
+ cs.running = false;
167
+ unsubscribe();
168
+ }
169
+ }
170
+ async handleCommand(command, channelId) {
171
+ switch (command) {
172
+ case "clear": {
173
+ const cs = this.channels.get(channelId);
174
+ if (cs) {
175
+ cs.session.dispose();
176
+ this.channels.delete(channelId);
177
+ }
178
+ return { success: true, message: "Session cleared." };
179
+ }
180
+ case "restart":
181
+ log("[PackAgent] Restart requested");
182
+ // Give a brief delay so the response can be sent
183
+ setTimeout(() => process.exit(0), 500);
184
+ return { success: true, message: "Restarting..." };
185
+ case "shutdown":
186
+ log("[PackAgent] Shutdown requested");
187
+ setTimeout(() => process.exit(0), 500);
188
+ return { success: true, message: "Shutting down..." };
189
+ default:
190
+ return { success: false, message: `Unknown command: ${command}` };
191
+ }
192
+ }
193
+ abort(channelId) {
194
+ const cs = this.channels.get(channelId);
195
+ if (cs?.running) {
196
+ cs.session.abort?.();
197
+ }
198
+ }
199
+ isRunning(channelId) {
200
+ return this.channels.get(channelId)?.running ?? false;
201
+ }
202
+ dispose(channelId) {
203
+ const cs = this.channels.get(channelId);
204
+ if (cs) {
205
+ cs.session.dispose();
206
+ this.channels.delete(channelId);
207
+ }
208
+ }
209
+ /** Reserved: list all sessions */
210
+ listSessions() {
211
+ // TODO: Implement session persistence and listing
212
+ return [];
213
+ }
214
+ /** Reserved: restore a historical session */
215
+ async restoreSession(_sessionId) {
216
+ // TODO: Implement session restoration
217
+ }
218
+ }
219
+ //# sourceMappingURL=agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}