@humanleg/sandbox 0.0.0-stage → 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/README.md CHANGED
@@ -1,3 +1,11 @@
1
- # Temporary Holding Version
1
+ # @humanleg/sandbox
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Synthetic-only HumanLeg API for local development and the public hosted developer sandbox. It
4
+ never dispatches real humans or moves real funds.
5
+
6
+ In-memory synthetic HumanLeg.ai API for local demos. It moves no funds, stores no identity data and
7
+ must not be exposed as a production service.
8
+
9
+ ```bash
10
+ npx @humanleg/sandbox
11
+ ```
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
package/dist/server.js ADDED
@@ -0,0 +1,360 @@
1
+ #!/usr/bin/env node
2
+ import { createHash, randomUUID } from "node:crypto";
3
+ import { createServer, } from "node:http";
4
+ const port = Number(process.env.PORT ?? 8787);
5
+ const token = process.env.HUMANLEG_AGENT_TOKEN ?? "sandbox-agent-token";
6
+ const settlementEnabled = process.env.HUMANLEG_ENABLE_SETTLEMENT === "true";
7
+ const maxBodyBytes = Number(process.env.HUMANLEG_MAX_BODY_BYTES ?? 64 * 1024);
8
+ const maxObjects = Number(process.env.HUMANLEG_MAX_OBJECTS ?? 500);
9
+ const maxEvents = Number(process.env.HUMANLEG_MAX_EVENTS ?? 2_000);
10
+ const requestsPerMinute = Number(process.env.HUMANLEG_REQUESTS_PER_MINUTE ?? 120);
11
+ const tasks = new Map();
12
+ const quotes = new Map();
13
+ const events = [];
14
+ const requestWindows = new Map();
15
+ function canonicalJson(value) {
16
+ if (value === null || typeof value !== "object")
17
+ return JSON.stringify(value);
18
+ if (Array.isArray(value))
19
+ return `[${value.map(canonicalJson).join(",")}]`;
20
+ const record = value;
21
+ return `{${Object.keys(record)
22
+ .sort()
23
+ .map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`)
24
+ .join(",")}}`;
25
+ }
26
+ function contentSnapshot(task) {
27
+ return {
28
+ taskId: task.id,
29
+ contentVersion: task.contentVersion,
30
+ category: task.category,
31
+ title: task.title,
32
+ instructions: task.instructions,
33
+ evidenceRequirements: task.evidenceRequirements,
34
+ rewardAtomic: task.rewardAtomic,
35
+ displayAudCents: task.displayAudCents,
36
+ deadline: task.deadline,
37
+ country: task.country,
38
+ physicalPresenceRequired: task.physicalPresenceRequired,
39
+ };
40
+ }
41
+ function reviewTask(task) {
42
+ const contentHash = createHash("sha256")
43
+ .update(canonicalJson(contentSnapshot(task)))
44
+ .digest("hex");
45
+ const text = `${task.title}\n${task.instructions}`.toLowerCase();
46
+ const prohibited = [
47
+ [
48
+ /gift[ -]?card|cash transfer|bank transfer|wire transfer/,
49
+ "P_FINANCIAL_VALUE_TRANSFER",
50
+ ],
51
+ [
52
+ /password|one[ -]?time password|\botp\b|seed phrase|private key/,
53
+ "P_CREDENTIAL_THEFT",
54
+ ],
55
+ [/phishing|impersonat(e|ion)|doxx/, "P_FRAUD_OR_HARASSMENT"],
56
+ ];
57
+ const match = prohibited.find(([pattern]) => pattern.test(text));
58
+ return {
59
+ contentHash,
60
+ complianceReview: {
61
+ id: randomUUID(),
62
+ decision: match ? "REJECT" : "APPROVE",
63
+ reasonCode: match?.[1] ?? null,
64
+ contentVersion: task.contentVersion,
65
+ contentHash,
66
+ expiresAt: new Date(Date.now() + 60 * 60 * 1000).toISOString(),
67
+ },
68
+ };
69
+ }
70
+ function json(response, status, body) {
71
+ response.writeHead(status, {
72
+ "content-type": "application/json; charset=utf-8",
73
+ "access-control-allow-origin": "*",
74
+ "cache-control": "no-store",
75
+ "x-content-type-options": "nosniff",
76
+ });
77
+ response.end(JSON.stringify(body));
78
+ }
79
+ function problem(response, status, code, detail) {
80
+ json(response, status, {
81
+ type: `https://humanleg.ai/problems/${code}`,
82
+ title: detail,
83
+ status,
84
+ code,
85
+ detail,
86
+ });
87
+ }
88
+ async function body(request) {
89
+ const chunks = [];
90
+ let bytes = 0;
91
+ for await (const chunk of request) {
92
+ const buffer = Buffer.from(chunk);
93
+ bytes += buffer.byteLength;
94
+ if (bytes > maxBodyBytes)
95
+ throw new Error("Request body exceeds sandbox limit.");
96
+ chunks.push(buffer);
97
+ }
98
+ if (chunks.length === 0)
99
+ return {};
100
+ return JSON.parse(Buffer.concat(chunks).toString("utf8"));
101
+ }
102
+ function requestKey(request) {
103
+ const forwarded = request.headers["x-forwarded-for"];
104
+ if (typeof forwarded === "string")
105
+ return forwarded.split(",")[0].trim();
106
+ return request.socket.remoteAddress ?? "unknown";
107
+ }
108
+ function withinRateLimit(request) {
109
+ const key = requestKey(request);
110
+ const now = Date.now();
111
+ const current = requestWindows.get(key);
112
+ if (!current || current.resetAt <= now) {
113
+ requestWindows.set(key, { count: 1, resetAt: now + 60_000 });
114
+ return true;
115
+ }
116
+ current.count += 1;
117
+ return current.count <= requestsPerMinute;
118
+ }
119
+ function setBounded(map, key, value) {
120
+ map.set(key, value);
121
+ while (map.size > maxObjects) {
122
+ const oldest = map.keys().next().value;
123
+ if (!oldest)
124
+ break;
125
+ map.delete(oldest);
126
+ }
127
+ }
128
+ function authenticate(request, response) {
129
+ if (request.headers.authorization !== `Bearer ${token}`) {
130
+ problem(response, 401, "unauthorized", "A valid sandbox bearer token is required.");
131
+ return false;
132
+ }
133
+ return true;
134
+ }
135
+ function requireIdempotency(request, response) {
136
+ const key = request.headers["idempotency-key"];
137
+ if (typeof key !== "string" || key.length < 8) {
138
+ problem(response, 400, "idempotency_key_required", "Idempotency-Key must be at least 8 characters.");
139
+ return false;
140
+ }
141
+ return true;
142
+ }
143
+ function emit(type, task) {
144
+ events.push({
145
+ id: randomUUID(),
146
+ type,
147
+ taskId: task.id,
148
+ at: new Date().toISOString(),
149
+ });
150
+ if (events.length > maxEvents)
151
+ events.splice(0, events.length - maxEvents);
152
+ }
153
+ const server = createServer(async (request, response) => {
154
+ try {
155
+ const method = request.method ?? "GET";
156
+ const url = new URL(request.url ?? "/", `http://${request.headers.host ?? "localhost"}`);
157
+ if (method === "OPTIONS") {
158
+ response.writeHead(204, {
159
+ "access-control-allow-origin": "*",
160
+ "access-control-allow-headers": "authorization,content-type,idempotency-key",
161
+ "access-control-allow-methods": "GET,POST,PATCH,OPTIONS",
162
+ });
163
+ return response.end();
164
+ }
165
+ if (!withinRateLimit(request)) {
166
+ return problem(response, 429, "rate_limit_exceeded", "Synthetic sandbox request limit exceeded; retry in one minute.");
167
+ }
168
+ if (method === "GET" && url.pathname === "/health") {
169
+ return json(response, 200, { status: "ok", mode: "synthetic-sandbox" });
170
+ }
171
+ if (method === "GET" && url.pathname === "/v1/capabilities") {
172
+ return json(response, 200, {
173
+ name: "HumanLeg.ai public synthetic sandbox",
174
+ mode: "synthetic-sandbox",
175
+ dispatchesRealHumans: false,
176
+ movesRealFunds: false,
177
+ settlementSimulationEnabled: settlementEnabled,
178
+ categories: ["REMOTE_VERIFICATION"],
179
+ tools: ["quote", "create_task", "get_task", "get_compliance_review"],
180
+ constraints: {
181
+ country: "AU",
182
+ physicalPresenceRequired: false,
183
+ minimumSyntheticRewardUsdc: 20,
184
+ },
185
+ documentation: "https://humanleg.ai/developers",
186
+ mcp: "https://humanleg.ai/mcp",
187
+ });
188
+ }
189
+ if (!authenticate(request, response))
190
+ return;
191
+ if (method === "POST" && url.pathname === "/v1/fee-quotes") {
192
+ if (!requireIdempotency(request, response))
193
+ return;
194
+ const input = await body(request);
195
+ const rewardAtomic = Number(input.rewardAtomic);
196
+ const displayAudCents = Number(input.displayAudCents);
197
+ if (!Number.isInteger(rewardAtomic) || rewardAtomic < 20_000_000) {
198
+ return problem(response, 422, "reward_too_low", "Sandbox reward must be at least 20 USDC.");
199
+ }
200
+ const quote = {
201
+ id: randomUUID(),
202
+ rewardAtomic,
203
+ displayAudCents,
204
+ feeAtomic: Math.max(3_000_000, Math.ceil(rewardAtomic * 0.15)),
205
+ expiresAt: new Date(Date.now() + 15 * 60 * 1000).toISOString(),
206
+ };
207
+ setBounded(quotes, String(quote.id), quote);
208
+ return json(response, 201, quote);
209
+ }
210
+ if (method === "POST" && url.pathname === "/v1/tasks") {
211
+ if (!requireIdempotency(request, response))
212
+ return;
213
+ const input = await body(request);
214
+ if (!quotes.has(String(input.feeQuoteId))) {
215
+ return problem(response, 422, "fee_quote_invalid", "Create a current fee quote first.");
216
+ }
217
+ const base = {
218
+ id: randomUUID(),
219
+ contentVersion: 1,
220
+ category: "REMOTE_VERIFICATION",
221
+ title: String(input.title ?? ""),
222
+ instructions: String(input.instructions ?? ""),
223
+ evidenceRequirements: Array.isArray(input.evidenceRequirements)
224
+ ? input.evidenceRequirements.map(String)
225
+ : [],
226
+ rewardAtomic: Number(input.rewardAtomic),
227
+ displayAudCents: Number(input.displayAudCents),
228
+ deadline: String(input.deadline),
229
+ country: "AU",
230
+ physicalPresenceRequired: false,
231
+ feeQuoteId: String(input.feeQuoteId),
232
+ };
233
+ if (base.title.length < 3 ||
234
+ base.instructions.length < 10 ||
235
+ base.evidenceRequirements.length < 1) {
236
+ return problem(response, 422, "task_invalid", "Title, instructions and evidence requirements are required.");
237
+ }
238
+ const review = reviewTask(base);
239
+ const task = { ...base, ...review, status: "DRAFT", funded: false };
240
+ setBounded(tasks, task.id, task);
241
+ emit("task.created", task);
242
+ return json(response, 201, task);
243
+ }
244
+ const taskMatch = url.pathname.match(/^\/v1\/tasks\/([^/]+)(?:\/(.*))?$/);
245
+ if (taskMatch) {
246
+ const id = decodeURIComponent(taskMatch[1] ?? "");
247
+ const action = taskMatch[2];
248
+ const task = tasks.get(id);
249
+ if (!task)
250
+ return problem(response, 404, "task_not_found", "Task not found.");
251
+ if (method === "GET" && !action)
252
+ return json(response, 200, task);
253
+ if (method === "GET" && action === "compliance-review") {
254
+ return json(response, 200, task.complianceReview);
255
+ }
256
+ if (method === "PATCH" && !action) {
257
+ if (!requireIdempotency(request, response))
258
+ return;
259
+ const input = await body(request);
260
+ if (Number(input.expectedVersion) !== task.contentVersion) {
261
+ return problem(response, 409, "version_conflict", "Task version changed; reload before editing.");
262
+ }
263
+ const base = {
264
+ id: task.id,
265
+ contentVersion: task.contentVersion + 1,
266
+ category: task.category,
267
+ title: String(input.title ?? task.title),
268
+ instructions: String(input.instructions ?? task.instructions),
269
+ evidenceRequirements: Array.isArray(input.evidenceRequirements)
270
+ ? input.evidenceRequirements.map(String)
271
+ : task.evidenceRequirements,
272
+ rewardAtomic: task.rewardAtomic,
273
+ displayAudCents: task.displayAudCents,
274
+ deadline: String(input.deadline ?? task.deadline),
275
+ country: task.country,
276
+ physicalPresenceRequired: task.physicalPresenceRequired,
277
+ feeQuoteId: task.feeQuoteId,
278
+ };
279
+ const updated = {
280
+ ...task,
281
+ ...base,
282
+ ...reviewTask(base),
283
+ status: "DRAFT",
284
+ funded: false,
285
+ };
286
+ tasks.set(id, updated);
287
+ emit("task.updated", updated);
288
+ return json(response, 200, updated);
289
+ }
290
+ if (method === "POST" && action === "funding-intents") {
291
+ if (!requireIdempotency(request, response))
292
+ return;
293
+ if (!settlementEnabled) {
294
+ return problem(response, 403, "settlement_disabled", "Funding is not available in the public developer sandbox.");
295
+ }
296
+ if (task.complianceReview.decision !== "APPROVE") {
297
+ return problem(response, 409, "compliance_not_approved", "Rejected tasks cannot be funded.");
298
+ }
299
+ task.funded = true;
300
+ task.status = "FUNDED";
301
+ emit("task.funded", task);
302
+ return json(response, 201, {
303
+ id: randomUUID(),
304
+ taskId: id,
305
+ status: "CONFIRMED",
306
+ simulated: true,
307
+ });
308
+ }
309
+ if (method === "POST" && action === "open") {
310
+ if (!requireIdempotency(request, response))
311
+ return;
312
+ if (!settlementEnabled) {
313
+ return problem(response, 403, "publication_disabled", "Publication is not available in the public developer sandbox.");
314
+ }
315
+ const input = await body(request);
316
+ const review = task.complianceReview;
317
+ if (review.decision !== "APPROVE" ||
318
+ review.contentVersion !== task.contentVersion ||
319
+ review.contentHash !== task.contentHash ||
320
+ Date.parse(review.expiresAt) <= Date.now()) {
321
+ return problem(response, 409, "compliance_not_current", "Exact current approval is required.");
322
+ }
323
+ if (!task.funded)
324
+ return problem(response, 409, "task_not_funded", "Fund the task before publication.");
325
+ if (Number(input.expectedVersion) !== task.contentVersion) {
326
+ return problem(response, 409, "version_conflict", "Task version changed before publication.");
327
+ }
328
+ task.status = "OPEN";
329
+ emit("task.opened", task);
330
+ return json(response, 200, task);
331
+ }
332
+ if (method === "POST" && action === "cancel") {
333
+ if (!requireIdempotency(request, response))
334
+ return;
335
+ task.status = "CANCELLED";
336
+ emit("task.cancelled", task);
337
+ return json(response, 200, task);
338
+ }
339
+ }
340
+ if (method === "GET" && url.pathname === "/v1/events") {
341
+ const after = url.searchParams.get("after");
342
+ const filtered = after
343
+ ? events.filter((event) => String(event.at) > after)
344
+ : events;
345
+ return json(response, 200, { events: filtered });
346
+ }
347
+ return problem(response, 404, "route_not_found", "Route not found.");
348
+ }
349
+ catch (error) {
350
+ if (error instanceof Error &&
351
+ error.message === "Request body exceeds sandbox limit.") {
352
+ return problem(response, 413, "request_too_large", error.message);
353
+ }
354
+ return problem(response, 500, "sandbox_error", error instanceof Error ? error.message : "Unexpected sandbox error.");
355
+ }
356
+ });
357
+ server.listen(port, "127.0.0.1", () => {
358
+ console.log(`HumanLeg synthetic sandbox listening on http://127.0.0.1:${port}`);
359
+ });
360
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,31 @@
1
1
  {
2
2
  "name": "@humanleg/sandbox",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0",
4
+ "description": "Synthetic in-memory HumanLeg.ai sandbox API for local development.",
5
+ "license": "Apache-2.0",
6
+ "type": "module",
7
+ "main": "dist/server.js",
8
+ "files": [
9
+ "dist",
10
+ "README.md"
11
+ ],
12
+ "scripts": {
13
+ "build": "tsc -p tsconfig.json",
14
+ "start": "node dist/server.js"
15
+ },
16
+ "bin": {
17
+ "humanleg-sandbox": "dist/server.js"
18
+ },
19
+ "repository": {
20
+ "type": "git",
21
+ "url": "git+https://github.com/humanleg-ai/humanleg.git",
22
+ "directory": "packages/sandbox"
23
+ },
24
+ "engines": {
25
+ "node": ">=20"
26
+ },
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "provenance": true
30
+ }
31
+ }