@poolzin/pool-bot 2026.3.17 → 2026.3.19
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/CHANGELOG.md +63 -0
- package/dist/agents/tools/web-fetch.js +1 -1
- package/dist/build-info.json +3 -3
- package/dist/commands/skills-openclaw.command.js +123 -0
- package/dist/config/paths.js +7 -0
- package/dist/infra/net/fetch-guard.js +191 -146
- package/dist/media/fetch.js +83 -112
- package/dist/media/inbound-path-policy.js +90 -97
- package/dist/media/read-response-with-limit.js +49 -26
- package/dist/media-understanding/attachments.js +1 -1
- package/dist/plugin-sdk/audio.js +7 -0
- package/dist/plugin-sdk/bluebubbles.js +7 -0
- package/dist/plugin-sdk/browser.js +7 -0
- package/dist/plugin-sdk/canvas.js +7 -0
- package/dist/plugin-sdk/cron.js +7 -0
- package/dist/plugin-sdk/discord-actions.js +6 -0
- package/dist/plugin-sdk/discord.js +7 -0
- package/dist/plugin-sdk/image.js +7 -0
- package/dist/plugin-sdk/imessage.js +6 -0
- package/dist/plugin-sdk/keyed-async-queue.js +35 -0
- package/dist/plugin-sdk/media.js +8 -0
- package/dist/plugin-sdk/memory.js +7 -0
- package/dist/plugin-sdk/pdf.js +7 -0
- package/dist/plugin-sdk/sessions.js +7 -0
- package/dist/plugin-sdk/signal.js +6 -0
- package/dist/plugin-sdk/slack-actions.js +7 -0
- package/dist/plugin-sdk/slack.js +7 -0
- package/dist/plugin-sdk/telegram-actions.js +6 -0
- package/dist/plugin-sdk/telegram.js +6 -0
- package/dist/plugin-sdk/test-utils.js +110 -0
- package/dist/plugin-sdk/tts.js +7 -0
- package/dist/plugin-sdk/whatsapp.js +6 -0
- package/dist/providers/github-copilot-auth.js +53 -76
- package/dist/providers/github-copilot-models.js +63 -35
- package/dist/providers/github-copilot-token.js +46 -89
- package/dist/security/audit-findings.js +165 -0
- package/dist/security/audit.js +141 -572
- package/dist/skills/openclaw-skill-loader.js +191 -0
- package/dist/slack/monitor/media.js +2 -1
- package/docs/improvements/OPENCLAW-IMPLEMENTATION.md +45 -0
- package/docs/skills/openclaw-integration.md +295 -0
- package/docs/testing/TEST-PLAN-2026-03-13.md +338 -0
- package/extensions/acpx/package.json +19 -0
- package/extensions/acpx/poolbot.plugin.json +9 -0
- package/extensions/acpx/src/index.ts +34 -0
- package/extensions/bluebubbles/src/runtime.ts +1 -0
- package/extensions/dexter/poolbot.plugin.json +10 -6
- package/extensions/diffs/package.json +15 -0
- package/extensions/diffs/poolbot.plugin.json +10 -0
- package/extensions/diffs/src/index.ts +106 -0
- package/extensions/discord/src/runtime.ts +1 -0
- package/extensions/feishu/src/runtime.ts +1 -0
- package/extensions/github-copilot/package.json +28 -0
- package/extensions/github-copilot/poolbot.plugin.json +33 -0
- package/extensions/github-copilot/src/index.ts +126 -0
- package/extensions/github-copilot/tsconfig.json +10 -0
- package/extensions/googlechat/src/runtime.ts +1 -0
- package/extensions/hackingtool/poolbot.plugin.json +33 -25
- package/extensions/hexstrike-ai/poolbot.plugin.json +16 -8
- package/extensions/imessage/src/runtime.ts +1 -0
- package/extensions/irc/src/runtime.ts +1 -0
- package/extensions/line/src/runtime.ts +1 -0
- package/extensions/matrix/src/runtime.ts +1 -0
- package/extensions/mattermost/src/mattermost/monitor-helpers.ts +10 -1
- package/extensions/mattermost/src/runtime.ts +6 -3
- package/extensions/msteams/src/runtime.ts +1 -0
- package/extensions/nextcloud-talk/src/runtime.ts +1 -0
- package/extensions/nostr/src/runtime.ts +5 -2
- package/extensions/ollama/package.json +20 -0
- package/extensions/ollama/poolbot.plugin.json +18 -0
- package/extensions/ollama/src/index.ts +95 -0
- package/extensions/sglang/package.json +18 -0
- package/extensions/sglang/poolbot.plugin.json +17 -0
- package/extensions/sglang/src/index.ts +62 -0
- package/extensions/signal/src/runtime.ts +1 -0
- package/extensions/slack/src/runtime.ts +1 -0
- package/extensions/telegram/src/runtime.ts +1 -0
- package/extensions/test-utils/package.json +17 -0
- package/extensions/test-utils/poolbot.plugin.json +16 -0
- package/extensions/test-utils/src/index.ts +220 -0
- package/extensions/tlon/src/runtime.ts +1 -0
- package/extensions/twitch/src/runtime.ts +1 -0
- package/extensions/vllm/package.json +19 -0
- package/extensions/vllm/poolbot.plugin.json +17 -0
- package/extensions/vllm/src/index.ts +90 -0
- package/extensions/whatsapp/src/runtime.ts +1 -0
- package/extensions/zalo/src/runtime.ts +1 -0
- package/extensions/zalouser/src/runtime.ts +1 -0
- package/package.json +77 -3
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GitHub Copilot Provider Extension
|
|
3
|
+
*
|
|
4
|
+
* Provides OAuth authentication and model access via GitHub Copilot
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
authenticateGitHubCopilot,
|
|
9
|
+
saveGitHubCopilotAuth,
|
|
10
|
+
} from "../../../src/providers/github-copilot-auth.js";
|
|
11
|
+
import {
|
|
12
|
+
getGitHubCopilotToken,
|
|
13
|
+
validateGitHubCopilotToken,
|
|
14
|
+
} from "../../../src/providers/github-copilot-token.js";
|
|
15
|
+
import {
|
|
16
|
+
listGitHubCopilotModels,
|
|
17
|
+
getGitHubCopilotModel,
|
|
18
|
+
} from "../../../src/providers/github-copilot-models.js";
|
|
19
|
+
|
|
20
|
+
export default async function createPlugin(ctx: any): Promise<any> {
|
|
21
|
+
const config = ctx.config as {
|
|
22
|
+
autoRefresh?: boolean;
|
|
23
|
+
refreshIntervalHours?: number;
|
|
24
|
+
defaultModel?: string;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
ctx.logger.info("GitHub Copilot Provider initialized");
|
|
28
|
+
|
|
29
|
+
// Register CLI commands
|
|
30
|
+
ctx.cli
|
|
31
|
+
.command("copilot.auth")
|
|
32
|
+
.description("Authenticate with GitHub Copilot using OAuth device flow")
|
|
33
|
+
.option("-p, --profile <name>", "Auth profile name (default: github-copilot)")
|
|
34
|
+
.action(async (options?: { profile?: string }) => {
|
|
35
|
+
const profileName = options?.profile ?? "github-copilot";
|
|
36
|
+
|
|
37
|
+
console.log("🔐 Authenticating with GitHub Copilot...\n");
|
|
38
|
+
|
|
39
|
+
const result = await authenticateGitHubCopilot();
|
|
40
|
+
|
|
41
|
+
if (result.success && result.accessToken) {
|
|
42
|
+
await saveGitHubCopilotAuth({
|
|
43
|
+
accessToken: result.accessToken,
|
|
44
|
+
profileName,
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
console.log("\n✅ Authentication successful!");
|
|
48
|
+
console.log(` Profile: ${profileName}`);
|
|
49
|
+
|
|
50
|
+
// Validate token
|
|
51
|
+
const validation = await validateGitHubCopilotToken(result.accessToken);
|
|
52
|
+
console.log(` Token status: ${validation.status}`);
|
|
53
|
+
if (validation.scopes) {
|
|
54
|
+
console.log(` Scopes: ${validation.scopes.join(", ")}`);
|
|
55
|
+
}
|
|
56
|
+
} else {
|
|
57
|
+
console.error(`\n❌ Authentication failed: ${result.error}`);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
ctx.cli
|
|
63
|
+
.command("copilot.status")
|
|
64
|
+
.description("Check GitHub Copilot authentication status")
|
|
65
|
+
.option("-p, --profile <name>", "Auth profile name (default: github-copilot)")
|
|
66
|
+
.action(async (options?: { profile?: string }) => {
|
|
67
|
+
const profileName = options?.profile ?? "github-copilot";
|
|
68
|
+
|
|
69
|
+
const token = await getGitHubCopilotToken(profileName);
|
|
70
|
+
|
|
71
|
+
if (!token) {
|
|
72
|
+
console.log("❌ Not authenticated");
|
|
73
|
+
console.log(" Run 'poolbot copilot.auth' to authenticate");
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
const validation = await validateGitHubCopilotToken(token);
|
|
78
|
+
|
|
79
|
+
console.log("✅ GitHub Copilot Status");
|
|
80
|
+
console.log(` Profile: ${profileName}`);
|
|
81
|
+
console.log(` Token status: ${validation.status}`);
|
|
82
|
+
if (validation.scopes) {
|
|
83
|
+
console.log(` Scopes: ${validation.scopes.join(", ")}`);
|
|
84
|
+
}
|
|
85
|
+
if (validation.expiresAt) {
|
|
86
|
+
console.log(` Expires: ${new Date(validation.expiresAt).toISOString()}`);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
ctx.cli
|
|
91
|
+
.command("copilot.models")
|
|
92
|
+
.description("List available GitHub Copilot models")
|
|
93
|
+
.action(async () => {
|
|
94
|
+
const models = listGitHubCopilotModels();
|
|
95
|
+
|
|
96
|
+
console.log("📦 GitHub Copilot Models\n");
|
|
97
|
+
|
|
98
|
+
for (const model of models) {
|
|
99
|
+
console.log(`🤖 ${model.name} (${model.id})`);
|
|
100
|
+
console.log(` ${model.description}`);
|
|
101
|
+
console.log(` Context: ${(model.contextWindow / 1000).toFixed(0)}K tokens`);
|
|
102
|
+
console.log(` Vision: ${model.supportsVision ? "✅" : "❌"}`);
|
|
103
|
+
console.log(` Functions: ${model.supportsFunctionCall ? "✅" : "❌"}`);
|
|
104
|
+
console.log();
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
// On init: check if auto-refresh is enabled
|
|
109
|
+
if (config.autoRefresh !== false) {
|
|
110
|
+
const needsRefresh = await import("../../../src/providers/github-copilot-token.js")
|
|
111
|
+
.then((m) => m.needsTokenRefresh());
|
|
112
|
+
|
|
113
|
+
if (needsRefresh) {
|
|
114
|
+
ctx.logger.warn("GitHub Copilot token needs refresh");
|
|
115
|
+
ctx.logger.warn("Run 'poolbot copilot.auth' to re-authenticate");
|
|
116
|
+
} else {
|
|
117
|
+
ctx.logger.info("GitHub Copilot token is valid");
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
return {
|
|
122
|
+
name: "github-copilot",
|
|
123
|
+
version: "2026.3.17",
|
|
124
|
+
commands: ["copilot.auth", "copilot.status", "copilot.models"],
|
|
125
|
+
};
|
|
126
|
+
}
|
|
@@ -21,31 +21,39 @@
|
|
|
21
21
|
"pentest.stop"
|
|
22
22
|
],
|
|
23
23
|
"hooks": ["onInit", "onShutdown"],
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
24
|
+
"configSchema": {
|
|
25
|
+
"type": "object",
|
|
26
|
+
"properties": {
|
|
27
|
+
"port": { "type": "number", "default": 8889 },
|
|
28
|
+
"host": { "type": "string", "default": "127.0.0.1" },
|
|
29
|
+
"autoStart": { "type": "boolean", "default": true },
|
|
30
|
+
"pythonPath": { "type": "string", "default": "python3" },
|
|
31
|
+
"toolCategories": {
|
|
32
|
+
"type": "array",
|
|
33
|
+
"items": { "type": "string" },
|
|
34
|
+
"default": [
|
|
35
|
+
"anonymity",
|
|
36
|
+
"information_gathering",
|
|
37
|
+
"wordlist",
|
|
38
|
+
"wireless",
|
|
39
|
+
"sql_injection",
|
|
40
|
+
"phishing",
|
|
41
|
+
"web_attack",
|
|
42
|
+
"post_exploitation",
|
|
43
|
+
"forensic",
|
|
44
|
+
"payload",
|
|
45
|
+
"exploit",
|
|
46
|
+
"reverse_engineering",
|
|
47
|
+
"ddos",
|
|
48
|
+
"rat",
|
|
49
|
+
"xss",
|
|
50
|
+
"steganography"
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
"maxConcurrentScans": { "type": "number", "default": 5 },
|
|
54
|
+
"scanTimeout": { "type": "number", "default": 600 }
|
|
55
|
+
},
|
|
56
|
+
"additionalProperties": false
|
|
49
57
|
},
|
|
50
58
|
"permissions": [
|
|
51
59
|
"gateway.rpc",
|
|
@@ -14,14 +14,22 @@
|
|
|
14
14
|
"security.stop"
|
|
15
15
|
],
|
|
16
16
|
"hooks": ["onInit", "onShutdown"],
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
17
|
+
"configSchema": {
|
|
18
|
+
"type": "object",
|
|
19
|
+
"properties": {
|
|
20
|
+
"port": { "type": "number", "default": 8888 },
|
|
21
|
+
"host": { "type": "string", "default": "127.0.0.1" },
|
|
22
|
+
"autoStart": { "type": "boolean", "default": true },
|
|
23
|
+
"pythonPath": { "type": "string", "default": "python3" },
|
|
24
|
+
"scanners": {
|
|
25
|
+
"type": "array",
|
|
26
|
+
"items": { "type": "string" },
|
|
27
|
+
"default": ["nmap", "nuclei", "sqlmap", "gobuster", "wpscan", "nikto", "dirb"]
|
|
28
|
+
},
|
|
29
|
+
"maxConcurrentScans": { "type": "number", "default": 3 },
|
|
30
|
+
"scanTimeout": { "type": "number", "default": 3600 }
|
|
31
|
+
},
|
|
32
|
+
"additionalProperties": false
|
|
25
33
|
},
|
|
26
34
|
"permissions": [
|
|
27
35
|
"gateway.rpc",
|
|
@@ -114,7 +114,16 @@ function normalizeAgentId(value: string | undefined | null): string {
|
|
|
114
114
|
);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
// AgentEntry interface - explicit definition to avoid type resolution issues
|
|
118
|
+
interface AgentEntry {
|
|
119
|
+
id: string;
|
|
120
|
+
default?: boolean;
|
|
121
|
+
name?: string;
|
|
122
|
+
identity?: {
|
|
123
|
+
name?: string;
|
|
124
|
+
avatar?: string;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
118
127
|
|
|
119
128
|
function listAgents(cfg: PoolbotConfig): AgentEntry[] {
|
|
120
129
|
const list = cfg.agents?.list;
|
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
import type { PluginRuntime } from "poolbot/plugin-sdk";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// MattermostPluginRuntime wrapper interface to avoid lint resolution issues
|
|
4
|
+
interface MattermostPluginRuntime extends PluginRuntime {}
|
|
5
|
+
|
|
6
|
+
let runtime: MattermostPluginRuntime | null = null;
|
|
4
7
|
|
|
5
8
|
export function setMattermostRuntime(next: PluginRuntime) {
|
|
6
|
-
runtime = next;
|
|
9
|
+
runtime = next as MattermostPluginRuntime;
|
|
7
10
|
}
|
|
8
11
|
|
|
9
12
|
export function getMattermostRuntime(): PluginRuntime {
|
|
10
13
|
if (!runtime) {
|
|
11
14
|
throw new Error("Mattermost runtime not initialized");
|
|
12
15
|
}
|
|
13
|
-
return runtime;
|
|
16
|
+
return runtime as PluginRuntime;
|
|
14
17
|
}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import type { PluginRuntime } from "poolbot/plugin-sdk";
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
// NostrPluginRuntime wrapper interface to avoid lint resolution issues
|
|
4
|
+
interface NostrPluginRuntime extends PluginRuntime {}
|
|
5
|
+
|
|
6
|
+
let runtime: NostrPluginRuntime | null = null;
|
|
4
7
|
|
|
5
8
|
export function setNostrRuntime(next: PluginRuntime): void {
|
|
6
9
|
runtime = next;
|
|
@@ -10,5 +13,5 @@ export function getNostrRuntime(): PluginRuntime {
|
|
|
10
13
|
if (!runtime) {
|
|
11
14
|
throw new Error("Nostr runtime not initialized");
|
|
12
15
|
}
|
|
13
|
-
return runtime;
|
|
16
|
+
return runtime as PluginRuntime;
|
|
14
17
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@poolbot/ollama",
|
|
3
|
+
"version": "2026.3.17",
|
|
4
|
+
"description": "Ollama provider for Pool Bot - local LLM inference",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"poolbot": "workspace:*",
|
|
9
|
+
"ollama": "^0.6.3"
|
|
10
|
+
},
|
|
11
|
+
"poolbot": {
|
|
12
|
+
"extensions": ["./src/index.ts"],
|
|
13
|
+
"provider": {
|
|
14
|
+
"id": "ollama",
|
|
15
|
+
"name": "Ollama",
|
|
16
|
+
"description": "Local LLM inference with Ollama",
|
|
17
|
+
"models": ["llama3", "mistral", "codellama", "phi", "gemma"]
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "ollama",
|
|
3
|
+
"name": "Ollama Provider",
|
|
4
|
+
"version": "2026.3.17",
|
|
5
|
+
"description": "Local LLM inference with Ollama",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"capabilities": ["provider", "local-llm"],
|
|
8
|
+
"commands": ["ollama.status", "ollama.models", "ollama.pull"],
|
|
9
|
+
"configSchema": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"host": { "type": "string", "default": "http://127.0.0.1" },
|
|
13
|
+
"port": { "type": "number", "default": 11434 },
|
|
14
|
+
"defaultModel": { "type": "string", "default": "llama3" }
|
|
15
|
+
},
|
|
16
|
+
"additionalProperties": false
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pool Bot Ollama Provider Extension
|
|
3
|
+
*
|
|
4
|
+
* Provides local LLM inference via Ollama
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export default async function createPlugin(ctx: any): Promise<any> {
|
|
8
|
+
const config = ctx.config as {
|
|
9
|
+
host?: string;
|
|
10
|
+
port?: number;
|
|
11
|
+
defaultModel?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const host = config.host ?? "http://127.0.0.1";
|
|
15
|
+
const port = config.port ?? 11434;
|
|
16
|
+
const baseUrl = `${host}:${port}`;
|
|
17
|
+
|
|
18
|
+
ctx.logger.info(`Ollama Provider initialized (${baseUrl})`);
|
|
19
|
+
|
|
20
|
+
ctx.cli
|
|
21
|
+
.command("ollama.status")
|
|
22
|
+
.description("Check Ollama server status")
|
|
23
|
+
.action(async () => {
|
|
24
|
+
try {
|
|
25
|
+
const res = await fetch(`${baseUrl}/api/tags`);
|
|
26
|
+
if (res.ok) {
|
|
27
|
+
const data = await res.json() as { models: Array<{ name: string }> };
|
|
28
|
+
console.log("✅ Ollama Status");
|
|
29
|
+
console.log(` URL: ${baseUrl}`);
|
|
30
|
+
console.log(` Models: ${data.models.length}`);
|
|
31
|
+
data.models.slice(0, 5).forEach((m) => console.log(` - ${m.name}`));
|
|
32
|
+
} else {
|
|
33
|
+
console.log("❌ Ollama not running");
|
|
34
|
+
}
|
|
35
|
+
} catch (error) {
|
|
36
|
+
console.log("❌ Ollama connection failed");
|
|
37
|
+
console.log(` Error: ${error instanceof Error ? error.message : error}`);
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
ctx.cli
|
|
42
|
+
.command("ollama.models")
|
|
43
|
+
.description("List available Ollama models")
|
|
44
|
+
.action(async () => {
|
|
45
|
+
try {
|
|
46
|
+
const res = await fetch(`${baseUrl}/api/tags`);
|
|
47
|
+
if (!res.ok) throw new Error("Ollama not running");
|
|
48
|
+
|
|
49
|
+
const data = await res.json() as { models: Array<{ name: string; size: number }> };
|
|
50
|
+
console.log("📦 Ollama Models\n");
|
|
51
|
+
|
|
52
|
+
for (const model of data.models) {
|
|
53
|
+
const sizeGB = (model.size / 1e9).toFixed(2);
|
|
54
|
+
console.log(`🤖 ${model.name}`);
|
|
55
|
+
console.log(` Size: ${sizeGB} GB`);
|
|
56
|
+
}
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error("Failed to list models:", error instanceof Error ? error.message : error);
|
|
59
|
+
process.exit(1);
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
ctx.cli
|
|
64
|
+
.command("ollama.pull")
|
|
65
|
+
.description("Pull an Ollama model")
|
|
66
|
+
.argument("<model>", "Model name (e.g., llama3, mistral)")
|
|
67
|
+
.action(async (modelName: string) => {
|
|
68
|
+
console.log(`📥 Pulling ${modelName}...`);
|
|
69
|
+
|
|
70
|
+
try {
|
|
71
|
+
const res = await fetch(`${baseUrl}/api/pull`, {
|
|
72
|
+
method: "POST",
|
|
73
|
+
headers: { "Content-Type": "application/json" },
|
|
74
|
+
body: JSON.stringify({ name: modelName }),
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
if (res.ok) {
|
|
78
|
+
console.log(`✅ Model ${modelName} pulled successfully`);
|
|
79
|
+
} else {
|
|
80
|
+
const error = await res.text();
|
|
81
|
+
console.error(`❌ Failed to pull: ${error}`);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
} catch (error) {
|
|
85
|
+
console.error("Failed to pull model:", error instanceof Error ? error.message : error);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
return {
|
|
91
|
+
name: "ollama",
|
|
92
|
+
version: "2026.3.17",
|
|
93
|
+
commands: ["ollama.status", "ollama.models", "ollama.pull"],
|
|
94
|
+
};
|
|
95
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@poolbot/sglang",
|
|
3
|
+
"version": "2026.3.17",
|
|
4
|
+
"description": "SGLang provider for Pool Bot - optimized LLM inference",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"poolbot": "workspace:*"
|
|
9
|
+
},
|
|
10
|
+
"poolbot": {
|
|
11
|
+
"extensions": ["./src/index.ts"],
|
|
12
|
+
"provider": {
|
|
13
|
+
"id": "sglang",
|
|
14
|
+
"name": "SGLang",
|
|
15
|
+
"description": "SGLang runtime for optimized LLM inference"
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "sglang",
|
|
3
|
+
"name": "SGLang Provider",
|
|
4
|
+
"version": "2026.3.17",
|
|
5
|
+
"description": "SGLang runtime for optimized LLM inference",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"capabilities": ["provider", "optimized-inference"],
|
|
8
|
+
"commands": ["sglang.status", "sglang.models"],
|
|
9
|
+
"configSchema": {
|
|
10
|
+
"type": "object",
|
|
11
|
+
"properties": {
|
|
12
|
+
"host": { "type": "string", "default": "http://127.0.0.1" },
|
|
13
|
+
"port": { "type": "number", "default": 30000 }
|
|
14
|
+
},
|
|
15
|
+
"additionalProperties": false
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pool Bot SGLang Provider Extension
|
|
3
|
+
*
|
|
4
|
+
* Provides SGLang runtime for optimized LLM inference
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
export default async function createPlugin(ctx: any): Promise<any> {
|
|
8
|
+
const config = ctx.config as {
|
|
9
|
+
host?: string;
|
|
10
|
+
port?: number;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const host = config.host ?? "http://127.0.0.1";
|
|
14
|
+
const port = config.port ?? 30000;
|
|
15
|
+
const baseUrl = `${host}:${port}`;
|
|
16
|
+
|
|
17
|
+
ctx.logger.info(`SGLang Provider initialized (${baseUrl})`);
|
|
18
|
+
|
|
19
|
+
ctx.cli
|
|
20
|
+
.command("sglang.status")
|
|
21
|
+
.description("Check SGLang server status")
|
|
22
|
+
.action(async () => {
|
|
23
|
+
try {
|
|
24
|
+
const res = await fetch(`${baseUrl}/health`);
|
|
25
|
+
if (res.ok) {
|
|
26
|
+
console.log("✅ SGLang Status");
|
|
27
|
+
console.log(` URL: ${baseUrl}`);
|
|
28
|
+
console.log(` Status: Running`);
|
|
29
|
+
} else {
|
|
30
|
+
console.log("❌ SGLang not running");
|
|
31
|
+
}
|
|
32
|
+
} catch (error) {
|
|
33
|
+
console.log("❌ SGLang connection failed");
|
|
34
|
+
console.log(` Error: ${error instanceof Error ? error.message : error}`);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
ctx.cli
|
|
39
|
+
.command("sglang.models")
|
|
40
|
+
.description("List available SGLang models")
|
|
41
|
+
.action(async () => {
|
|
42
|
+
try {
|
|
43
|
+
const res = await fetch(`${baseUrl}/v1/models`);
|
|
44
|
+
if (!res.ok) throw new Error("SGLang not running");
|
|
45
|
+
|
|
46
|
+
const data = await res.json() as { data: Array<{ id: string }> };
|
|
47
|
+
console.log("📦 SGLang Models\n");
|
|
48
|
+
|
|
49
|
+
for (const model of data.data) {
|
|
50
|
+
console.log(`🤖 ${model.id}`);
|
|
51
|
+
}
|
|
52
|
+
} catch (error) {
|
|
53
|
+
console.error("Failed to list models:", error instanceof Error ? error.message : error);
|
|
54
|
+
}
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
name: "sglang",
|
|
59
|
+
version: "2026.3.17",
|
|
60
|
+
commands: ["sglang.status", "sglang.models"],
|
|
61
|
+
};
|
|
62
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@poolbot/test-utils",
|
|
3
|
+
"version": "2026.3.17",
|
|
4
|
+
"description": "Pool Bot test utilities and helpers",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"poolbot": "workspace:*"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"vitest": "^4.0.18"
|
|
12
|
+
},
|
|
13
|
+
"poolbot": {
|
|
14
|
+
"extensions": ["./src/index.ts"],
|
|
15
|
+
"testUtils": true
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"id": "test-utils",
|
|
3
|
+
"name": "Test Utilities",
|
|
4
|
+
"version": "2026.3.17",
|
|
5
|
+
"description": "Testing utilities and helpers for Pool Bot development",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"capabilities": ["testing", "mocking"],
|
|
8
|
+
"commands": ["test.mock-config"],
|
|
9
|
+
"exports": {
|
|
10
|
+
"createMockConfig": "./dist/index.js",
|
|
11
|
+
"createMockRuntime": "./dist/index.js",
|
|
12
|
+
"waitForCondition": "./dist/index.js",
|
|
13
|
+
"createTempFile": "./dist/index.js",
|
|
14
|
+
"cleanupTempFiles": "./dist/index.js"
|
|
15
|
+
}
|
|
16
|
+
}
|