@ct-agents/worker 0.1.8 → 0.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/package.json +7 -6
- package/src/index.ts +388 -377
- package/src/leased-item-runner.ts +85 -0
- package/src/platform-api-path.ts +5 -0
- package/src/resources/database/postgres.ts +36 -37
- package/src/resources/platform-proxy.ts +6 -33
- package/src/resources/text-generation/index.ts +25 -2
- package/src/resources/web-search/tavily.ts +1 -1
- package/src/sandbox/docker.ts +7 -78
- package/src/sandbox/index.ts +1 -0
- package/src/sandbox/local-process.ts +1 -6
- package/src/sandbox/manager.ts +1 -7
- package/src/sandbox/resources-def.ts +1 -20
- package/src/sandbox/resources.ts +1 -13
- package/src/sandbox/types.ts +124 -0
- package/src/worker-http-transport.ts +79 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { platformApiPath } from './platform-api-path.js';
|
|
2
|
+
|
|
3
|
+
export type WorkerHttpTransportInput = {
|
|
4
|
+
baseUrl: string;
|
|
5
|
+
environmentKey: string;
|
|
6
|
+
fetchImpl?: typeof fetch;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export class WorkerHttpError extends Error {
|
|
10
|
+
readonly retryable: boolean;
|
|
11
|
+
|
|
12
|
+
constructor(
|
|
13
|
+
message: string,
|
|
14
|
+
readonly status: number,
|
|
15
|
+
readonly code?: string,
|
|
16
|
+
readonly details?: unknown,
|
|
17
|
+
) {
|
|
18
|
+
super(message);
|
|
19
|
+
this.name = 'WorkerHttpError';
|
|
20
|
+
this.retryable = status === 408 || status === 429 || status === 504 || status >= 500;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Worker HTTP client 共用的认证、URL 与 Envelope Transport。 */
|
|
25
|
+
export class WorkerHttpTransport {
|
|
26
|
+
private readonly baseUrl: string;
|
|
27
|
+
private readonly fetchImpl: typeof fetch;
|
|
28
|
+
|
|
29
|
+
constructor(private readonly input: WorkerHttpTransportInput) {
|
|
30
|
+
this.baseUrl = trimTrailingSlash(input.baseUrl);
|
|
31
|
+
this.fetchImpl = input.fetchImpl ?? fetch;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async requestJson(path: string, init: RequestInit, fallbackMessage: string): Promise<unknown> {
|
|
35
|
+
const headers = new Headers(init.headers);
|
|
36
|
+
headers.set('x-api-key', this.input.environmentKey);
|
|
37
|
+
if (init.body && !headers.has('content-type')) {
|
|
38
|
+
headers.set('content-type', 'application/json');
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
const response = await this.fetchImpl(`${this.baseUrl}${platformApiPath(`/worker${path}`)}`, {
|
|
42
|
+
...init,
|
|
43
|
+
headers,
|
|
44
|
+
});
|
|
45
|
+
return parseApiEnvelope(response, `${fallbackMessage}:${response.status}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function parseApiEnvelope(response: Response, fallbackMessage: string): Promise<unknown> {
|
|
50
|
+
const body = await response.json().catch(() => null) as unknown;
|
|
51
|
+
const envelope = isRecord(body) ? body : null;
|
|
52
|
+
if (!envelope) {
|
|
53
|
+
if (!response.ok) {
|
|
54
|
+
throw new WorkerHttpError(fallbackMessage, response.status);
|
|
55
|
+
}
|
|
56
|
+
throw new Error(fallbackMessage);
|
|
57
|
+
}
|
|
58
|
+
if (!response.ok || envelope.success !== true) {
|
|
59
|
+
const error = isRecord(envelope.error) ? envelope.error : {};
|
|
60
|
+
const message = typeof error.message === 'string'
|
|
61
|
+
? error.message
|
|
62
|
+
: `平台请求失败:${response.status}`;
|
|
63
|
+
throw new WorkerHttpError(
|
|
64
|
+
message,
|
|
65
|
+
response.status,
|
|
66
|
+
typeof error.code === 'string' ? error.code : undefined,
|
|
67
|
+
error.details,
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
return envelope.data;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function trimTrailingSlash(value: string) {
|
|
74
|
+
return value.endsWith('/') ? value.slice(0, -1) : value;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
78
|
+
return Boolean(value) && typeof value === 'object' && !Array.isArray(value);
|
|
79
|
+
}
|