@cremini/skillpack 1.0.9-im.1 → 1.0.9-im.3
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/package.json +1 -1
- package/runtime/README.md +16 -0
- package/runtime/ecosystem.config.cjs +20 -0
- package/runtime/server/dist/adapters/web.js +35 -3
- package/runtime/server/dist/adapters/web.js.map +1 -1
- package/runtime/server/dist/agent.js +9 -5
- package/runtime/server/dist/agent.js.map +1 -1
- package/runtime/server/dist/index.js +23 -4
- package/runtime/server/dist/index.js.map +1 -1
- package/runtime/server/dist/lifecycle.js +85 -0
- package/runtime/server/dist/lifecycle.js.map +1 -0
- package/runtime/web/index.html +2 -1
- package/runtime/web/js/api.js +12 -0
- package/runtime/web/js/config.js +2 -1
- package/runtime/web/js/settings.js +67 -9
- package/runtime/web/styles.css +26 -1
package/package.json
CHANGED
package/runtime/README.md
CHANGED
|
@@ -21,6 +21,21 @@ After the server starts, your browser opens [http://127.0.0.1:26313](http://127.
|
|
|
21
21
|
|
|
22
22
|
By default, the server only listens on `127.0.0.1` so the API key you enter stays on the local machine and is not exposed to your LAN.
|
|
23
23
|
|
|
24
|
+
## Managed Restart with PM2
|
|
25
|
+
|
|
26
|
+
If you want the web UI and bot commands to support in-app restart, run the server under PM2:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install -g pm2
|
|
30
|
+
pm2 start ecosystem.config.cjs
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Behavior:
|
|
34
|
+
|
|
35
|
+
- `/restart` or the web restart button exits with restart code `75`; PM2 brings the process back up
|
|
36
|
+
- `/shutdown` exits with code `64`; PM2 treats it as a stop and does not auto-restart
|
|
37
|
+
- When started via `start.sh` or `start.bat`, restart is manual only
|
|
38
|
+
|
|
24
39
|
## First Use
|
|
25
40
|
|
|
26
41
|
1. Enter your OpenAI or Anthropic API key in the left sidebar
|
|
@@ -39,3 +54,4 @@ By default, the server only listens on `127.0.0.1` so the API key you enter stay
|
|
|
39
54
|
| `ANTHROPIC_API_KEY` | Anthropic API key, optional if you set it in the web UI |
|
|
40
55
|
| `HOST` | Bind address, defaults to `127.0.0.1` |
|
|
41
56
|
| `PORT` | Server port, defaults to `26313` |
|
|
57
|
+
| `SKILLPACK_PROCESS_MANAGER` | Set to `pm2` when started under PM2 |
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
const path = require("node:path");
|
|
2
|
+
|
|
3
|
+
module.exports = {
|
|
4
|
+
apps: [
|
|
5
|
+
{
|
|
6
|
+
name: "skillpack",
|
|
7
|
+
cwd: path.join(__dirname, "server"),
|
|
8
|
+
script: "dist/index.js",
|
|
9
|
+
autorestart: true,
|
|
10
|
+
stop_exit_codes: [64],
|
|
11
|
+
restart_delay: 1000,
|
|
12
|
+
kill_timeout: 3000,
|
|
13
|
+
env: {
|
|
14
|
+
NODE_ENV: "production",
|
|
15
|
+
PACK_ROOT: __dirname,
|
|
16
|
+
SKILLPACK_PROCESS_MANAGER: "pm2",
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
],
|
|
20
|
+
};
|
|
@@ -18,6 +18,15 @@ function parseCommand(text) {
|
|
|
18
18
|
const trimmed = text.trim().toLowerCase();
|
|
19
19
|
return COMMANDS[trimmed] ?? null;
|
|
20
20
|
}
|
|
21
|
+
function getRuntimeConfigSignature(config) {
|
|
22
|
+
return JSON.stringify({
|
|
23
|
+
apiKey: config.apiKey || "",
|
|
24
|
+
provider: config.provider || "openai",
|
|
25
|
+
telegramToken: config.adapters?.telegram?.token || "",
|
|
26
|
+
slackBotToken: config.adapters?.slack?.botToken || "",
|
|
27
|
+
slackAppToken: config.adapters?.slack?.appToken || "",
|
|
28
|
+
});
|
|
29
|
+
}
|
|
21
30
|
// ---------------------------------------------------------------------------
|
|
22
31
|
// WebAdapter
|
|
23
32
|
// ---------------------------------------------------------------------------
|
|
@@ -26,7 +35,7 @@ export class WebAdapter {
|
|
|
26
35
|
wss = null;
|
|
27
36
|
agent = null;
|
|
28
37
|
async start(ctx) {
|
|
29
|
-
const { agent, server, app, rootDir } = ctx;
|
|
38
|
+
const { agent, server, app, rootDir, lifecycle } = ctx;
|
|
30
39
|
this.agent = agent;
|
|
31
40
|
// -- API key & provider (in-memory, can be overridden by frontend) ------
|
|
32
41
|
const currentConf = configManager.getConfig();
|
|
@@ -43,7 +52,8 @@ export class WebAdapter {
|
|
|
43
52
|
skills: config.skills || [],
|
|
44
53
|
hasApiKey: !!conf.apiKey,
|
|
45
54
|
provider: conf.provider || "openai",
|
|
46
|
-
adapters: conf.adapters || {}
|
|
55
|
+
adapters: conf.adapters || {},
|
|
56
|
+
runtimeControl: lifecycle.getRuntimeControl(),
|
|
47
57
|
});
|
|
48
58
|
});
|
|
49
59
|
app.get("/api/skills", (_req, res) => {
|
|
@@ -53,6 +63,7 @@ export class WebAdapter {
|
|
|
53
63
|
app.post("/api/config/update", (req, res) => {
|
|
54
64
|
const { key, provider, adapters } = req.body;
|
|
55
65
|
const updates = {};
|
|
66
|
+
const beforeConfig = JSON.parse(JSON.stringify(configManager.getConfig()));
|
|
56
67
|
if (key !== undefined) {
|
|
57
68
|
updates.apiKey = key;
|
|
58
69
|
apiKey = key;
|
|
@@ -69,7 +80,28 @@ export class WebAdapter {
|
|
|
69
80
|
// but if the design is to restart to take effect or if we only need it persisted, this covers the save.
|
|
70
81
|
// Depending on agent implementation, we might need agent.updateConfig({ apiKey: key, provider: currentProvider })
|
|
71
82
|
const newConf = configManager.getConfig();
|
|
72
|
-
|
|
83
|
+
const requiresRestart = getRuntimeConfigSignature(beforeConfig) !==
|
|
84
|
+
getRuntimeConfigSignature(newConf);
|
|
85
|
+
res.json({
|
|
86
|
+
success: true,
|
|
87
|
+
provider: newConf.provider,
|
|
88
|
+
adapters: newConf.adapters,
|
|
89
|
+
requiresRestart,
|
|
90
|
+
runtimeControl: lifecycle.getRuntimeControl(),
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
app.post("/api/runtime/restart", async (_req, res) => {
|
|
94
|
+
const runtimeControl = lifecycle.getRuntimeControl();
|
|
95
|
+
if (!runtimeControl.canManagedRestart) {
|
|
96
|
+
res.status(409).json({
|
|
97
|
+
success: false,
|
|
98
|
+
message: "Managed restart is unavailable for this process.",
|
|
99
|
+
runtimeControl,
|
|
100
|
+
});
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const result = await lifecycle.requestRestart("web");
|
|
104
|
+
res.status(202).json({ ...result, runtimeControl });
|
|
73
105
|
});
|
|
74
106
|
app.delete("/api/chat", (_req, res) => {
|
|
75
107
|
res.json({ success: true });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/adapters/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAkB,MAAM,IAAI,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/adapters/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,eAAe,EAAkB,MAAM,IAAI,CAAC;AACrD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAW7C,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,gBAAgB,CAAC,EAAE,OAAO,CAAC,CAAC;IAC3E,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,QAAQ,GAA+B;IAC3C,QAAQ,EAAE,OAAO;IACjB,UAAU,EAAE,SAAS;IACrB,WAAW,EAAE,UAAU;CACxB,CAAC;AAEF,SAAS,YAAY,CAAC,IAAY;IAChC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAC1C,OAAO,QAAQ,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;AACnC,CAAC;AAED,SAAS,yBAAyB,CAAC,MAAkB;IACnD,OAAO,IAAI,CAAC,SAAS,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;QAC3B,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,QAAQ;QACrC,aAAa,EAAE,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,IAAI,EAAE;QACrD,aAAa,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,EAAE;QACrD,aAAa,EAAE,MAAM,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,IAAI,EAAE;KACtD,CAAC,CAAC;AACL,CAAC;AAED,8EAA8E;AAC9E,aAAa;AACb,8EAA8E;AAE9E,MAAM,OAAO,UAAU;IACZ,IAAI,GAAG,KAAK,CAAC;IAEd,GAAG,GAA2B,IAAI,CAAC;IACnC,KAAK,GAAsB,IAAI,CAAC;IAExC,KAAK,CAAC,KAAK,CAAC,GAAmB;QAC7B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,GAAG,CAAC;QACvD,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QAEnB,0EAA0E;QAE1E,MAAM,WAAW,GAAG,aAAa,CAAC,SAAS,EAAE,CAAC;QAC9C,IAAI,MAAM,GAAG,WAAW,CAAC,MAAM,IAAI,EAAE,CAAC;QACtC,IAAI,eAAe,GAAG,WAAW,CAAC,QAAQ,IAAI,QAAQ,CAAC;QAEvD,0EAA0E;QAE1E,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACnC,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;YACtC,MAAM,IAAI,GAAG,aAAa,CAAC,SAAS,EAAE,CAAC;YACvC,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,WAAW,EAAE,MAAM,CAAC,WAAW;gBAC/B,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;gBAC7B,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,EAAE;gBAC3B,SAAS,EAAE,CAAC,CAAC,IAAI,CAAC,MAAM;gBACxB,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,QAAQ;gBACnC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,EAAE;gBAC7B,cAAc,EAAE,SAAS,CAAC,iBAAiB,EAAE;aAC9C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACnC,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;YACtC,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC,CAAC;QAChC,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,IAAI,CAAC,oBAAoB,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;YAC1C,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC,IAAI,CAAC;YAC7C,MAAM,OAAO,GAAQ,EAAE,CAAC;YACxB,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YAE3E,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACtB,OAAO,CAAC,MAAM,GAAG,GAAG,CAAC;gBACrB,MAAM,GAAG,GAAG,CAAC;YACf,CAAC;YACD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;gBAC5B,eAAe,GAAG,QAAQ,CAAC;YAC7B,CAAC;YACD,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC3B,OAAO,CAAC,QAAQ,GAAG,QAAQ,CAAC;YAC9B,CAAC;YAED,aAAa,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;YAErC,0FAA0F;YAC1F,wGAAwG;YACxG,kHAAkH;YAElH,MAAM,OAAO,GAAG,aAAa,CAAC,SAAS,EAAE,CAAC;YAC1C,MAAM,eAAe,GACnB,yBAAyB,CAAC,YAAY,CAAC;gBACvC,yBAAyB,CAAC,OAAO,CAAC,CAAC;YACrC,GAAG,CAAC,IAAI,CAAC;gBACP,OAAO,EAAE,IAAI;gBACb,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,QAAQ,EAAE,OAAO,CAAC,QAAQ;gBAC1B,eAAe;gBACf,cAAc,EAAE,SAAS,CAAC,iBAAiB,EAAE;aAC9C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,IAAI,CAAC,sBAAsB,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,EAAE,EAAE;YACnD,MAAM,cAAc,GAAG,SAAS,CAAC,iBAAiB,EAAE,CAAC;YACrD,IAAI,CAAC,cAAc,CAAC,iBAAiB,EAAE,CAAC;gBACtC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACnB,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,kDAAkD;oBAC3D,cAAc;iBACf,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YAED,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC;YACrD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,cAAc,EAAE,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,MAAM,CAAC,WAAW,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACpC,GAAG,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QAEH,0EAA0E;QAE1E,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACrC,MAAM,QAAQ,GAAG,KAAK,CAAC,YAAY,EAAE,CAAC;YACtC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrB,CAAC,CAAC,CAAC;QAEH,GAAG,CAAC,GAAG,CAAC,mBAAmB,EAAE,CAAC,IAAI,EAAE,GAAG,EAAE,EAAE;YACzC,8BAA8B;YAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,qBAAqB,EAAE,CAAC,CAAC;QACzD,CAAC,CAAC,CAAC;QAEH,0EAA0E;QAE1E,IAAI,CAAC,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAEnD,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE;YAC7C,IAAI,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;gBACzC,IAAI,CAAC,GAAI,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,EAAE;oBACpD,IAAI,CAAC,GAAI,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;gBAC5C,CAAC,CAAC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACN,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,EAAa,EAAE,OAAO,EAAE,EAAE;YACnD,MAAM,GAAG,GAAG,IAAI,GAAG,CACjB,OAAO,CAAC,GAAG,IAAI,GAAG,EAClB,UAAU,OAAO,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,EAAE,CAChD,CAAC;YACF,MAAM,YAAY,GAChB,GAAG,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,eAAe,CAAC;YAEtD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACZ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,6BAA6B,EAAE,CAAC,CAAC,CAAC;gBAClE,EAAE,CAAC,KAAK,EAAE,CAAC;gBACX,OAAO;YACT,CAAC;YAED,qDAAqD;YACrD,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YAEhF,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,SAAS,EAAE,KAAK,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC;YACb,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC;gBACtC,MAAM,CAAC,KAAK,EAAE,CAAC;YACjB,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC;YACjB,IAAI,CAAC,GAAG,GAAG,IAAI,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACtC,CAAC;IAED,4EAA4E;IAC5E,4BAA4B;IAC5B,4EAA4E;IAEpE,kBAAkB,CACxB,EAAa,EACb,SAAiB,EACjB,KAAiB;QAEjB,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE;YAC9B,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC5C,IAAI,CAAC,OAAO,CAAC,IAAI;oBAAE,OAAO;gBAE1B,MAAM,IAAI,GAAW,OAAO,CAAC,IAAI,CAAC;gBAElC,yBAAyB;gBACzB,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;gBACnC,IAAI,OAAO,EAAE,CAAC;oBACZ,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;oBAC7D,EAAE,CAAC,IAAI,CACL,IAAI,CAAC,SAAS,CAAC;wBACb,IAAI,EAAE,gBAAgB;wBACtB,OAAO;wBACP,GAAG,MAAM;qBACV,CAAC,CACH,CAAC;oBACF,IAAI,OAAO,KAAK,OAAO,EAAE,CAAC;wBACxB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;oBAC1C,CAAC;oBACD,OAAO;gBACT,CAAC;gBAED,gDAAgD;gBAChD,MAAM,OAAO,GAAG,CAAC,KAAiB,EAAE,EAAE;oBACpC,IAAI,EAAE,CAAC,UAAU,KAAK,EAAE,CAAC,IAAI;wBAAE,OAAO;oBACtC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC;gBACjC,CAAC,CAAC;gBAEF,MAAM,MAAM,GAAG,MAAM,KAAK,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;gBAEnE,IAAI,MAAM,CAAC,YAAY,EAAE,CAAC;oBACxB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC,CAAC;oBACxD,OAAO;gBACT,CAAC;gBAED,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;YAC1C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;YAClD,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;YAClB,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC;CACF"}
|
|
@@ -21,6 +21,13 @@ function getAssistantDiagnostics(message) {
|
|
|
21
21
|
const toolCalls = content.filter((item) => item?.type === "toolCall").length;
|
|
22
22
|
return { stopReason, errorMessage, hasText: text.length > 0, toolCalls };
|
|
23
23
|
}
|
|
24
|
+
function getLifecycleTrigger(channelId) {
|
|
25
|
+
if (channelId.startsWith("telegram-"))
|
|
26
|
+
return "telegram";
|
|
27
|
+
if (channelId.startsWith("slack-"))
|
|
28
|
+
return "slack";
|
|
29
|
+
return "web";
|
|
30
|
+
}
|
|
24
31
|
// ---------------------------------------------------------------------------
|
|
25
32
|
// PackAgent
|
|
26
33
|
// ---------------------------------------------------------------------------
|
|
@@ -179,13 +186,10 @@ export class PackAgent {
|
|
|
179
186
|
}
|
|
180
187
|
case "restart":
|
|
181
188
|
log("[PackAgent] Restart requested");
|
|
182
|
-
|
|
183
|
-
setTimeout(() => process.exit(0), 500);
|
|
184
|
-
return { success: true, message: "Restarting..." };
|
|
189
|
+
return this.options.lifecycleHandler.requestRestart(getLifecycleTrigger(channelId));
|
|
185
190
|
case "shutdown":
|
|
186
191
|
log("[PackAgent] Shutdown requested");
|
|
187
|
-
|
|
188
|
-
return { success: true, message: "Shutting down..." };
|
|
192
|
+
return this.options.lifecycleHandler.requestShutdown(getLifecycleTrigger(channelId));
|
|
189
193
|
default:
|
|
190
194
|
return { success: false, message: `Unknown command: ${command}` };
|
|
191
195
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,aAAa,EACb,cAAc,EACd,qBAAqB,GACtB,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../src/agent.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ import { exec } from "node:child_process";
|
|
|
7
7
|
import { PackAgent } from "./agent.js";
|
|
8
8
|
import { WebAdapter } from "./adapters/web.js";
|
|
9
9
|
import { configManager } from "./config.js";
|
|
10
|
+
import { Lifecycle } from "./lifecycle.js";
|
|
10
11
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
11
12
|
// ---------------------------------------------------------------------------
|
|
12
13
|
// Resolve root directory
|
|
@@ -32,17 +33,26 @@ const app = express();
|
|
|
32
33
|
app.use(express.json());
|
|
33
34
|
app.use(express.static(webDir));
|
|
34
35
|
const server = createServer(app);
|
|
36
|
+
const lifecycle = new Lifecycle(server);
|
|
35
37
|
// ---------------------------------------------------------------------------
|
|
36
38
|
// Create PackAgent (shared instance)
|
|
37
39
|
// ---------------------------------------------------------------------------
|
|
38
|
-
const agent = new PackAgent({
|
|
40
|
+
const agent = new PackAgent({
|
|
41
|
+
apiKey,
|
|
42
|
+
rootDir,
|
|
43
|
+
provider,
|
|
44
|
+
modelId,
|
|
45
|
+
lifecycleHandler: lifecycle,
|
|
46
|
+
});
|
|
39
47
|
// ---------------------------------------------------------------------------
|
|
40
48
|
// Start adapters
|
|
41
49
|
// ---------------------------------------------------------------------------
|
|
42
50
|
async function startAdapters() {
|
|
51
|
+
const adapters = [];
|
|
43
52
|
// Web adapter is always enabled
|
|
44
53
|
const webAdapter = new WebAdapter();
|
|
45
|
-
await webAdapter.start({ agent, server, app, rootDir });
|
|
54
|
+
await webAdapter.start({ agent, server, app, rootDir, lifecycle });
|
|
55
|
+
adapters.push(webAdapter);
|
|
46
56
|
// Telegram adapter (conditional)
|
|
47
57
|
if (dataConfig.adapters?.telegram?.token) {
|
|
48
58
|
try {
|
|
@@ -50,7 +60,8 @@ async function startAdapters() {
|
|
|
50
60
|
const telegramAdapter = new TelegramAdapter({
|
|
51
61
|
token: dataConfig.adapters.telegram.token,
|
|
52
62
|
});
|
|
53
|
-
await telegramAdapter.start({ agent, server, app, rootDir });
|
|
63
|
+
await telegramAdapter.start({ agent, server, app, rootDir, lifecycle });
|
|
64
|
+
adapters.push(telegramAdapter);
|
|
54
65
|
}
|
|
55
66
|
catch (err) {
|
|
56
67
|
console.error("[Telegram] Failed to start:", err);
|
|
@@ -69,13 +80,15 @@ async function startAdapters() {
|
|
|
69
80
|
botToken: slackConfig.botToken,
|
|
70
81
|
appToken: slackConfig.appToken,
|
|
71
82
|
});
|
|
72
|
-
await slackAdapter.start({ agent, server, app, rootDir });
|
|
83
|
+
await slackAdapter.start({ agent, server, app, rootDir, lifecycle });
|
|
84
|
+
adapters.push(slackAdapter);
|
|
73
85
|
}
|
|
74
86
|
catch (err) {
|
|
75
87
|
console.error("[Slack] Failed to start:", err);
|
|
76
88
|
}
|
|
77
89
|
}
|
|
78
90
|
}
|
|
91
|
+
lifecycle.registerAdapters(adapters);
|
|
79
92
|
}
|
|
80
93
|
// ---------------------------------------------------------------------------
|
|
81
94
|
// Listen
|
|
@@ -109,6 +122,12 @@ function tryListen(port) {
|
|
|
109
122
|
}
|
|
110
123
|
});
|
|
111
124
|
}
|
|
125
|
+
process.on("SIGINT", () => {
|
|
126
|
+
void lifecycle.requestShutdown("signal");
|
|
127
|
+
});
|
|
128
|
+
process.on("SIGTERM", () => {
|
|
129
|
+
void lifecycle.requestShutdown("signal");
|
|
130
|
+
});
|
|
112
131
|
// Start adapters, then listen
|
|
113
132
|
startAdapters()
|
|
114
133
|
.then(() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAC9B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE1C,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export const SHUTDOWN_EXIT_CODE = 64;
|
|
2
|
+
export const RESTART_EXIT_CODE = 75;
|
|
3
|
+
const STOP_TIMEOUT_MS = 3_000;
|
|
4
|
+
function detectProcessManager() {
|
|
5
|
+
return process.env.SKILLPACK_PROCESS_MANAGER === "pm2" ? "pm2" : "none";
|
|
6
|
+
}
|
|
7
|
+
export class Lifecycle {
|
|
8
|
+
server;
|
|
9
|
+
exitFn;
|
|
10
|
+
processManager;
|
|
11
|
+
adapters = [];
|
|
12
|
+
stopReason = null;
|
|
13
|
+
constructor(server, exitFn = (code) => process.exit(code)) {
|
|
14
|
+
this.server = server;
|
|
15
|
+
this.exitFn = exitFn;
|
|
16
|
+
this.processManager = detectProcessManager();
|
|
17
|
+
}
|
|
18
|
+
registerAdapters(adapters) {
|
|
19
|
+
this.adapters = adapters;
|
|
20
|
+
}
|
|
21
|
+
getRuntimeControl() {
|
|
22
|
+
return {
|
|
23
|
+
canManagedRestart: this.processManager === "pm2",
|
|
24
|
+
processManager: this.processManager,
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
async requestRestart(trigger) {
|
|
28
|
+
return this.requestStop("restart", trigger);
|
|
29
|
+
}
|
|
30
|
+
async requestShutdown(trigger) {
|
|
31
|
+
return this.requestStop("shutdown", trigger);
|
|
32
|
+
}
|
|
33
|
+
async requestStop(reason, trigger) {
|
|
34
|
+
if (this.stopReason) {
|
|
35
|
+
const message = this.stopReason === "restart"
|
|
36
|
+
? "Restart already in progress."
|
|
37
|
+
: "Shutdown already in progress.";
|
|
38
|
+
return { success: true, message };
|
|
39
|
+
}
|
|
40
|
+
this.stopReason = reason;
|
|
41
|
+
console.log(`[Lifecycle] ${reason} requested via ${trigger}`);
|
|
42
|
+
setTimeout(() => {
|
|
43
|
+
void this.gracefulStopAndExit(reason);
|
|
44
|
+
}, 50);
|
|
45
|
+
return {
|
|
46
|
+
success: true,
|
|
47
|
+
message: reason === "restart" ? "Restarting..." : "Shutting down...",
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
async gracefulStopAndExit(reason) {
|
|
51
|
+
try {
|
|
52
|
+
await Promise.race([
|
|
53
|
+
this.gracefulStop(),
|
|
54
|
+
new Promise((resolve) => {
|
|
55
|
+
setTimeout(() => {
|
|
56
|
+
console.warn("[Lifecycle] Graceful stop timed out, forcing exit.");
|
|
57
|
+
resolve();
|
|
58
|
+
}, STOP_TIMEOUT_MS);
|
|
59
|
+
}),
|
|
60
|
+
]);
|
|
61
|
+
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
console.error("[Lifecycle] Error during graceful stop:", err);
|
|
64
|
+
}
|
|
65
|
+
const exitCode = reason === "restart" ? RESTART_EXIT_CODE : SHUTDOWN_EXIT_CODE;
|
|
66
|
+
this.exitFn(exitCode);
|
|
67
|
+
}
|
|
68
|
+
async gracefulStop() {
|
|
69
|
+
for (const adapter of [...this.adapters].reverse()) {
|
|
70
|
+
try {
|
|
71
|
+
await adapter.stop();
|
|
72
|
+
}
|
|
73
|
+
catch (err) {
|
|
74
|
+
console.error(`[Lifecycle] Failed to stop ${adapter.name}:`, err);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
if (!this.server.listening) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
await new Promise((resolve) => {
|
|
81
|
+
this.server.close(() => resolve());
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
//# sourceMappingURL=lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../src/lifecycle.ts"],"names":[],"mappings":"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"}
|
package/runtime/web/index.html
CHANGED
|
@@ -104,6 +104,7 @@
|
|
|
104
104
|
</div>
|
|
105
105
|
</div>
|
|
106
106
|
<div class="settings-modal-footer">
|
|
107
|
+
<button id="restart-service-btn" class="secondary-btn" hidden>Restart Service</button>
|
|
107
108
|
<button id="save-settings-btn" class="primary-btn">Save Settings</button>
|
|
108
109
|
</div>
|
|
109
110
|
</dialog>
|
|
@@ -112,4 +113,4 @@
|
|
|
112
113
|
<script type="module" src="js/main.js"></script>
|
|
113
114
|
</body>
|
|
114
115
|
|
|
115
|
-
</html>
|
|
116
|
+
</html>
|
package/runtime/web/js/api.js
CHANGED
|
@@ -11,3 +11,15 @@ export async function saveConfigData(updates) {
|
|
|
11
11
|
}
|
|
12
12
|
return await res.json();
|
|
13
13
|
}
|
|
14
|
+
|
|
15
|
+
export async function restartRuntime() {
|
|
16
|
+
const res = await fetch(state.API_BASE + "/api/runtime/restart", {
|
|
17
|
+
method: "POST",
|
|
18
|
+
headers: { "Content-Type": "application/json" },
|
|
19
|
+
});
|
|
20
|
+
const payload = await res.json();
|
|
21
|
+
if (!res.ok) {
|
|
22
|
+
throw new Error(payload.message || "Restart Failed");
|
|
23
|
+
}
|
|
24
|
+
return payload;
|
|
25
|
+
}
|
package/runtime/web/js/config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { state } from "./config.js";
|
|
2
|
-
import { saveConfigData } from "./api.js";
|
|
2
|
+
import { restartRuntime, saveConfigData } from "./api.js";
|
|
3
3
|
|
|
4
4
|
// DOM Elements
|
|
5
5
|
let dialog;
|
|
@@ -12,6 +12,7 @@ let telegramTokenInput;
|
|
|
12
12
|
let slackBotTokenInput;
|
|
13
13
|
let slackAppTokenInput;
|
|
14
14
|
let keyStatus;
|
|
15
|
+
let restartBtn;
|
|
15
16
|
|
|
16
17
|
export function initSettings() {
|
|
17
18
|
dialog = document.getElementById("settings-dialog");
|
|
@@ -25,6 +26,7 @@ export function initSettings() {
|
|
|
25
26
|
slackBotTokenInput = document.getElementById("slack-bot-token-input");
|
|
26
27
|
slackAppTokenInput = document.getElementById("slack-app-token-input");
|
|
27
28
|
keyStatus = document.getElementById("key-status");
|
|
29
|
+
restartBtn = document.getElementById("restart-service-btn");
|
|
28
30
|
|
|
29
31
|
if (!dialog) return;
|
|
30
32
|
|
|
@@ -47,6 +49,9 @@ export function initSettings() {
|
|
|
47
49
|
if (saveBtn) {
|
|
48
50
|
saveBtn.addEventListener("click", handleSave);
|
|
49
51
|
}
|
|
52
|
+
if (restartBtn) {
|
|
53
|
+
restartBtn.addEventListener("click", handleRestart);
|
|
54
|
+
}
|
|
50
55
|
|
|
51
56
|
// Placeholder logic
|
|
52
57
|
if (providerSelect) {
|
|
@@ -65,11 +70,20 @@ function populateForm() {
|
|
|
65
70
|
const config = state.config;
|
|
66
71
|
if (!config) return;
|
|
67
72
|
|
|
68
|
-
if (
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
if (state.restartRequired) {
|
|
74
|
+
setStatus(
|
|
75
|
+
config.runtimeControl?.canManagedRestart
|
|
76
|
+
? "Settings saved. Restart service to apply changes."
|
|
77
|
+
: "Settings saved. Restart the service manually to apply changes.",
|
|
78
|
+
"warning",
|
|
79
|
+
);
|
|
80
|
+
updateRestartButton(true);
|
|
81
|
+
} else if (config.hasApiKey) {
|
|
82
|
+
setStatus("API key configured", "success");
|
|
83
|
+
updateRestartButton(false);
|
|
71
84
|
} else {
|
|
72
|
-
|
|
85
|
+
setStatus("", "");
|
|
86
|
+
updateRestartButton(false);
|
|
73
87
|
}
|
|
74
88
|
|
|
75
89
|
if (config.provider) {
|
|
@@ -116,17 +130,61 @@ async function handleSave() {
|
|
|
116
130
|
|
|
117
131
|
try {
|
|
118
132
|
const res = await saveConfigData(updates);
|
|
119
|
-
keyStatus.textContent = "Settings saved";
|
|
120
|
-
keyStatus.className = "status-text success";
|
|
121
133
|
apiKeyInput.value = ""; // clear after save
|
|
122
134
|
|
|
123
135
|
// Update local config
|
|
124
136
|
state.config.provider = res.provider;
|
|
125
137
|
state.config.adapters = res.adapters;
|
|
138
|
+
state.config.runtimeControl = res.runtimeControl;
|
|
126
139
|
if (key) state.config.hasApiKey = true;
|
|
140
|
+
state.restartRequired = !!res.requiresRestart;
|
|
141
|
+
|
|
142
|
+
if (res.requiresRestart) {
|
|
143
|
+
setStatus(
|
|
144
|
+
res.runtimeControl.canManagedRestart
|
|
145
|
+
? "Settings saved. Restart service to apply changes."
|
|
146
|
+
: "Settings saved. Restart the service manually to apply changes.",
|
|
147
|
+
"warning",
|
|
148
|
+
);
|
|
149
|
+
updateRestartButton(res.runtimeControl.canManagedRestart);
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
setStatus("Settings saved", "success");
|
|
154
|
+
updateRestartButton(false);
|
|
155
|
+
|
|
156
|
+
} catch (err) {
|
|
157
|
+
setStatus("Save failed: " + err.message, "error");
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
async function handleRestart() {
|
|
162
|
+
if (!restartBtn) return;
|
|
127
163
|
|
|
164
|
+
restartBtn.disabled = true;
|
|
165
|
+
if (saveBtn) saveBtn.disabled = true;
|
|
166
|
+
setStatus("Restarting service...", "warning");
|
|
167
|
+
|
|
168
|
+
try {
|
|
169
|
+
await restartRuntime();
|
|
170
|
+
setTimeout(() => {
|
|
171
|
+
window.location.reload();
|
|
172
|
+
}, 3000);
|
|
128
173
|
} catch (err) {
|
|
129
|
-
|
|
130
|
-
|
|
174
|
+
if (saveBtn) saveBtn.disabled = false;
|
|
175
|
+
restartBtn.disabled = false;
|
|
176
|
+
setStatus("Restart failed: " + err.message, "error");
|
|
131
177
|
}
|
|
132
178
|
}
|
|
179
|
+
|
|
180
|
+
function updateRestartButton(show) {
|
|
181
|
+
if (!restartBtn) return;
|
|
182
|
+
restartBtn.hidden = !show;
|
|
183
|
+
restartBtn.disabled = false;
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
function setStatus(message, status) {
|
|
187
|
+
if (!keyStatus) return;
|
|
188
|
+
keyStatus.textContent = message;
|
|
189
|
+
keyStatus.className = status ? `status-text ${status}` : "status-text";
|
|
190
|
+
}
|
package/runtime/web/styles.css
CHANGED
|
@@ -198,6 +198,9 @@ body {
|
|
|
198
198
|
.status-text.success {
|
|
199
199
|
color: var(--success);
|
|
200
200
|
}
|
|
201
|
+
.status-text.warning {
|
|
202
|
+
color: var(--accent);
|
|
203
|
+
}
|
|
201
204
|
.status-text.error {
|
|
202
205
|
color: var(--error);
|
|
203
206
|
}
|
|
@@ -922,6 +925,22 @@ body {
|
|
|
922
925
|
display: flex;
|
|
923
926
|
justify-content: flex-end;
|
|
924
927
|
align-items: center;
|
|
928
|
+
gap: 12px;
|
|
929
|
+
}
|
|
930
|
+
.secondary-btn {
|
|
931
|
+
padding: 10px 20px;
|
|
932
|
+
background: transparent;
|
|
933
|
+
color: var(--text-primary);
|
|
934
|
+
border: 1px solid var(--border-color);
|
|
935
|
+
border-radius: var(--radius-sm);
|
|
936
|
+
font-weight: 500;
|
|
937
|
+
font-size: 14px;
|
|
938
|
+
cursor: pointer;
|
|
939
|
+
transition: all 0.2s ease;
|
|
940
|
+
}
|
|
941
|
+
.secondary-btn:hover {
|
|
942
|
+
border-color: var(--accent);
|
|
943
|
+
color: var(--accent);
|
|
925
944
|
}
|
|
926
945
|
.primary-btn {
|
|
927
946
|
padding: 10px 20px;
|
|
@@ -942,4 +961,10 @@ body {
|
|
|
942
961
|
.primary-btn:active {
|
|
943
962
|
transform: translateY(0);
|
|
944
963
|
}
|
|
945
|
-
|
|
964
|
+
.primary-btn:disabled,
|
|
965
|
+
.secondary-btn:disabled {
|
|
966
|
+
opacity: 0.6;
|
|
967
|
+
cursor: not-allowed;
|
|
968
|
+
transform: none;
|
|
969
|
+
box-shadow: none;
|
|
970
|
+
}
|