@rubytech/taskmaster 1.0.66 → 1.0.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agents/memory-search.js +1 -1
- package/dist/build-info.json +2 -2
- package/dist/config/schema.js +1 -1
- package/dist/config/zod-schema.agent-runtime.js +1 -1
- package/dist/gateway/net.js +25 -18
- package/dist/memory/embeddings.js +28 -15
- package/package.json +1 -1
- package/taskmaster-docs/USER-GUIDE.md +51 -0
|
@@ -42,7 +42,7 @@ function resolveStorePath(agentId, raw) {
|
|
|
42
42
|
function mergeConfig(defaults, overrides, agentId) {
|
|
43
43
|
const enabled = overrides?.enabled ?? defaults?.enabled ?? true;
|
|
44
44
|
const sessionMemory = overrides?.experimental?.sessionMemory ?? defaults?.experimental?.sessionMemory ?? false;
|
|
45
|
-
const provider = overrides?.provider ?? defaults?.provider ?? "
|
|
45
|
+
const provider = overrides?.provider ?? defaults?.provider ?? "auto";
|
|
46
46
|
const defaultRemote = defaults?.remote;
|
|
47
47
|
const overrideRemote = overrides?.remote;
|
|
48
48
|
const hasRemote = Boolean(defaultRemote || overrideRemote);
|
package/dist/build-info.json
CHANGED
package/dist/config/schema.js
CHANGED
|
@@ -402,7 +402,7 @@ const FIELD_HELP = {
|
|
|
402
402
|
"agents.defaults.memorySearch": "Vector search over MEMORY.md and memory/*.md (per-agent overrides supported).",
|
|
403
403
|
"agents.defaults.memorySearch.sources": 'Sources to index for memory search (default: ["memory"]; add "sessions" to include session transcripts).',
|
|
404
404
|
"agents.defaults.memorySearch.experimental.sessionMemory": "Enable experimental session transcript indexing for memory search (default: false).",
|
|
405
|
-
"agents.defaults.memorySearch.provider": 'Embedding provider ("openai", "gemini", or "local").',
|
|
405
|
+
"agents.defaults.memorySearch.provider": 'Embedding provider ("auto", "openai", "gemini", or "local"). Auto uses remote when API keys are available, falls back to local.',
|
|
406
406
|
"agents.defaults.memorySearch.remote.baseUrl": "Custom base URL for remote embeddings (OpenAI-compatible proxies or Gemini overrides).",
|
|
407
407
|
"agents.defaults.memorySearch.remote.apiKey": "Custom API key for the remote embedding provider.",
|
|
408
408
|
"agents.defaults.memorySearch.remote.headers": "Extra headers for remote embeddings (merged; remote overrides OpenAI headers).",
|
|
@@ -286,7 +286,7 @@ export const MemorySearchSchema = z
|
|
|
286
286
|
})
|
|
287
287
|
.strict()
|
|
288
288
|
.optional(),
|
|
289
|
-
provider: z.union([z.literal("openai"), z.literal("local"), z.literal("gemini")]).optional(),
|
|
289
|
+
provider: z.union([z.literal("auto"), z.literal("openai"), z.literal("local"), z.literal("gemini")]).optional(),
|
|
290
290
|
remote: z
|
|
291
291
|
.object({
|
|
292
292
|
baseUrl: z.string().optional(),
|
package/dist/gateway/net.js
CHANGED
|
@@ -1,22 +1,29 @@
|
|
|
1
1
|
import net from "node:net";
|
|
2
|
-
import os from "node:os";
|
|
3
2
|
import { pickPrimaryTailnetIPv4, pickPrimaryTailnetIPv6 } from "../infra/tailnet.js";
|
|
4
3
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* Check if an IPv4 address belongs to a private (RFC 1918) or link-local range.
|
|
5
|
+
* These addresses are non-routable on the public internet, so any request
|
|
6
|
+
* from one is by definition on the local network — safe for LAN access.
|
|
7
|
+
*
|
|
8
|
+
* Ranges: 10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16, 169.254.0.0/16
|
|
8
9
|
*/
|
|
9
|
-
function
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
function isPrivateIPv4(ip) {
|
|
11
|
+
const parts = ip.split(".");
|
|
12
|
+
if (parts.length !== 4)
|
|
13
|
+
return false;
|
|
14
|
+
const a = parseInt(parts[0], 10);
|
|
15
|
+
const b = parseInt(parts[1], 10);
|
|
16
|
+
if (Number.isNaN(a) || Number.isNaN(b))
|
|
17
|
+
return false;
|
|
18
|
+
if (a === 10)
|
|
19
|
+
return true; // 10.0.0.0/8
|
|
20
|
+
if (a === 172 && b >= 16 && b <= 31)
|
|
21
|
+
return true; // 172.16.0.0/12
|
|
22
|
+
if (a === 192 && b === 168)
|
|
23
|
+
return true; // 192.168.0.0/16
|
|
24
|
+
if (a === 169 && b === 254)
|
|
25
|
+
return true; // 169.254.0.0/16 (link-local)
|
|
26
|
+
return false;
|
|
20
27
|
}
|
|
21
28
|
export function isLoopbackAddress(ip) {
|
|
22
29
|
if (!ip)
|
|
@@ -96,9 +103,9 @@ export function isLocalGatewayAddress(ip) {
|
|
|
96
103
|
const tailnetIPv6 = pickPrimaryTailnetIPv6();
|
|
97
104
|
if (tailnetIPv6 && ip.trim().toLowerCase() === tailnetIPv6.toLowerCase())
|
|
98
105
|
return true;
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
if (
|
|
106
|
+
// Any RFC 1918 private or link-local address is on the local network.
|
|
107
|
+
// These are non-routable on the public internet, so they're safe.
|
|
108
|
+
if (isPrivateIPv4(normalized))
|
|
102
109
|
return true;
|
|
103
110
|
return false;
|
|
104
111
|
}
|
|
@@ -2,6 +2,7 @@ import fsSync from "node:fs";
|
|
|
2
2
|
import os from "node:os";
|
|
3
3
|
import { createSubsystemLogger } from "../logging/subsystem.js";
|
|
4
4
|
import { resolveUserPath } from "../utils.js";
|
|
5
|
+
import { getCustomProviderApiKey } from "../agents/model-auth.js";
|
|
5
6
|
import { createGeminiEmbeddingProvider } from "./embeddings-gemini.js";
|
|
6
7
|
import { createOpenAiEmbeddingProvider } from "./embeddings-openai.js";
|
|
7
8
|
import { importNodeLlamaCpp } from "./node-llama.js";
|
|
@@ -174,36 +175,48 @@ export async function createEmbeddingProvider(options) {
|
|
|
174
175
|
};
|
|
175
176
|
const formatPrimaryError = (err, provider) => provider === "local" ? formatLocalSetupError(err) : formatError(err);
|
|
176
177
|
if (requestedProvider === "auto") {
|
|
177
|
-
const
|
|
178
|
-
|
|
178
|
+
const errors = [];
|
|
179
|
+
// 1. If user configured an explicit local model file, try it first.
|
|
179
180
|
if (canAutoSelectLocal(options)) {
|
|
180
181
|
try {
|
|
181
182
|
const local = await createProvider("local");
|
|
182
183
|
return { ...local, requestedProvider };
|
|
183
184
|
}
|
|
184
185
|
catch (err) {
|
|
185
|
-
|
|
186
|
+
errors.push(formatLocalSetupError(err));
|
|
186
187
|
}
|
|
187
188
|
}
|
|
188
|
-
|
|
189
|
+
// 2. Try remote providers — preferred when API keys are available
|
|
190
|
+
// (faster, no RAM overhead, no model download).
|
|
191
|
+
// Only consider providers whose key is in the config (apiKeys section).
|
|
192
|
+
// Environment variables are ignored for auto-selection to avoid using
|
|
193
|
+
// stale dev keys that would fail at runtime.
|
|
194
|
+
const remoteProviders = [
|
|
195
|
+
{ id: "openai", configKey: "openai" },
|
|
196
|
+
{ id: "gemini", configKey: "google" },
|
|
197
|
+
];
|
|
198
|
+
for (const { id, configKey } of remoteProviders) {
|
|
199
|
+
if (!getCustomProviderApiKey(options.config, configKey))
|
|
200
|
+
continue;
|
|
189
201
|
try {
|
|
190
|
-
const result = await createProvider(
|
|
202
|
+
const result = await createProvider(id);
|
|
191
203
|
return { ...result, requestedProvider };
|
|
192
204
|
}
|
|
193
205
|
catch (err) {
|
|
194
|
-
|
|
195
|
-
if (isMissingApiKeyError(err)) {
|
|
196
|
-
missingKeyErrors.push(message);
|
|
197
|
-
continue;
|
|
198
|
-
}
|
|
199
|
-
throw new Error(message);
|
|
206
|
+
errors.push(formatPrimaryError(err, id));
|
|
200
207
|
}
|
|
201
208
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
209
|
+
// 3. Fall back to local (downloads default model on first use).
|
|
210
|
+
try {
|
|
211
|
+
const local = await createProvider("local");
|
|
212
|
+
return { ...local, requestedProvider };
|
|
205
213
|
}
|
|
206
|
-
|
|
214
|
+
catch (err) {
|
|
215
|
+
errors.push(formatLocalSetupError(err));
|
|
216
|
+
}
|
|
217
|
+
throw new Error(errors.length > 0
|
|
218
|
+
? errors.join("\n\n")
|
|
219
|
+
: "No embeddings provider available.");
|
|
207
220
|
}
|
|
208
221
|
try {
|
|
209
222
|
const primary = await createProvider(requestedProvider);
|
package/package.json
CHANGED
|
@@ -1267,6 +1267,57 @@ If the page loses connection during the update and doesn't reconnect within two
|
|
|
1267
1267
|
|
|
1268
1268
|
---
|
|
1269
1269
|
|
|
1270
|
+
## Command Line (CLI)
|
|
1271
|
+
|
|
1272
|
+
Taskmaster includes a command-line tool called `taskmaster` that you can run in a terminal (Terminal on Mac, or via SSH on a Pi). You don't need the command line for day-to-day use — the Control Panel handles everything — but it's useful for troubleshooting, updating when the Control Panel isn't accessible, or automating tasks.
|
|
1273
|
+
|
|
1274
|
+
### How to access the terminal
|
|
1275
|
+
|
|
1276
|
+
- **Mac:** Open **Terminal** (search for "Terminal" in Spotlight)
|
|
1277
|
+
- **Raspberry Pi (direct):** Plug in a keyboard and monitor, open Terminal from the taskbar
|
|
1278
|
+
- **Raspberry Pi (remote):** From another computer, run `ssh admin@taskmaster.local` (replace `taskmaster` with your hostname if changed)
|
|
1279
|
+
|
|
1280
|
+
### Essential commands
|
|
1281
|
+
|
|
1282
|
+
| Command | What it does |
|
|
1283
|
+
|---------|-------------|
|
|
1284
|
+
| `taskmaster update` | Update to the latest version and restart the service |
|
|
1285
|
+
| `taskmaster daemon restart` | Restart the gateway service (picks up code and config changes) |
|
|
1286
|
+
| `taskmaster daemon status` | Check if the gateway service is running |
|
|
1287
|
+
| `taskmaster doctor` | Run health checks and fix common issues automatically |
|
|
1288
|
+
| `taskmaster status` | Show connection status for all channels (WhatsApp, Claude, etc.) |
|
|
1289
|
+
| `taskmaster dashboard` | Open the Control Panel in your browser |
|
|
1290
|
+
|
|
1291
|
+
### Configuration commands
|
|
1292
|
+
|
|
1293
|
+
| Command | What it does |
|
|
1294
|
+
|---------|-------------|
|
|
1295
|
+
| `taskmaster config set <key> <value>` | Change a config setting (e.g., `taskmaster config set gateway.port 19000`) |
|
|
1296
|
+
| `taskmaster config get <key>` | Read a config setting |
|
|
1297
|
+
| `taskmaster config` | Open the interactive config wizard |
|
|
1298
|
+
|
|
1299
|
+
### When to use the CLI instead of the Control Panel
|
|
1300
|
+
|
|
1301
|
+
- **Can't reach the Control Panel** — If the web UI is down, SSH into the device and use CLI commands to restart or update
|
|
1302
|
+
- **Updating from a specific version** — `taskmaster update` works even when the Control Panel can't load
|
|
1303
|
+
- **Changing network settings** — Port and hostname changes require the terminal (see "Changing Network Settings" above)
|
|
1304
|
+
- **Diagnosing problems** — `taskmaster doctor` runs automated health checks that can detect and fix issues the UI can't show
|
|
1305
|
+
- **Scripting and automation** — CLI commands can be combined in scripts for advanced setups
|
|
1306
|
+
|
|
1307
|
+
### Getting help for any command
|
|
1308
|
+
|
|
1309
|
+
Add `--help` to any command to see its options:
|
|
1310
|
+
|
|
1311
|
+
```bash
|
|
1312
|
+
taskmaster update --help
|
|
1313
|
+
taskmaster daemon --help
|
|
1314
|
+
taskmaster config set --help
|
|
1315
|
+
```
|
|
1316
|
+
|
|
1317
|
+
Or run `taskmaster help` to see all available commands.
|
|
1318
|
+
|
|
1319
|
+
---
|
|
1320
|
+
|
|
1270
1321
|
## Uninstalling Taskmaster
|
|
1271
1322
|
|
|
1272
1323
|
### From the Control Panel
|