@lobu/worker 3.0.8 → 3.0.12
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/index.d.ts.map +1 -1
- package/dist/index.js +4 -6
- package/dist/index.js.map +1 -1
- package/dist/openclaw/session-context.d.ts.map +1 -1
- package/dist/openclaw/session-context.js +1 -1
- package/dist/openclaw/session-context.js.map +1 -1
- package/package.json +2 -2
- package/USAGE.md +0 -120
- package/docs/custom-base-image.md +0 -88
- package/scripts/worker-entrypoint.sh +0 -184
- package/src/__tests__/audio-provider-suggestions.test.ts +0 -198
- package/src/__tests__/embedded-just-bash-bootstrap.test.ts +0 -39
- package/src/__tests__/embedded-tools.test.ts +0 -558
- package/src/__tests__/instructions.test.ts +0 -59
- package/src/__tests__/memory-flush-runtime.test.ts +0 -138
- package/src/__tests__/memory-flush.test.ts +0 -64
- package/src/__tests__/model-resolver.test.ts +0 -156
- package/src/__tests__/processor.test.ts +0 -225
- package/src/__tests__/setup.ts +0 -109
- package/src/__tests__/sse-client.test.ts +0 -48
- package/src/__tests__/tool-policy.test.ts +0 -269
- package/src/__tests__/worker.test.ts +0 -89
- package/src/core/error-handler.ts +0 -70
- package/src/core/project-scanner.ts +0 -65
- package/src/core/types.ts +0 -125
- package/src/core/url-utils.ts +0 -9
- package/src/core/workspace.ts +0 -138
- package/src/embedded/just-bash-bootstrap.ts +0 -228
- package/src/gateway/gateway-integration.ts +0 -287
- package/src/gateway/message-batcher.ts +0 -128
- package/src/gateway/sse-client.ts +0 -955
- package/src/gateway/types.ts +0 -68
- package/src/index.ts +0 -146
- package/src/instructions/builder.ts +0 -80
- package/src/instructions/providers.ts +0 -27
- package/src/modules/lifecycle.ts +0 -92
- package/src/openclaw/custom-tools.ts +0 -290
- package/src/openclaw/instructions.ts +0 -38
- package/src/openclaw/model-resolver.ts +0 -150
- package/src/openclaw/plugin-loader.ts +0 -427
- package/src/openclaw/processor.ts +0 -216
- package/src/openclaw/session-context.ts +0 -277
- package/src/openclaw/tool-policy.ts +0 -212
- package/src/openclaw/tools.ts +0 -208
- package/src/openclaw/worker.ts +0 -1792
- package/src/server.ts +0 -329
- package/src/shared/audio-provider-suggestions.ts +0 -132
- package/src/shared/processor-utils.ts +0 -33
- package/src/shared/provider-auth-hints.ts +0 -64
- package/src/shared/tool-display-config.ts +0 -75
- package/src/shared/tool-implementations.ts +0 -768
- package/tsconfig.json +0 -21
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, mock, test } from "bun:test";
|
|
2
|
-
import { OpenClawWorker } from "../openclaw/worker";
|
|
3
|
-
import {
|
|
4
|
-
fetchAudioProviderSuggestions,
|
|
5
|
-
normalizeAudioProviderSuggestions,
|
|
6
|
-
} from "../shared/audio-provider-suggestions";
|
|
7
|
-
import { generateAudio } from "../shared/tool-implementations";
|
|
8
|
-
|
|
9
|
-
const originalFetch = globalThis.fetch;
|
|
10
|
-
|
|
11
|
-
function extractText(result: {
|
|
12
|
-
content: Array<{ type: "text"; text: string }>;
|
|
13
|
-
}): string {
|
|
14
|
-
return result.content[0]?.text || "";
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
describe("audio provider suggestions", () => {
|
|
18
|
-
afterEach(() => {
|
|
19
|
-
globalThis.fetch = originalFetch;
|
|
20
|
-
mock.restore();
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
test("normalizes gateway capability providers into prefill IDs + display list", () => {
|
|
24
|
-
const normalized = normalizeAudioProviderSuggestions({
|
|
25
|
-
available: false,
|
|
26
|
-
providers: [
|
|
27
|
-
{ provider: "openai", name: "OpenAI" },
|
|
28
|
-
{ provider: "gemini", name: "Google Gemini" },
|
|
29
|
-
],
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
expect(normalized.available).toBe(false);
|
|
33
|
-
expect(normalized.usedFallback).toBe(false);
|
|
34
|
-
expect(normalized.providerIds).toEqual(["chatgpt", "openai", "gemini"]);
|
|
35
|
-
expect(normalized.providerDisplayList).toBe("OpenAI, Google Gemini");
|
|
36
|
-
});
|
|
37
|
-
|
|
38
|
-
test("falls back safely when capability payload is malformed", () => {
|
|
39
|
-
const normalized = normalizeAudioProviderSuggestions({
|
|
40
|
-
available: true,
|
|
41
|
-
providers: [{ unexpected: "value" }],
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
expect(normalized.available).toBe(true);
|
|
45
|
-
expect(normalized.usedFallback).toBe(true);
|
|
46
|
-
expect(normalized.providerIds).toEqual(["chatgpt", "gemini", "elevenlabs"]);
|
|
47
|
-
expect(normalized.providerDisplayList).toBe("");
|
|
48
|
-
});
|
|
49
|
-
|
|
50
|
-
test("falls back safely when capability fetch fails", async () => {
|
|
51
|
-
globalThis.fetch = mock(async () => {
|
|
52
|
-
throw new Error("network down");
|
|
53
|
-
}) as unknown as typeof fetch;
|
|
54
|
-
|
|
55
|
-
const normalized = await fetchAudioProviderSuggestions({
|
|
56
|
-
gatewayUrl: "http://gateway",
|
|
57
|
-
workerToken: "token",
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
expect(normalized.available).toBeNull();
|
|
61
|
-
expect(normalized.usedFallback).toBe(true);
|
|
62
|
-
expect(normalized.providerIds).toEqual(["chatgpt", "gemini", "elevenlabs"]);
|
|
63
|
-
expect(normalized.providerDisplayList).toBe("");
|
|
64
|
-
});
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
describe("GenerateAudio dynamic provider messaging", () => {
|
|
68
|
-
afterEach(() => {
|
|
69
|
-
globalThis.fetch = originalFetch;
|
|
70
|
-
mock.restore();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
test("uses dynamic capability providers in missing-scope guidance", async () => {
|
|
74
|
-
const fetchMock = mock(
|
|
75
|
-
async (input: RequestInfo | URL, init?: RequestInit) => {
|
|
76
|
-
const url = String(input);
|
|
77
|
-
|
|
78
|
-
if (url.endsWith("/internal/audio/capabilities")) {
|
|
79
|
-
return new Response(
|
|
80
|
-
JSON.stringify({
|
|
81
|
-
available: true,
|
|
82
|
-
providers: [
|
|
83
|
-
{ provider: "openai", name: "OpenAI" },
|
|
84
|
-
{ provider: "gemini", name: "Google Gemini" },
|
|
85
|
-
],
|
|
86
|
-
}),
|
|
87
|
-
{ status: 200, headers: { "Content-Type": "application/json" } }
|
|
88
|
-
);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
if (url.endsWith("/internal/audio/synthesize")) {
|
|
92
|
-
expect(init?.method).toBe("POST");
|
|
93
|
-
return new Response(
|
|
94
|
-
JSON.stringify({
|
|
95
|
-
error: "missing_scope: api.model.audio.request",
|
|
96
|
-
}),
|
|
97
|
-
{ status: 400, headers: { "Content-Type": "application/json" } }
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
throw new Error(`Unexpected URL: ${url}`);
|
|
102
|
-
}
|
|
103
|
-
);
|
|
104
|
-
|
|
105
|
-
globalThis.fetch = fetchMock as unknown as typeof fetch;
|
|
106
|
-
|
|
107
|
-
const result = await generateAudio(
|
|
108
|
-
{
|
|
109
|
-
gatewayUrl: "http://gateway",
|
|
110
|
-
workerToken: "token",
|
|
111
|
-
channelId: "ch",
|
|
112
|
-
conversationId: "conv",
|
|
113
|
-
platform: "telegram",
|
|
114
|
-
},
|
|
115
|
-
{ text: "hello world" }
|
|
116
|
-
);
|
|
117
|
-
|
|
118
|
-
const text = extractText(result as any);
|
|
119
|
-
|
|
120
|
-
expect(text).toContain("OpenAI, Google Gemini");
|
|
121
|
-
expect(text).toContain("Ask an admin");
|
|
122
|
-
});
|
|
123
|
-
});
|
|
124
|
-
|
|
125
|
-
describe("OpenClawWorker audio permission hint", () => {
|
|
126
|
-
afterEach(() => {
|
|
127
|
-
globalThis.fetch = originalFetch;
|
|
128
|
-
mock.restore();
|
|
129
|
-
});
|
|
130
|
-
|
|
131
|
-
test("uses dynamic providers in admin guidance", async () => {
|
|
132
|
-
const fetchMock = mock(async (input: RequestInfo | URL) => {
|
|
133
|
-
const url = String(input);
|
|
134
|
-
if (url.endsWith("/internal/audio/capabilities")) {
|
|
135
|
-
return new Response(
|
|
136
|
-
JSON.stringify({
|
|
137
|
-
available: true,
|
|
138
|
-
providers: [
|
|
139
|
-
{ provider: "openai", name: "OpenAI" },
|
|
140
|
-
{ provider: "elevenlabs", name: "ElevenLabs" },
|
|
141
|
-
],
|
|
142
|
-
}),
|
|
143
|
-
{ status: 200, headers: { "Content-Type": "application/json" } }
|
|
144
|
-
);
|
|
145
|
-
}
|
|
146
|
-
throw new Error(`Unexpected URL: ${url}`);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
globalThis.fetch = fetchMock as unknown as typeof fetch;
|
|
150
|
-
|
|
151
|
-
const hint = await (
|
|
152
|
-
OpenClawWorker.prototype as any
|
|
153
|
-
).maybeBuildAudioPermissionHintMessage(
|
|
154
|
-
"Audio generation failed because token lacks api.model.audio.request",
|
|
155
|
-
"http://gateway",
|
|
156
|
-
"token"
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
expect(hint).toContain("OpenAI, ElevenLabs");
|
|
160
|
-
expect(hint).toContain("Ask an admin");
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
test("falls back to generic provider suggestions when capabilities lookup fails", async () => {
|
|
164
|
-
const fetchMock = mock(async () => {
|
|
165
|
-
throw new Error("capabilities unavailable");
|
|
166
|
-
});
|
|
167
|
-
|
|
168
|
-
globalThis.fetch = fetchMock as unknown as typeof fetch;
|
|
169
|
-
|
|
170
|
-
const hint = await (
|
|
171
|
-
OpenClawWorker.prototype as any
|
|
172
|
-
).maybeBuildAudioPermissionHintMessage(
|
|
173
|
-
"api.model.audio.request is missing",
|
|
174
|
-
"http://gateway",
|
|
175
|
-
"token"
|
|
176
|
-
);
|
|
177
|
-
|
|
178
|
-
expect(hint).toBeNull();
|
|
179
|
-
});
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
describe("OpenClawWorker auth hint messaging", () => {
|
|
183
|
-
test("routes missing provider auth to admin guidance", async () => {
|
|
184
|
-
const hint = await (
|
|
185
|
-
OpenClawWorker.prototype as any
|
|
186
|
-
).maybeBuildAuthHintMessage(
|
|
187
|
-
'Authentication failed for "openai"',
|
|
188
|
-
"openai",
|
|
189
|
-
"gpt-4.1",
|
|
190
|
-
"http://gateway",
|
|
191
|
-
"token"
|
|
192
|
-
);
|
|
193
|
-
|
|
194
|
-
expect(hint).toContain("gpt-4.1");
|
|
195
|
-
expect(hint).toContain("admin");
|
|
196
|
-
expect(hint).toContain("openai");
|
|
197
|
-
});
|
|
198
|
-
});
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { afterEach, describe, expect, test } from "bun:test";
|
|
2
|
-
import fs from "node:fs";
|
|
3
|
-
import os from "node:os";
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
import { buildBinaryInvocation } from "../embedded/just-bash-bootstrap";
|
|
6
|
-
|
|
7
|
-
const tempDirs: string[] = [];
|
|
8
|
-
|
|
9
|
-
afterEach(() => {
|
|
10
|
-
for (const dir of tempDirs.splice(0)) {
|
|
11
|
-
fs.rmSync(dir, { recursive: true, force: true });
|
|
12
|
-
}
|
|
13
|
-
});
|
|
14
|
-
|
|
15
|
-
describe("buildBinaryInvocation", () => {
|
|
16
|
-
test("runs node shebang scripts through node", () => {
|
|
17
|
-
const dir = fs.mkdtempSync(path.join(os.tmpdir(), "lobu-owletto-"));
|
|
18
|
-
tempDirs.push(dir);
|
|
19
|
-
const scriptPath = path.join(dir, "owletto");
|
|
20
|
-
fs.writeFileSync(
|
|
21
|
-
scriptPath,
|
|
22
|
-
"#!/usr/bin/env node\nconsole.log('ok');\n",
|
|
23
|
-
"utf8"
|
|
24
|
-
);
|
|
25
|
-
fs.chmodSync(scriptPath, 0o755);
|
|
26
|
-
|
|
27
|
-
expect(buildBinaryInvocation(scriptPath, ["version"])).toEqual({
|
|
28
|
-
command: "node",
|
|
29
|
-
args: [scriptPath, "version"],
|
|
30
|
-
});
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
test("executes normal binaries directly", () => {
|
|
34
|
-
expect(buildBinaryInvocation("/bin/echo", ["hello"])).toEqual({
|
|
35
|
-
command: "/bin/echo",
|
|
36
|
-
args: ["hello"],
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
});
|