@poolzin/pool-bot 2026.1.38 → 2026.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/chrome-extension/README.md +3 -3
- package/assets/chrome-extension/background.js +5 -5
- package/assets/chrome-extension/manifest.json +3 -3
- package/assets/chrome-extension/options.html +4 -4
- package/assets/chrome-extension/options.js +1 -1
- package/dist/acp/client.js +3 -3
- package/dist/acp/types.js +1 -1
- package/dist/agents/agent-paths.js +3 -3
- package/dist/agents/auth-profiles/paths.js +3 -3
- package/dist/agents/cli-runner/helpers.js +1 -1
- package/dist/agents/cli-runner.js +2 -2
- package/dist/agents/cloudflare-ai-gateway.js +31 -0
- package/dist/agents/compaction.js +16 -2
- package/dist/agents/context-window-guard.js +13 -10
- package/dist/agents/context.js +4 -4
- package/dist/agents/docs-path.js +1 -1
- package/dist/agents/minimax-vlm.js +1 -1
- package/dist/agents/model-auth.js +12 -1
- package/dist/agents/model-catalog.js +4 -4
- package/dist/agents/model-selection.js +10 -4
- package/dist/agents/models-config.js +3 -3
- package/dist/agents/models-config.providers.js +147 -39
- package/dist/agents/pi-embedded-helpers/openai.js +1 -1
- package/dist/agents/pi-embedded-runner/compact.js +8 -8
- package/dist/agents/pi-embedded-runner/model.js +2 -2
- package/dist/agents/pi-embedded-runner/run/attempt.js +6 -6
- package/dist/agents/pi-embedded-runner/run.js +4 -4
- package/dist/agents/pi-embedded-runner/tool-result-truncation.js +275 -0
- package/dist/agents/pi-embedded-runner/utils.js +1 -1
- package/dist/agents/pi-model-discovery.js +10 -0
- package/dist/agents/pi-tool-definition-adapter.js +50 -9
- package/dist/agents/pi-tools.before-tool-call.js +67 -0
- package/dist/agents/pi-tools.js +10 -5
- package/dist/agents/pi-tools.read.js +2 -2
- package/dist/agents/session-file-repair.js +83 -0
- package/dist/agents/session-transcript-repair.js +68 -0
- package/dist/agents/skills/frontmatter.js +1 -1
- package/dist/agents/skills/workspace.js +2 -2
- package/dist/agents/system-prompt.js +28 -4
- package/dist/agents/together-models.js +127 -0
- package/dist/agents/tool-images.js +1 -1
- package/dist/agents/tool-policy.js +1 -1
- package/dist/agents/tools/browser-tool.js +3 -3
- package/dist/agents/tools/image-tool.js +2 -2
- package/dist/agents/tools/memory-tool.js +94 -7
- package/dist/agents/tools/web-search.js +1 -1
- package/dist/agents/workspace.js +1 -5
- package/dist/auto-reply/commands-registry.data.js +1 -1
- package/dist/auto-reply/reply/commands-context-report.js +2 -2
- package/dist/auto-reply/reply/commands-session.js +2 -2
- package/dist/auto-reply/reply/get-reply-run.js +14 -4
- package/dist/auto-reply/reply/groups.js +1 -1
- package/dist/auto-reply/reply/inbound-context.js +4 -0
- package/dist/auto-reply/reply/inbound-meta.js +130 -0
- package/dist/auto-reply/reply/untrusted-context.js +15 -0
- package/dist/auto-reply/status.js +1 -1
- package/dist/browser/client-fetch.js +1 -1
- package/dist/browser/config.js +1 -1
- package/dist/browser/extension-relay.js +3 -3
- package/dist/browser/server-context.js +2 -2
- package/dist/build-info.json +3 -3
- package/dist/canvas-host/a2ui.js +3 -3
- package/dist/channels/plugins/agent-tools/whatsapp-login.js +1 -17
- package/dist/channels/plugins/catalog.js +2 -2
- package/dist/channels/plugins/onboarding/imessage.js +1 -1
- package/dist/channels/plugins/onboarding/signal.js +1 -1
- package/dist/channels/plugins/onboarding/slack.js +4 -4
- package/dist/channels/plugins/onboarding/whatsapp.js +3 -3
- package/dist/channels/plugins/pairing-message.js +1 -1
- package/dist/cli/browser-cli-extension.js +2 -2
- package/dist/cli/docs-cli.js +1 -1
- package/dist/cli/gateway-cli/dev.js +1 -1
- package/dist/cli/memory-cli.js +25 -15
- package/dist/cli/nodes-cli/register.canvas.js +1 -1
- package/dist/cli/plugins-cli.js +1 -1
- package/dist/cli/run-main.js +2 -2
- package/dist/cli/security-cli.js +1 -1
- package/dist/cli/tagline.js +1 -1
- package/dist/cli/update-cli.js +4 -4
- package/dist/cli/webhooks-cli.js +5 -5
- package/dist/commands/agents.commands.add.js +1 -1
- package/dist/commands/auth-choice.apply.api-providers.js +305 -17
- package/dist/commands/auth-choice.apply.js +4 -1
- package/dist/commands/auth-choice.apply.plugin-provider.js +2 -2
- package/dist/commands/auth-choice.apply.xai.js +63 -0
- package/dist/commands/auth-choice.preferred-provider.js +7 -1
- package/dist/commands/configure.wizard.js +1 -1
- package/dist/commands/dashboard.js +1 -1
- package/dist/commands/docs.js +1 -1
- package/dist/commands/doctor-gateway-services.js +3 -3
- package/dist/commands/doctor-state-integrity.js +2 -14
- package/dist/commands/doctor-update.js +3 -3
- package/dist/commands/doctor.js +1 -1
- package/dist/commands/models/list.probe.js +2 -2
- package/dist/commands/models/list.registry.js +4 -4
- package/dist/commands/models/list.status-command.js +2 -2
- package/dist/commands/onboard-auth.config-core.js +366 -28
- package/dist/commands/onboard-auth.credentials.js +71 -9
- package/dist/commands/onboard-auth.js +3 -3
- package/dist/commands/onboard-auth.models.js +26 -24
- package/dist/commands/onboard-non-interactive/local/auth-choice.js +140 -6
- package/dist/commands/status-all/report-lines.js +1 -1
- package/dist/commands/status.command.js +1 -1
- package/dist/commands/uninstall.js +3 -3
- package/dist/compat/legacy-names.js +1 -1
- package/dist/config/io.js +3 -3
- package/dist/config/schema.js +1 -1
- package/dist/config/types.js +0 -1
- package/dist/config/types.memory.js +1 -0
- package/dist/config/version.js +4 -4
- package/dist/config/zod-schema.js +0 -6
- package/dist/daemon/constants.js +7 -7
- package/dist/daemon/inspect.js +6 -6
- package/dist/daemon/systemd-unit.js +1 -1
- package/dist/discord/monitor/message-handler.process.js +6 -4
- package/dist/gateway/client.js +0 -14
- package/dist/gateway/live-image-probe.js +1 -66
- package/dist/gateway/openai-http.js +2 -2
- package/dist/gateway/openresponses-http.js +4 -4
- package/dist/gateway/server-discovery.js +2 -2
- package/dist/gateway/server-http.js +1 -1
- package/dist/gateway/server.impl.js +2 -6
- package/dist/hooks/frontmatter.js +1 -1
- package/dist/hooks/hooks-status.js +1 -1
- package/dist/hooks/install.js +2 -2
- package/dist/hooks/loader.js +1 -1
- package/dist/hooks/workspace.js +3 -3
- package/dist/index.js +2 -2
- package/dist/infra/bonjour.js +3 -3
- package/dist/infra/path-env.js +3 -3
- package/dist/infra/provider-usage.fetch.minimax.js +1 -1
- package/dist/infra/restart.js +1 -1
- package/dist/infra/tailscale.js +1 -1
- package/dist/macos/relay.js +2 -2
- package/dist/media/input-files.js +1 -1
- package/dist/media/mime.js +4 -0
- package/dist/media/png-encode.js +74 -0
- package/dist/media-understanding/providers/image.js +2 -2
- package/dist/memory/backend-config.js +207 -0
- package/dist/memory/embeddings.js +1 -1
- package/dist/memory/index.js +0 -5
- package/dist/memory/manager.js +3 -25
- package/dist/memory/types.js +1 -0
- package/dist/node-host/runner.js +2 -2
- package/dist/pairing/pairing-messages.js +1 -1
- package/dist/plugins/discovery.js +1 -1
- package/dist/plugins/install.js +2 -2
- package/dist/plugins/update.js +1 -1
- package/dist/security/audit.js +2 -2
- package/dist/shared/text/reasoning-tags.js +52 -7
- package/dist/slack/monitor/message-handler/prepare.js +10 -4
- package/dist/slack/monitor/slash.js +10 -4
- package/dist/tailscale/detect.js +146 -0
- package/dist/telegram/bot-message-context.js +1 -1
- package/dist/test-helpers/workspace.js +11 -0
- package/dist/test-utils/channel-plugins.js +82 -0
- package/dist/test-utils/ports.js +73 -0
- package/dist/utils/shell-argv.js +61 -0
- package/dist/utils.js +10 -0
- package/dist/web/qr-image.js +1 -61
- package/dist/wizard/onboarding.finalize.js +7 -7
- package/dist/wizard/onboarding.js +3 -3
- package/docs/RELEASE_WORKFOTS_COMPARISON.md +3 -3
- package/docs/_config.yml +2 -2
- package/docs/_layouts/default.html +9 -9
- package/docs/concepts/typebox.md +1 -1
- package/docs/docs.json +1 -1
- package/docs/northflank.mdx +7 -7
- package/docs/railway.mdx +3 -3
- package/docs/render.mdx +5 -5
- package/docs/start/lore.md +2 -2
- package/extensions/bluebubbles/index.ts +2 -2
- package/extensions/bluebubbles/package.json +1 -1
- package/extensions/bluebubbles/src/accounts.ts +8 -8
- package/extensions/bluebubbles/src/actions.test.ts +22 -22
- package/extensions/bluebubbles/src/actions.ts +5 -5
- package/extensions/bluebubbles/src/attachments.ts +2 -2
- package/extensions/bluebubbles/src/channel.ts +16 -16
- package/extensions/bluebubbles/src/chat.ts +2 -2
- package/extensions/bluebubbles/src/media-send.ts +2 -2
- package/extensions/bluebubbles/src/monitor.test.ts +46 -46
- package/extensions/bluebubbles/src/monitor.ts +5 -5
- package/extensions/bluebubbles/src/onboarding.ts +7 -7
- package/extensions/bluebubbles/src/reactions.ts +2 -2
- package/extensions/bluebubbles/src/send.ts +2 -2
- package/extensions/copilot-proxy/README.md +1 -1
- package/extensions/copilot-proxy/package.json +1 -1
- package/extensions/diagnostics-otel/index.ts +2 -2
- package/extensions/diagnostics-otel/package.json +1 -1
- package/extensions/diagnostics-otel/src/service.ts +3 -3
- package/extensions/discord/index.ts +2 -2
- package/extensions/discord/package.json +1 -1
- package/extensions/google-antigravity-auth/README.md +1 -1
- package/extensions/google-antigravity-auth/index.ts +1 -1
- package/extensions/google-antigravity-auth/package.json +1 -1
- package/extensions/google-gemini-cli-auth/README.md +1 -1
- package/extensions/google-gemini-cli-auth/oauth.ts +1 -1
- package/extensions/google-gemini-cli-auth/package.json +1 -1
- package/extensions/googlechat/index.ts +3 -3
- package/extensions/googlechat/package.json +1 -1
- package/extensions/googlechat/src/accounts.ts +8 -8
- package/extensions/googlechat/src/actions.ts +6 -6
- package/extensions/googlechat/src/channel.ts +21 -21
- package/extensions/googlechat/src/monitor.ts +8 -8
- package/extensions/googlechat/src/onboarding.ts +10 -10
- package/extensions/imessage/index.ts +2 -2
- package/extensions/imessage/package.json +1 -1
- package/extensions/line/index.ts +2 -2
- package/extensions/line/package.json +1 -1
- package/extensions/line/src/card-command.ts +2 -2
- package/extensions/line/src/channel.logout.test.ts +4 -4
- package/extensions/line/src/channel.sendPayload.test.ts +8 -8
- package/extensions/line/src/channel.ts +3 -3
- package/extensions/llm-task/README.md +3 -3
- package/extensions/llm-task/index.ts +2 -2
- package/extensions/llm-task/package.json +1 -1
- package/extensions/llm-task/src/llm-task-tool.ts +4 -4
- package/extensions/lobster/README.md +6 -6
- package/extensions/lobster/index.ts +2 -2
- package/extensions/lobster/src/lobster-tool.test.ts +4 -4
- package/extensions/lobster/src/lobster-tool.ts +2 -2
- package/extensions/matrix/index.ts +2 -2
- package/extensions/matrix/package.json +1 -1
- package/extensions/matrix/src/matrix/client/config.ts +1 -1
- package/extensions/matrix/src/matrix/monitor/handler.ts +1 -1
- package/extensions/matrix/src/onboarding.ts +1 -1
- package/extensions/mattermost/index.ts +2 -2
- package/extensions/mattermost/package.json +1 -1
- package/extensions/mattermost/src/mattermost/accounts.ts +8 -8
- package/extensions/mattermost/src/mattermost/monitor-helpers.ts +5 -5
- package/extensions/mattermost/src/mattermost/monitor.ts +2 -2
- package/extensions/mattermost/src/onboarding-helpers.ts +3 -3
- package/extensions/mattermost/src/onboarding.ts +2 -2
- package/extensions/memory-core/index.ts +2 -2
- package/extensions/memory-core/package.json +1 -4
- package/extensions/memory-lancedb/index.ts +3 -3
- package/extensions/memory-lancedb/package.json +1 -1
- package/extensions/msteams/index.ts +2 -2
- package/extensions/msteams/package.json +1 -1
- package/extensions/msteams/src/channel.directory.test.ts +2 -2
- package/extensions/msteams/src/channel.ts +2 -2
- package/extensions/msteams/src/graph-upload.ts +4 -4
- package/extensions/msteams/src/monitor-handler.ts +2 -2
- package/extensions/msteams/src/monitor.ts +2 -2
- package/extensions/msteams/src/onboarding.ts +9 -9
- package/extensions/msteams/src/reply-dispatcher.ts +2 -2
- package/extensions/msteams/src/send-context.ts +2 -2
- package/extensions/msteams/src/send.ts +4 -4
- package/extensions/nextcloud-talk/index.ts +2 -2
- package/extensions/nextcloud-talk/package.json +1 -1
- package/extensions/nextcloud-talk/src/channel.ts +7 -7
- package/extensions/nextcloud-talk/src/inbound.ts +7 -7
- package/extensions/nextcloud-talk/src/onboarding.ts +1 -1
- package/extensions/nostr/README.md +2 -2
- package/extensions/nostr/index.ts +5 -5
- package/extensions/nostr/package.json +1 -1
- package/extensions/nostr/src/types.ts +4 -4
- package/extensions/open-prose/index.ts +2 -2
- package/extensions/qwen-portal-auth/README.md +1 -1
- package/extensions/signal/index.ts +2 -2
- package/extensions/signal/package.json +1 -1
- package/extensions/slack/index.ts +2 -2
- package/extensions/slack/package.json +1 -1
- package/extensions/telegram/index.ts +2 -2
- package/extensions/telegram/package.json +1 -1
- package/extensions/telegram/src/channel.ts +2 -2
- package/extensions/tlon/README.md +2 -2
- package/extensions/tlon/index.ts +2 -2
- package/extensions/tlon/package.json +1 -1
- package/extensions/tlon/src/channel.ts +13 -13
- package/extensions/tlon/src/monitor/index.ts +3 -3
- package/extensions/tlon/src/onboarding.ts +3 -3
- package/extensions/tlon/src/types.ts +3 -3
- package/extensions/twitch/README.md +1 -1
- package/extensions/twitch/index.ts +2 -2
- package/extensions/twitch/package.json +1 -1
- package/extensions/twitch/src/config.ts +3 -3
- package/extensions/twitch/src/monitor.ts +3 -3
- package/extensions/twitch/src/onboarding.ts +9 -9
- package/extensions/twitch/src/outbound.test.ts +2 -2
- package/extensions/twitch/src/plugin.test.ts +2 -2
- package/extensions/twitch/src/plugin.ts +8 -8
- package/extensions/twitch/src/send.test.ts +2 -2
- package/extensions/twitch/src/send.ts +4 -4
- package/extensions/twitch/src/token.test.ts +8 -8
- package/extensions/twitch/src/token.ts +3 -3
- package/extensions/twitch/src/twitch-client.ts +3 -3
- package/extensions/twitch/src/types.ts +3 -3
- package/extensions/twitch/src/utils/markdown.ts +1 -1
- package/extensions/voice-call/README.md +3 -3
- package/extensions/voice-call/package.json +1 -1
- package/extensions/voice-call/src/core-bridge.ts +2 -2
- package/extensions/voice-call/src/response-generator.ts +1 -1
- package/extensions/whatsapp/index.ts +2 -2
- package/extensions/whatsapp/package.json +1 -1
- package/extensions/zalo/README.md +1 -1
- package/extensions/zalo/index.ts +2 -2
- package/extensions/zalo/package.json +1 -1
- package/extensions/zalo/src/accounts.ts +8 -8
- package/extensions/zalo/src/actions.ts +4 -4
- package/extensions/zalo/src/channel.directory.test.ts +2 -2
- package/extensions/zalo/src/channel.ts +18 -18
- package/extensions/zalo/src/monitor.ts +9 -9
- package/extensions/zalo/src/monitor.webhook.test.ts +2 -2
- package/extensions/zalo/src/onboarding.ts +24 -24
- package/extensions/zalo/src/send.ts +2 -2
- package/extensions/zalouser/README.md +2 -2
- package/extensions/zalouser/index.ts +2 -2
- package/extensions/zalouser/package.json +1 -1
- package/extensions/zalouser/src/accounts.ts +9 -9
- package/extensions/zalouser/src/channel.ts +24 -24
- package/extensions/zalouser/src/monitor.ts +4 -4
- package/extensions/zalouser/src/onboarding.ts +28 -28
- package/package.json +13 -250
- package/skills/nano-banana-pro/scripts/generate_image.py +1 -1
- package/skills/tmux/scripts/find-sessions.sh +1 -1
- package/CHANGELOG.md +0 -200
- package/README-header.png +0 -0
- package/git-hooks/pre-commit +0 -4
- package/scripts/format-staged.js +0 -148
- package/scripts/postinstall.js +0 -300
- package/scripts/setup-git-hooks.js +0 -96
- package/skills/webgpu-threejs-tsl/REFERENCE.md +0 -283
- package/skills/webgpu-threejs-tsl/SKILL.md +0 -91
- package/skills/webgpu-threejs-tsl/docs/compute-shaders.md +0 -404
- package/skills/webgpu-threejs-tsl/docs/core-concepts.md +0 -453
- package/skills/webgpu-threejs-tsl/docs/materials.md +0 -353
- package/skills/webgpu-threejs-tsl/docs/post-processing.md +0 -434
- package/skills/webgpu-threejs-tsl/docs/wgsl-integration.md +0 -324
- package/skills/webgpu-threejs-tsl/examples/basic-setup.js +0 -87
- package/skills/webgpu-threejs-tsl/examples/custom-material.js +0 -170
- package/skills/webgpu-threejs-tsl/examples/earth-shader.js +0 -292
- package/skills/webgpu-threejs-tsl/examples/particle-system.js +0 -259
- package/skills/webgpu-threejs-tsl/examples/post-processing.js +0 -199
- package/skills/webgpu-threejs-tsl/templates/compute-shader.js +0 -305
- package/skills/webgpu-threejs-tsl/templates/webgpu-project.js +0 -276
package/dist/gateway/client.js
CHANGED
|
@@ -3,7 +3,6 @@ import { WebSocket } from "ws";
|
|
|
3
3
|
import { normalizeFingerprint } from "../infra/tls/fingerprint.js";
|
|
4
4
|
import { rawDataToString } from "../infra/ws.js";
|
|
5
5
|
import { logDebug, logError } from "../logger.js";
|
|
6
|
-
import { validateGatewayUrlSecurity } from "./url-validation.js";
|
|
7
6
|
import { loadOrCreateDeviceIdentity, publicKeyRawBase64UrlFromPem, signDevicePayload, } from "../infra/device-identity.js";
|
|
8
7
|
import { clearDeviceAuthToken, loadDeviceAuthToken, storeDeviceAuthToken, } from "../infra/device-auth-store.js";
|
|
9
8
|
import { GATEWAY_CLIENT_MODES, GATEWAY_CLIENT_NAMES, } from "../utils/message-channel.js";
|
|
@@ -42,19 +41,6 @@ export class GatewayClient {
|
|
|
42
41
|
if (this.closed)
|
|
43
42
|
return;
|
|
44
43
|
const url = this.opts.url ?? "ws://127.0.0.1:18789";
|
|
45
|
-
// SECURITY: Validate gateway URL override
|
|
46
|
-
// Prevents credential leakage via redirects to untrusted gateways
|
|
47
|
-
try {
|
|
48
|
-
validateGatewayUrlSecurity({
|
|
49
|
-
url,
|
|
50
|
-
token: this.opts.token,
|
|
51
|
-
requireExplicitToken: this.opts.requireExplicitToken,
|
|
52
|
-
});
|
|
53
|
-
}
|
|
54
|
-
catch (err) {
|
|
55
|
-
this.opts.onConnectError?.(err instanceof Error ? err : new Error(String(err)));
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
44
|
if (this.opts.tlsFingerprint && !url.startsWith("wss://")) {
|
|
59
45
|
this.opts.onConnectError?.(new Error("gateway tls fingerprint requires wss:// gateway url"));
|
|
60
46
|
return;
|
|
@@ -1,69 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
const CRC_TABLE = (() => {
|
|
3
|
-
const table = new Uint32Array(256);
|
|
4
|
-
for (let i = 0; i < 256; i += 1) {
|
|
5
|
-
let c = i;
|
|
6
|
-
for (let k = 0; k < 8; k += 1) {
|
|
7
|
-
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
8
|
-
}
|
|
9
|
-
table[i] = c >>> 0;
|
|
10
|
-
}
|
|
11
|
-
return table;
|
|
12
|
-
})();
|
|
13
|
-
function crc32(buf) {
|
|
14
|
-
let crc = 0xffffffff;
|
|
15
|
-
for (let i = 0; i < buf.length; i += 1) {
|
|
16
|
-
crc = CRC_TABLE[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8);
|
|
17
|
-
}
|
|
18
|
-
return (crc ^ 0xffffffff) >>> 0;
|
|
19
|
-
}
|
|
20
|
-
function pngChunk(type, data) {
|
|
21
|
-
const typeBuf = Buffer.from(type, "ascii");
|
|
22
|
-
const len = Buffer.alloc(4);
|
|
23
|
-
len.writeUInt32BE(data.length, 0);
|
|
24
|
-
const crc = crc32(Buffer.concat([typeBuf, data]));
|
|
25
|
-
const crcBuf = Buffer.alloc(4);
|
|
26
|
-
crcBuf.writeUInt32BE(crc, 0);
|
|
27
|
-
return Buffer.concat([len, typeBuf, data, crcBuf]);
|
|
28
|
-
}
|
|
29
|
-
function encodePngRgba(buffer, width, height) {
|
|
30
|
-
const stride = width * 4;
|
|
31
|
-
const raw = Buffer.alloc((stride + 1) * height);
|
|
32
|
-
for (let row = 0; row < height; row += 1) {
|
|
33
|
-
const rawOffset = row * (stride + 1);
|
|
34
|
-
raw[rawOffset] = 0; // filter: none
|
|
35
|
-
buffer.copy(raw, rawOffset + 1, row * stride, row * stride + stride);
|
|
36
|
-
}
|
|
37
|
-
const compressed = deflateSync(raw);
|
|
38
|
-
const signature = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
|
|
39
|
-
const ihdr = Buffer.alloc(13);
|
|
40
|
-
ihdr.writeUInt32BE(width, 0);
|
|
41
|
-
ihdr.writeUInt32BE(height, 4);
|
|
42
|
-
ihdr[8] = 8; // bit depth
|
|
43
|
-
ihdr[9] = 6; // color type RGBA
|
|
44
|
-
ihdr[10] = 0; // compression
|
|
45
|
-
ihdr[11] = 0; // filter
|
|
46
|
-
ihdr[12] = 0; // interlace
|
|
47
|
-
return Buffer.concat([
|
|
48
|
-
signature,
|
|
49
|
-
pngChunk("IHDR", ihdr),
|
|
50
|
-
pngChunk("IDAT", compressed),
|
|
51
|
-
pngChunk("IEND", Buffer.alloc(0)),
|
|
52
|
-
]);
|
|
53
|
-
}
|
|
54
|
-
function fillPixel(buf, x, y, width, r, g, b, a = 255) {
|
|
55
|
-
if (x < 0 || y < 0)
|
|
56
|
-
return;
|
|
57
|
-
if (x >= width)
|
|
58
|
-
return;
|
|
59
|
-
const idx = (y * width + x) * 4;
|
|
60
|
-
if (idx < 0 || idx + 3 >= buf.length)
|
|
61
|
-
return;
|
|
62
|
-
buf[idx] = r;
|
|
63
|
-
buf[idx + 1] = g;
|
|
64
|
-
buf[idx + 2] = b;
|
|
65
|
-
buf[idx + 3] = a;
|
|
66
|
-
}
|
|
1
|
+
import { encodePngRgba, fillPixel } from "../media/png-encode.js";
|
|
67
2
|
const GLYPH_ROWS_5X7 = {
|
|
68
3
|
"0": [0b01110, 0b10001, 0b10011, 0b10101, 0b11001, 0b10001, 0b01110],
|
|
69
4
|
"1": [0b00100, 0b01100, 0b00100, 0b00100, 0b00100, 0b00100, 0b01110],
|
|
@@ -167,7 +167,7 @@ export async function handleOpenAiHttpRequest(req, res, opts) {
|
|
|
167
167
|
.map((p) => (typeof p.text === "string" ? p.text : ""))
|
|
168
168
|
.filter(Boolean)
|
|
169
169
|
.join("\n\n")
|
|
170
|
-
: "No response from
|
|
170
|
+
: "No response from Poolbot.";
|
|
171
171
|
sendJson(res, 200, {
|
|
172
172
|
id: runId,
|
|
173
173
|
object: "chat.completion",
|
|
@@ -275,7 +275,7 @@ export async function handleOpenAiHttpRequest(req, res, opts) {
|
|
|
275
275
|
.map((p) => (typeof p.text === "string" ? p.text : ""))
|
|
276
276
|
.filter(Boolean)
|
|
277
277
|
.join("\n\n")
|
|
278
|
-
: "No response from
|
|
278
|
+
: "No response from Poolbot.";
|
|
279
279
|
sawAssistantDelta = true;
|
|
280
280
|
writeSse(res, {
|
|
281
281
|
id: runId,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* OpenResponses HTTP Handler
|
|
3
3
|
*
|
|
4
|
-
* Implements the OpenResponses `/v1/responses` endpoint for
|
|
4
|
+
* Implements the OpenResponses `/v1/responses` endpoint for Poolbot Gateway.
|
|
5
5
|
*
|
|
6
6
|
* @see https://www.open-responses.com/
|
|
7
7
|
*/
|
|
@@ -405,7 +405,7 @@ export async function handleOpenResponsesHttpRequest(req, res, opts) {
|
|
|
405
405
|
.map((p) => (typeof p.text === "string" ? p.text : ""))
|
|
406
406
|
.filter(Boolean)
|
|
407
407
|
.join("\n\n")
|
|
408
|
-
: "No response from
|
|
408
|
+
: "No response from Poolbot.";
|
|
409
409
|
const response = createResponseResource({
|
|
410
410
|
id: responseId,
|
|
411
411
|
model,
|
|
@@ -543,7 +543,7 @@ export async function handleOpenResponsesHttpRequest(req, res, opts) {
|
|
|
543
543
|
if (evt.stream === "lifecycle") {
|
|
544
544
|
const phase = evt.data?.phase;
|
|
545
545
|
if (phase === "end" || phase === "error") {
|
|
546
|
-
const finalText = accumulatedText || "No response from
|
|
546
|
+
const finalText = accumulatedText || "No response from Poolbot.";
|
|
547
547
|
const finalStatus = phase === "error" ? "failed" : "completed";
|
|
548
548
|
requestFinalize(finalStatus, finalText);
|
|
549
549
|
}
|
|
@@ -647,7 +647,7 @@ export async function handleOpenResponsesHttpRequest(req, res, opts) {
|
|
|
647
647
|
.map((p) => (typeof p.text === "string" ? p.text : ""))
|
|
648
648
|
.filter(Boolean)
|
|
649
649
|
.join("\n\n")
|
|
650
|
-
: "No response from
|
|
650
|
+
: "No response from Poolbot.";
|
|
651
651
|
accumulatedText = content;
|
|
652
652
|
sawAssistantDelta = true;
|
|
653
653
|
writeSseEvent(res, {
|
|
@@ -5,10 +5,10 @@ import { runExec } from "../process/exec.js";
|
|
|
5
5
|
export function formatBonjourInstanceName(displayName) {
|
|
6
6
|
const trimmed = displayName.trim();
|
|
7
7
|
if (!trimmed)
|
|
8
|
-
return "
|
|
8
|
+
return "Poolbot";
|
|
9
9
|
if (/poolbot/i.test(trimmed))
|
|
10
10
|
return trimmed;
|
|
11
|
-
return `${trimmed} (
|
|
11
|
+
return `${trimmed} (Poolbot)`;
|
|
12
12
|
}
|
|
13
13
|
export function resolveBonjourCliPath(opts = {}) {
|
|
14
14
|
const env = opts.env ?? process.env;
|
|
@@ -36,7 +36,7 @@ export function createHooksRequestHandler(opts) {
|
|
|
36
36
|
if (fromQuery) {
|
|
37
37
|
logHooks.warn("Hook token provided via query parameter is deprecated for security reasons. " +
|
|
38
38
|
"Tokens in URLs appear in logs, browser history, and referrer headers. " +
|
|
39
|
-
"Use Authorization: Bearer <token> or X-
|
|
39
|
+
"Use Authorization: Bearer <token> or X-Poolbot-Token header instead.");
|
|
40
40
|
}
|
|
41
41
|
if (req.method !== "POST") {
|
|
42
42
|
res.statusCode = 405;
|
|
@@ -12,7 +12,7 @@ import { clearAgentRunContext, onAgentEvent } from "../infra/agent-events.js";
|
|
|
12
12
|
import { onHeartbeatEvent } from "../infra/heartbeat-events.js";
|
|
13
13
|
import { startHeartbeatRunner } from "../infra/heartbeat-runner.js";
|
|
14
14
|
import { getMachineDisplayName } from "../infra/machine-name.js";
|
|
15
|
-
import {
|
|
15
|
+
import { ensurePoolbotCliOnPath } from "../infra/path-env.js";
|
|
16
16
|
import { primeRemoteSkillsCache, refreshRemoteBinsForConnectedNodes, setSkillsRemoteRegistry, } from "../infra/skills-remote.js";
|
|
17
17
|
import { scheduleGatewayUpdateCheck } from "../infra/update-startup.js";
|
|
18
18
|
import { setGatewaySigusr1RestartPolicy } from "../infra/restart.js";
|
|
@@ -27,7 +27,6 @@ import { createExecApprovalHandlers } from "./server-methods/exec-approval.js";
|
|
|
27
27
|
import { createExecApprovalForwarder } from "../infra/exec-approval-forwarder.js";
|
|
28
28
|
import { createChannelManager } from "./server-channels.js";
|
|
29
29
|
import { createAgentEventHandler } from "./server-chat.js";
|
|
30
|
-
import { startLifecycleHooksIntegration } from "./hooks/lifecycle-hooks-integration.js";
|
|
31
30
|
import { createGatewayCloseHandler } from "./server-close.js";
|
|
32
31
|
import { buildGatewayCronService } from "./server-cron.js";
|
|
33
32
|
import { applyGatewayLaneConcurrency } from "./server-lanes.js";
|
|
@@ -51,7 +50,7 @@ import { loadGatewayTlsRuntime } from "./server/tls.js";
|
|
|
51
50
|
import { createWizardSessionTracker } from "./server-wizard-sessions.js";
|
|
52
51
|
import { attachGatewayWsHandlers } from "./server-ws-runtime.js";
|
|
53
52
|
export { __resetModelCatalogCacheForTest } from "./server-model-catalog.js";
|
|
54
|
-
|
|
53
|
+
ensurePoolbotCliOnPath();
|
|
55
54
|
const log = createSubsystemLogger("gateway");
|
|
56
55
|
const logCanvas = log.child("canvas");
|
|
57
56
|
const logDiscovery = log.child("discovery");
|
|
@@ -264,9 +263,6 @@ export async function startGatewayServer(port = 18789, opts = {}) {
|
|
|
264
263
|
resolveSessionKeyForRun,
|
|
265
264
|
clearAgentRunContext,
|
|
266
265
|
}));
|
|
267
|
-
// Lifecycle Hooks Integration (POC Day 1.5)
|
|
268
|
-
const lifecycleHooksUnsub = startLifecycleHooksIntegration();
|
|
269
|
-
logHooks.info("Lifecycle hooks integration started");
|
|
270
266
|
const heartbeatUnsub = onHeartbeatEvent((evt) => {
|
|
271
267
|
broadcast("heartbeat", evt, { dropIfSlow: true });
|
|
272
268
|
});
|
|
@@ -52,7 +52,7 @@ function parseFrontmatterBool(value, fallback) {
|
|
|
52
52
|
const parsed = parseBooleanValue(value);
|
|
53
53
|
return parsed === undefined ? fallback : parsed;
|
|
54
54
|
}
|
|
55
|
-
export function
|
|
55
|
+
export function resolvePoolbotMetadata(frontmatter) {
|
|
56
56
|
const raw = getFrontmatterValue(frontmatter, "metadata");
|
|
57
57
|
if (!raw)
|
|
58
58
|
return undefined;
|
|
@@ -16,7 +16,7 @@ function normalizeInstallOptions(entry) {
|
|
|
16
16
|
let label = (spec.label ?? "").trim();
|
|
17
17
|
if (!label) {
|
|
18
18
|
if (spec.kind === "bundled") {
|
|
19
|
-
label = "Bundled with
|
|
19
|
+
label = "Bundled with Poolbot";
|
|
20
20
|
}
|
|
21
21
|
else if (spec.kind === "npm" && spec.package) {
|
|
22
22
|
label = `Install ${spec.package} (npm)`;
|
package/dist/hooks/install.js
CHANGED
|
@@ -23,7 +23,7 @@ export function resolveHookInstallDir(hookId, hooksDir) {
|
|
|
23
23
|
const hooksBase = hooksDir ? resolveUserPath(hooksDir) : path.join(CONFIG_DIR, "hooks");
|
|
24
24
|
return path.join(hooksBase, safeDirName(hookId));
|
|
25
25
|
}
|
|
26
|
-
async function
|
|
26
|
+
async function ensurePoolbotHooks(manifest) {
|
|
27
27
|
const hooks = manifest.poolbot?.hooks ?? manifest[LEGACY_MANIFEST_KEY]?.hooks;
|
|
28
28
|
if (!Array.isArray(hooks)) {
|
|
29
29
|
throw new Error("package.json missing poolbot.hooks");
|
|
@@ -72,7 +72,7 @@ async function installHookPackageFromDir(params) {
|
|
|
72
72
|
}
|
|
73
73
|
let hookEntries;
|
|
74
74
|
try {
|
|
75
|
-
hookEntries = await
|
|
75
|
+
hookEntries = await ensurePoolbotHooks(manifest);
|
|
76
76
|
}
|
|
77
77
|
catch (err) {
|
|
78
78
|
return { ok: false, error: String(err) };
|
package/dist/hooks/loader.js
CHANGED
|
@@ -17,7 +17,7 @@ import { shouldIncludeHook } from "./config.js";
|
|
|
17
17
|
* 1. Directory-based discovery (bundled, managed, workspace)
|
|
18
18
|
* 2. Legacy config handlers (backwards compatibility)
|
|
19
19
|
*
|
|
20
|
-
* @param cfg -
|
|
20
|
+
* @param cfg - Poolbot configuration
|
|
21
21
|
* @param workspaceDir - Workspace directory for hook discovery
|
|
22
22
|
* @returns Number of handlers successfully loaded
|
|
23
23
|
*
|
package/dist/hooks/workspace.js
CHANGED
|
@@ -4,7 +4,7 @@ import { LEGACY_MANIFEST_KEY } from "../compat/legacy-names.js";
|
|
|
4
4
|
import { CONFIG_DIR, resolveUserPath } from "../utils.js";
|
|
5
5
|
import { resolveBundledHooksDir } from "./bundled-dir.js";
|
|
6
6
|
import { shouldIncludeHook } from "./config.js";
|
|
7
|
-
import { parseFrontmatter,
|
|
7
|
+
import { parseFrontmatter, resolvePoolbotMetadata, resolveHookInvocationPolicy, } from "./frontmatter.js";
|
|
8
8
|
function filterHookEntries(entries, config, eligibility) {
|
|
9
9
|
return entries.filter((entry) => shouldIncludeHook({ entry, config, eligibility }));
|
|
10
10
|
}
|
|
@@ -128,7 +128,7 @@ export function loadHookEntriesFromDir(params) {
|
|
|
128
128
|
pluginId: params.pluginId,
|
|
129
129
|
},
|
|
130
130
|
frontmatter,
|
|
131
|
-
metadata:
|
|
131
|
+
metadata: resolvePoolbotMetadata(frontmatter),
|
|
132
132
|
invocation: resolveHookInvocationPolicy(frontmatter),
|
|
133
133
|
};
|
|
134
134
|
return entry;
|
|
@@ -185,7 +185,7 @@ function loadHookEntries(workspaceDir, opts) {
|
|
|
185
185
|
return {
|
|
186
186
|
hook,
|
|
187
187
|
frontmatter,
|
|
188
|
-
metadata:
|
|
188
|
+
metadata: resolvePoolbotMetadata(frontmatter),
|
|
189
189
|
invocation: resolveHookInvocationPolicy(frontmatter),
|
|
190
190
|
};
|
|
191
191
|
});
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import { ensureBinary } from "./infra/binaries.js";
|
|
|
13
13
|
import { loadDotEnv } from "./infra/dotenv.js";
|
|
14
14
|
import { normalizeEnv } from "./infra/env.js";
|
|
15
15
|
import { isMainModule } from "./infra/is-main.js";
|
|
16
|
-
import {
|
|
16
|
+
import { ensurePoolbotCliOnPath } from "./infra/path-env.js";
|
|
17
17
|
import { describePortOwner, ensurePortAvailable, handlePortError, PortInUseError, } from "./infra/ports.js";
|
|
18
18
|
import { assertSupportedRuntime } from "./infra/runtime-guard.js";
|
|
19
19
|
import { formatUncaughtError } from "./infra/errors.js";
|
|
@@ -23,7 +23,7 @@ import { runCommandWithTimeout, runExec } from "./process/exec.js";
|
|
|
23
23
|
import { assertWebChannel, normalizeE164, toWhatsappJid } from "./utils.js";
|
|
24
24
|
loadDotEnv({ quiet: true });
|
|
25
25
|
normalizeEnv();
|
|
26
|
-
|
|
26
|
+
ensurePoolbotCliOnPath();
|
|
27
27
|
// Capture all console output into structured logs while keeping stdout/stderr behavior.
|
|
28
28
|
enableConsoleCapture();
|
|
29
29
|
// Enforce the minimum supported runtime before doing any work.
|
package/dist/infra/bonjour.js
CHANGED
|
@@ -16,11 +16,11 @@ function isDisabledByEnv() {
|
|
|
16
16
|
}
|
|
17
17
|
function safeServiceName(name) {
|
|
18
18
|
const trimmed = name.trim();
|
|
19
|
-
return trimmed.length > 0 ? trimmed : "
|
|
19
|
+
return trimmed.length > 0 ? trimmed : "Poolbot";
|
|
20
20
|
}
|
|
21
21
|
function prettifyInstanceName(name) {
|
|
22
22
|
const normalized = name.trim().replace(/\s+/g, " ");
|
|
23
|
-
return normalized.replace(/\s+\(
|
|
23
|
+
return normalized.replace(/\s+\(Poolbot\)\s*$/i, "").trim() || normalized;
|
|
24
24
|
}
|
|
25
25
|
function serviceSummary(label, svc) {
|
|
26
26
|
let fqdn = "unknown";
|
|
@@ -63,7 +63,7 @@ export async function startGatewayBonjourAdvertiser(opts) {
|
|
|
63
63
|
.trim() || "poolbot";
|
|
64
64
|
const instanceName = typeof opts.instanceName === "string" && opts.instanceName.trim()
|
|
65
65
|
? opts.instanceName.trim()
|
|
66
|
-
: `${hostname} (
|
|
66
|
+
: `${hostname} (Poolbot)`;
|
|
67
67
|
const displayName = prettifyInstanceName(instanceName);
|
|
68
68
|
const txtBase = {
|
|
69
69
|
role: "gateway",
|
package/dist/infra/path-env.js
CHANGED
|
@@ -45,8 +45,8 @@ function candidateBinDirs(opts) {
|
|
|
45
45
|
// Bundled macOS app: `poolbot` lives next to the executable (process.execPath).
|
|
46
46
|
try {
|
|
47
47
|
const execDir = path.dirname(execPath);
|
|
48
|
-
const
|
|
49
|
-
if (isExecutable(
|
|
48
|
+
const siblingPoolbot = path.join(execDir, "poolbot");
|
|
49
|
+
if (isExecutable(siblingPoolbot))
|
|
50
50
|
candidates.push(execDir);
|
|
51
51
|
}
|
|
52
52
|
catch {
|
|
@@ -79,7 +79,7 @@ function candidateBinDirs(opts) {
|
|
|
79
79
|
* Best-effort PATH bootstrap so skills that require the `poolbot` CLI can run
|
|
80
80
|
* under launchd/minimal environments (and inside the macOS app bundle).
|
|
81
81
|
*/
|
|
82
|
-
export function
|
|
82
|
+
export function ensurePoolbotCliOnPath(opts = {}) {
|
|
83
83
|
if (isTruthyEnvValue(process.env.CLAWDBOT_PATH_BOOTSTRAPPED))
|
|
84
84
|
return;
|
|
85
85
|
process.env.CLAWDBOT_PATH_BOOTSTRAPPED = "1";
|
|
@@ -260,7 +260,7 @@ export async function fetchMinimaxUsage(apiKey, timeoutMs, fetchFn) {
|
|
|
260
260
|
headers: {
|
|
261
261
|
Authorization: `Bearer ${apiKey}`,
|
|
262
262
|
"Content-Type": "application/json",
|
|
263
|
-
"MM-API-Source": "
|
|
263
|
+
"MM-API-Source": "Poolbot",
|
|
264
264
|
},
|
|
265
265
|
}, timeoutMs, fetchFn);
|
|
266
266
|
if (!res.ok) {
|
package/dist/infra/restart.js
CHANGED
|
@@ -71,7 +71,7 @@ function normalizeSystemdUnit(raw, profile) {
|
|
|
71
71
|
}
|
|
72
72
|
return unit.endsWith(".service") ? unit : `${unit}.service`;
|
|
73
73
|
}
|
|
74
|
-
export function
|
|
74
|
+
export function triggerPoolbotRestart() {
|
|
75
75
|
if (process.env.VITEST || process.env.NODE_ENV === "test") {
|
|
76
76
|
return { ok: true, method: "supervisor", detail: "test mode" };
|
|
77
77
|
}
|
package/dist/infra/tailscale.js
CHANGED
|
@@ -263,7 +263,7 @@ export async function ensureFunnel(port, exec = runExec, runtime = defaultRuntim
|
|
|
263
263
|
console.error(warn("Tailscale client/server version mismatch detected; try updating tailscale/tailscaled."));
|
|
264
264
|
}
|
|
265
265
|
runtime.error("Failed to enable Tailscale Funnel. Is it allowed on your tailnet?");
|
|
266
|
-
runtime.error(info(`Tip: Funnel is optional for
|
|
266
|
+
runtime.error(info(`Tip: Funnel is optional for Poolbot. You can keep running the web gateway without it: \`${formatCliCommand("poolbot gateway")}\``));
|
|
267
267
|
if (shouldLogVerbose()) {
|
|
268
268
|
const rich = isRich();
|
|
269
269
|
if (stdout.trim()) {
|
package/dist/macos/relay.js
CHANGED
|
@@ -37,8 +37,8 @@ async function main() {
|
|
|
37
37
|
await patchBunLongForProtobuf();
|
|
38
38
|
const { loadDotEnv } = await import("../infra/dotenv.js");
|
|
39
39
|
loadDotEnv({ quiet: true });
|
|
40
|
-
const {
|
|
41
|
-
|
|
40
|
+
const { ensurePoolbotCliOnPath } = await import("../infra/path-env.js");
|
|
41
|
+
ensurePoolbotCliOnPath();
|
|
42
42
|
const { enableConsoleCapture } = await import("../logging.js");
|
|
43
43
|
enableConsoleCapture();
|
|
44
44
|
const { assertSupportedRuntime } = await import("../infra/runtime-guard.js");
|
|
@@ -78,7 +78,7 @@ export async function fetchWithGuard(params) {
|
|
|
78
78
|
try {
|
|
79
79
|
const response = await fetch(parsedUrl, {
|
|
80
80
|
signal: controller.signal,
|
|
81
|
-
headers: { "User-Agent": "
|
|
81
|
+
headers: { "User-Agent": "Poolbot-Gateway/1.0" },
|
|
82
82
|
redirect: "manual",
|
|
83
83
|
dispatcher,
|
|
84
84
|
});
|
package/dist/media/mime.js
CHANGED
|
@@ -11,7 +11,10 @@ const EXT_BY_MIME = {
|
|
|
11
11
|
"image/gif": ".gif",
|
|
12
12
|
"audio/ogg": ".ogg",
|
|
13
13
|
"audio/mpeg": ".mp3",
|
|
14
|
+
"audio/x-m4a": ".m4a",
|
|
15
|
+
"audio/mp4": ".m4a",
|
|
14
16
|
"video/mp4": ".mp4",
|
|
17
|
+
"video/quicktime": ".mov",
|
|
15
18
|
"application/pdf": ".pdf",
|
|
16
19
|
"application/json": ".json",
|
|
17
20
|
"application/zip": ".zip",
|
|
@@ -43,6 +46,7 @@ const AUDIO_FILE_EXTENSIONS = new Set([
|
|
|
43
46
|
".ogg",
|
|
44
47
|
".opus",
|
|
45
48
|
".wav",
|
|
49
|
+
".caf",
|
|
46
50
|
]);
|
|
47
51
|
function normalizeHeaderMime(mime) {
|
|
48
52
|
if (!mime)
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Minimal PNG encoder for generating simple RGBA images without native dependencies.
|
|
3
|
+
* Used for QR codes, live probes, and other programmatic image generation.
|
|
4
|
+
*/
|
|
5
|
+
import { deflateSync } from "node:zlib";
|
|
6
|
+
const CRC_TABLE = (() => {
|
|
7
|
+
const table = new Uint32Array(256);
|
|
8
|
+
for (let i = 0; i < 256; i += 1) {
|
|
9
|
+
let c = i;
|
|
10
|
+
for (let k = 0; k < 8; k += 1) {
|
|
11
|
+
c = c & 1 ? 0xedb88320 ^ (c >>> 1) : c >>> 1;
|
|
12
|
+
}
|
|
13
|
+
table[i] = c >>> 0;
|
|
14
|
+
}
|
|
15
|
+
return table;
|
|
16
|
+
})();
|
|
17
|
+
/** Compute CRC32 checksum for a buffer (used in PNG chunk encoding). */
|
|
18
|
+
export function crc32(buf) {
|
|
19
|
+
let crc = 0xffffffff;
|
|
20
|
+
for (let i = 0; i < buf.length; i += 1) {
|
|
21
|
+
crc = CRC_TABLE[(crc ^ buf[i]) & 0xff] ^ (crc >>> 8);
|
|
22
|
+
}
|
|
23
|
+
return (crc ^ 0xffffffff) >>> 0;
|
|
24
|
+
}
|
|
25
|
+
/** Create a PNG chunk with type, data, and CRC. */
|
|
26
|
+
export function pngChunk(type, data) {
|
|
27
|
+
const typeBuf = Buffer.from(type, "ascii");
|
|
28
|
+
const len = Buffer.alloc(4);
|
|
29
|
+
len.writeUInt32BE(data.length, 0);
|
|
30
|
+
const crc = crc32(Buffer.concat([typeBuf, data]));
|
|
31
|
+
const crcBuf = Buffer.alloc(4);
|
|
32
|
+
crcBuf.writeUInt32BE(crc, 0);
|
|
33
|
+
return Buffer.concat([len, typeBuf, data, crcBuf]);
|
|
34
|
+
}
|
|
35
|
+
/** Write a pixel to an RGBA buffer. Ignores out-of-bounds writes. */
|
|
36
|
+
export function fillPixel(buf, x, y, width, r, g, b, a = 255) {
|
|
37
|
+
if (x < 0 || y < 0 || x >= width) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const idx = (y * width + x) * 4;
|
|
41
|
+
if (idx < 0 || idx + 3 >= buf.length) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
buf[idx] = r;
|
|
45
|
+
buf[idx + 1] = g;
|
|
46
|
+
buf[idx + 2] = b;
|
|
47
|
+
buf[idx + 3] = a;
|
|
48
|
+
}
|
|
49
|
+
/** Encode an RGBA buffer as a PNG image. */
|
|
50
|
+
export function encodePngRgba(buffer, width, height) {
|
|
51
|
+
const stride = width * 4;
|
|
52
|
+
const raw = Buffer.alloc((stride + 1) * height);
|
|
53
|
+
for (let row = 0; row < height; row += 1) {
|
|
54
|
+
const rawOffset = row * (stride + 1);
|
|
55
|
+
raw[rawOffset] = 0; // filter: none
|
|
56
|
+
buffer.copy(raw, rawOffset + 1, row * stride, row * stride + stride);
|
|
57
|
+
}
|
|
58
|
+
const compressed = deflateSync(raw);
|
|
59
|
+
const signature = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]);
|
|
60
|
+
const ihdr = Buffer.alloc(13);
|
|
61
|
+
ihdr.writeUInt32BE(width, 0);
|
|
62
|
+
ihdr.writeUInt32BE(height, 4);
|
|
63
|
+
ihdr[8] = 8; // bit depth
|
|
64
|
+
ihdr[9] = 6; // color type RGBA
|
|
65
|
+
ihdr[10] = 0; // compression
|
|
66
|
+
ihdr[11] = 0; // filter
|
|
67
|
+
ihdr[12] = 0; // interlace
|
|
68
|
+
return Buffer.concat([
|
|
69
|
+
signature,
|
|
70
|
+
pngChunk("IHDR", ihdr),
|
|
71
|
+
pngChunk("IDAT", compressed),
|
|
72
|
+
pngChunk("IEND", Buffer.alloc(0)),
|
|
73
|
+
]);
|
|
74
|
+
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { complete } from "@mariozechner/pi-ai";
|
|
2
2
|
import { discoverAuthStorage, discoverModels } from "@mariozechner/pi-coding-agent";
|
|
3
3
|
import { getApiKeyForModel, requireApiKey } from "../../agents/model-auth.js";
|
|
4
|
-
import {
|
|
4
|
+
import { ensurePoolbotModelsJson } from "../../agents/models-config.js";
|
|
5
5
|
import { minimaxUnderstandImage } from "../../agents/minimax-vlm.js";
|
|
6
6
|
import { coerceImageAssistantText } from "../../agents/tools/image-tool.helpers.js";
|
|
7
7
|
export async function describeImageWithModel(params) {
|
|
8
|
-
await
|
|
8
|
+
await ensurePoolbotModelsJson(params.cfg, params.agentDir);
|
|
9
9
|
const authStorage = discoverAuthStorage(params.agentDir);
|
|
10
10
|
const modelRegistry = discoverModels(authStorage, params.agentDir);
|
|
11
11
|
const model = modelRegistry.find(params.provider, params.model);
|