@bounty-ai/agent-sdk 0.1.0 → 0.1.2

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,11 +1,11 @@
1
- # @bounty/agent-sdk
1
+ # @bounty-ai/agent-sdk
2
2
 
3
3
  TypeScript SDK for Bounty agents.
4
4
 
5
5
  ## Install
6
6
 
7
7
  ```bash
8
- npm install @bounty/agent-sdk
8
+ npm install @bounty-ai/agent-sdk
9
9
  ```
10
10
 
11
11
  ## Core Concepts
@@ -13,12 +13,13 @@ npm install @bounty/agent-sdk
13
13
  - `v1` assignment contracts (`parseAssignmentV1`, `toAssignmentEnvelopeV1`)
14
14
  - webhook processing with signature verification
15
15
  - framework adapters for Express, Next.js, Fastify, and Hono
16
+ - automatic assignment execution + submission (`createAutoSubmitAssignmentHandler`)
16
17
  - API client for `ackAssignment`, `submitResult`, and `submitError`
17
18
 
18
19
  ## Webhook (framework-agnostic)
19
20
 
20
21
  ```ts
21
- import { createWebhookHandler } from "@bounty/agent-sdk";
22
+ import { createWebhookHandler } from "@bounty-ai/agent-sdk";
22
23
 
23
24
  const handleWebhook = createWebhookHandler({
24
25
  webhookSecret: process.env.AGENT_WEBHOOK_SECRET!,
@@ -37,10 +38,9 @@ const handleWebhook = createWebhookHandler({
37
38
 
38
39
  ```ts
39
40
  import express from "express";
40
- import { createExpressWebhookHandler } from "@bounty/agent-sdk";
41
+ import { createExpressWebhookHandler } from "@bounty-ai/agent-sdk";
41
42
 
42
43
  const app = express();
43
- app.use(express.json());
44
44
 
45
45
  app.post(
46
46
  "/agent/webhook",
@@ -52,12 +52,90 @@ app.post(
52
52
  }),
53
53
  }),
54
54
  );
55
+
56
+ app.use(express.json());
57
+ ```
58
+
59
+ Important: register the webhook route before `express.json()` (or exclude it from JSON parsing) so signature verification can use the original raw request bytes.
60
+
61
+ ## Managed Assignment Runtime
62
+
63
+ Use `createAutoSubmitAssignmentHandler` to remove manual background execution and result submission logic:
64
+
65
+ ```ts
66
+ import {
67
+ createAutoSubmitAssignmentHandler,
68
+ createExpressWebhookHandler,
69
+ } from "@bounty-ai/agent-sdk";
70
+
71
+ const onAssignment = createAutoSubmitAssignmentHandler({
72
+ client: {
73
+ baseUrl: process.env.AGENT_BASE_URL!,
74
+ apiKey: process.env.AGENT_API_KEY!,
75
+ },
76
+ runAssignment: async ({ assignment }) => {
77
+ return {
78
+ assignmentId: assignment.assignment_id,
79
+ progress: "done",
80
+ };
81
+ },
82
+ });
83
+
84
+ app.post(
85
+ "/agent/webhook",
86
+ createExpressWebhookHandler({
87
+ webhookSecret: process.env.AGENT_WEBHOOK_SECRET!,
88
+ onAssignment,
89
+ }),
90
+ );
91
+ ```
92
+
93
+ ## Route By Template Slug
94
+
95
+ Use `createAssignmentSlugRouter` when you want a WorkOS-style handler map by task slug:
96
+
97
+ ```ts
98
+ import {
99
+ createAssignmentSlugRouter,
100
+ createAutoSubmitAssignmentHandler,
101
+ createExpressWebhookHandler,
102
+ } from "@bounty-ai/agent-sdk";
103
+
104
+ const runAssignment = createAssignmentSlugRouter({
105
+ handlers: {
106
+ "company-research-v1": async ({ assignment }) => {
107
+ return solveCompanyResearch(assignment);
108
+ },
109
+ "people-research-v1": async ({ assignment }) => {
110
+ return solvePeopleResearch(assignment);
111
+ },
112
+ },
113
+ fallback: async ({ assignment }) => {
114
+ return solveDefaultAssignment(assignment);
115
+ },
116
+ });
117
+
118
+ const onAssignment = createAutoSubmitAssignmentHandler({
119
+ client: {
120
+ baseUrl: process.env.AGENT_BASE_URL!,
121
+ apiKey: process.env.AGENT_API_KEY!,
122
+ },
123
+ runAssignment,
124
+ });
125
+
126
+ app.post(
127
+ "/agent/webhook",
128
+ createExpressWebhookHandler({
129
+ webhookSecret: process.env.AGENT_WEBHOOK_SECRET!,
130
+ onAssignment,
131
+ }),
132
+ );
55
133
  ```
56
134
 
57
135
  ## Table Result Helper
58
136
 
59
137
  ```ts
60
- import { createTableResult } from "@bounty/agent-sdk";
138
+ import { createTableResult } from "@bounty-ai/agent-sdk";
61
139
 
62
140
  const rows = [
63
141
  {
@@ -76,7 +154,7 @@ const { result } = createTableResult(rows, {
76
154
  ## Client
77
155
 
78
156
  ```ts
79
- import { AgentClient } from "@bounty/agent-sdk";
157
+ import { AgentClient } from "@bounty-ai/agent-sdk";
80
158
 
81
159
  const client = new AgentClient({
82
160
  baseUrl: "https://api.bounty.com",
package/dist/index.cjs CHANGED
@@ -26,15 +26,21 @@ __export(index_exports, {
26
26
  DEFAULT_TIMESTAMP_HEADER: () => DEFAULT_TIMESTAMP_HEADER,
27
27
  SdkError: () => SdkError,
28
28
  computeWebhookSignature: () => computeWebhookSignature,
29
+ createAssignmentSlugRouter: () => createAssignmentSlugRouter,
30
+ createAutoSubmitAssignmentHandler: () => createAutoSubmitAssignmentHandler,
31
+ createEmailDeliveryAction: () => createEmailDeliveryAction,
29
32
  createExpressWebhookHandler: () => createExpressWebhookHandler,
30
33
  createFastifyWebhookHandler: () => createFastifyWebhookHandler,
31
34
  createHonoWebhookHandler: () => createHonoWebhookHandler,
35
+ createIntegrationAction: () => createIntegrationAction,
32
36
  createNextWebhookHandler: () => createNextWebhookHandler,
33
37
  createTablePayload: () => createTablePayload,
34
38
  createTableResult: () => createTableResult,
35
39
  createWebhookHandler: () => createWebhookHandler,
36
40
  executeWebhook: () => executeWebhook,
37
41
  getContractVersion: () => getContractVersion,
42
+ isEmailDeliveryAction: () => isEmailDeliveryAction,
43
+ isIntegrationAction: () => isIntegrationAction,
38
44
  parseAssignmentV1: () => parseAssignmentV1,
39
45
  toAssignmentEnvelopeV1: () => toAssignmentEnvelopeV1,
40
46
  verifyWebhookSignature: () => verifyWebhookSignature
@@ -87,7 +93,8 @@ var AgentClient = class {
87
93
  };
88
94
  await this.post(`/agent/assignments/submit`, {
89
95
  assignment_id: input.assignmentId,
90
- ...payload
96
+ ...payload,
97
+ ...input.actions ? { actions: input.actions } : {}
91
98
  });
92
99
  }
93
100
  async submitError(input) {
@@ -255,7 +262,7 @@ async function executeWebhook(handler, input) {
255
262
  return {
256
263
  status: 400,
257
264
  body: {
258
- status: "timed_out",
265
+ status: "rejected",
259
266
  error: sdkError.message
260
267
  }
261
268
  };
@@ -274,11 +281,46 @@ function normalizeBody(body) {
274
281
  if (typeof body === "string") {
275
282
  return body;
276
283
  }
284
+ if (typeof Buffer !== "undefined" && Buffer.isBuffer(body)) {
285
+ return body.toString("utf8");
286
+ }
277
287
  if (body === void 0 || body === null) {
278
288
  return "";
279
289
  }
280
290
  return JSON.stringify(body);
281
291
  }
292
+ async function readExpressBody(req) {
293
+ if (typeof req.rawBody === "string" || Buffer.isBuffer(req.rawBody)) {
294
+ return normalizeBody(req.rawBody);
295
+ }
296
+ if (req.body !== void 0) {
297
+ if (typeof req.body === "object" && req.body !== null && !Buffer.isBuffer(req.body)) {
298
+ throw new SdkError(
299
+ "Express webhook route must receive raw bytes. Mount webhook routes before express.json() or exclude them from JSON parsing."
300
+ );
301
+ }
302
+ return normalizeBody(req.body);
303
+ }
304
+ if (!req.on) {
305
+ return "";
306
+ }
307
+ return await new Promise((resolve, reject) => {
308
+ const chunks = [];
309
+ req.on?.("data", (chunk) => {
310
+ if (typeof chunk === "string") {
311
+ chunks.push(Buffer.from(chunk, "utf8"));
312
+ } else if (chunk instanceof Uint8Array) {
313
+ chunks.push(chunk);
314
+ }
315
+ });
316
+ req.on?.("end", () => {
317
+ resolve(Buffer.concat(chunks).toString("utf8"));
318
+ });
319
+ req.on?.("error", (error) => {
320
+ reject(error);
321
+ });
322
+ });
323
+ }
282
324
  function toWebhookInput(params) {
283
325
  return {
284
326
  body: params.body,
@@ -286,18 +328,33 @@ function toWebhookInput(params) {
286
328
  ...params.timestamp ? { timestamp: params.timestamp } : {}
287
329
  };
288
330
  }
331
+ function toBadRequest(error) {
332
+ const message = error instanceof Error ? error.message : "Unexpected webhook error";
333
+ return {
334
+ status: 400,
335
+ body: {
336
+ status: "rejected",
337
+ error: message
338
+ }
339
+ };
340
+ }
289
341
  function createExpressWebhookHandler(options) {
290
342
  const handler = createWebhookHandler(options);
291
343
  return async function expressWebhook(req, res) {
292
- const body = req.rawBody ?? normalizeBody(req.body);
293
- const result = await executeWebhook(
294
- handler,
295
- toWebhookInput({
296
- body,
297
- signature: headerValue(req.headers, DEFAULT_SIGNATURE_HEADER),
298
- timestamp: headerValue(req.headers, DEFAULT_TIMESTAMP_HEADER)
299
- })
300
- );
344
+ let result;
345
+ try {
346
+ const body = await readExpressBody(req);
347
+ result = await executeWebhook(
348
+ handler,
349
+ toWebhookInput({
350
+ body,
351
+ signature: headerValue(req.headers, DEFAULT_SIGNATURE_HEADER),
352
+ timestamp: headerValue(req.headers, DEFAULT_TIMESTAMP_HEADER)
353
+ })
354
+ );
355
+ } catch (error) {
356
+ result = toBadRequest(error);
357
+ }
301
358
  res.status(result.status).json(result.body);
302
359
  };
303
360
  }
@@ -350,6 +407,190 @@ function createHonoWebhookHandler(options) {
350
407
  };
351
408
  }
352
409
 
410
+ // src/runtime.ts
411
+ function toMessage(error) {
412
+ if (error instanceof Error && error.message.trim().length > 0) {
413
+ return error.message;
414
+ }
415
+ return "Unknown assignment execution error";
416
+ }
417
+ function defaultAcceptedResponse(assignment) {
418
+ return {
419
+ status: "assigned",
420
+ result: {
421
+ accepted: true,
422
+ assignment_id: assignment.assignment_id
423
+ }
424
+ };
425
+ }
426
+ function defaultSubmitRequest(params) {
427
+ return {
428
+ assignmentId: params.assignment.assignment_id,
429
+ status: "verifying",
430
+ result: params.result,
431
+ ...params.actions && params.actions.length > 0 ? { actions: params.actions } : {}
432
+ };
433
+ }
434
+ function defaultSubmitErrorRequest(params) {
435
+ return {
436
+ assignmentId: params.assignment.assignment_id,
437
+ error: toMessage(params.error)
438
+ };
439
+ }
440
+ function asClient(client) {
441
+ return client instanceof AgentClient ? client : new AgentClient(client);
442
+ }
443
+ function normalizeExecutionOutput(output) {
444
+ if (output && typeof output === "object" && !Array.isArray(output) && "result" in output && output.result && typeof output.result === "object" && !Array.isArray(output.result)) {
445
+ const actions = "actions" in output && Array.isArray(output.actions) ? output.actions : void 0;
446
+ return {
447
+ result: output.result,
448
+ ...actions && actions.length > 0 ? { actions } : {}
449
+ };
450
+ }
451
+ if (!output || typeof output !== "object" || Array.isArray(output)) {
452
+ throw new SdkError("Assignment execution must return an object result");
453
+ }
454
+ return {
455
+ result: output
456
+ };
457
+ }
458
+ function createAssignmentSlugRouter(options) {
459
+ const normalize = options.normalizeSlug ?? ((slug) => slug);
460
+ const normalizedHandlers = /* @__PURE__ */ new Map();
461
+ for (const [slug, handler] of Object.entries(options.handlers)) {
462
+ normalizedHandlers.set(normalize(slug), handler);
463
+ }
464
+ return async ({ assignment }) => {
465
+ const slug = normalize(assignment.template_slug);
466
+ const handler = normalizedHandlers.get(slug) ?? options.fallback;
467
+ if (!handler) {
468
+ throw new SdkError(`No assignment handler registered for template slug "${assignment.template_slug}"`);
469
+ }
470
+ return handler({ assignment });
471
+ };
472
+ }
473
+ function createAutoSubmitAssignmentHandler(options) {
474
+ const client = asClient(options.client);
475
+ const mode = options.executionMode ?? "background";
476
+ const logger = options.logger;
477
+ async function processAssignment(assignment) {
478
+ try {
479
+ const execution = normalizeExecutionOutput(await options.runAssignment({ assignment }));
480
+ const submitRequest = options.createSubmitRequest ? options.createSubmitRequest({
481
+ assignment,
482
+ result: execution.result,
483
+ ...execution.actions ? { actions: execution.actions } : {}
484
+ }) : defaultSubmitRequest({
485
+ assignment,
486
+ result: execution.result,
487
+ ...execution.actions ? { actions: execution.actions } : {}
488
+ });
489
+ await client.submitResult(submitRequest);
490
+ logger?.info?.("[agent-sdk] assignment_submitted", {
491
+ assignmentId: assignment.assignment_id,
492
+ status: submitRequest.status,
493
+ actionCount: submitRequest.actions?.length ?? 0
494
+ });
495
+ } catch (error) {
496
+ const submitErrorRequest = options.createSubmitErrorRequest ? options.createSubmitErrorRequest({ assignment, error }) : defaultSubmitErrorRequest({ assignment, error });
497
+ await client.submitError(submitErrorRequest);
498
+ logger?.error?.("[agent-sdk] assignment_failed", {
499
+ assignmentId: assignment.assignment_id,
500
+ error: submitErrorRequest.error
501
+ });
502
+ }
503
+ }
504
+ return async function onAssignment({ assignment }) {
505
+ const accepted = options.acceptAssignment ? await options.acceptAssignment({ assignment }) : defaultAcceptedResponse(assignment);
506
+ if (accepted.status !== "assigned") {
507
+ return accepted;
508
+ }
509
+ if (mode === "blocking") {
510
+ await processAssignment(assignment);
511
+ } else {
512
+ void processAssignment(assignment).catch((error) => {
513
+ logger?.error?.("[agent-sdk] assignment_background_failure", {
514
+ assignmentId: assignment.assignment_id,
515
+ error: toMessage(error)
516
+ });
517
+ });
518
+ }
519
+ return accepted;
520
+ };
521
+ }
522
+
523
+ // src/integrations.ts
524
+ function normalizeRecipients(recipients, label) {
525
+ if (!Array.isArray(recipients) || recipients.length === 0) {
526
+ throw new Error(`${label} must include at least one recipient`);
527
+ }
528
+ return recipients.map((recipient, index) => {
529
+ if (!recipient || typeof recipient.email !== "string" || recipient.email.trim().length === 0) {
530
+ throw new Error(`${label}[${index}] is missing email`);
531
+ }
532
+ return {
533
+ email: recipient.email.trim(),
534
+ ...typeof recipient.name === "string" && recipient.name.trim().length > 0 ? { name: recipient.name.trim() } : {}
535
+ };
536
+ });
537
+ }
538
+ function createIntegrationAction(input) {
539
+ if (typeof input.type !== "string" || input.type.trim().length === 0) {
540
+ throw new Error("type is required");
541
+ }
542
+ if (typeof input.operation !== "string" || input.operation.trim().length === 0) {
543
+ throw new Error("operation is required");
544
+ }
545
+ if (!input.input || typeof input.input !== "object" || Array.isArray(input.input)) {
546
+ throw new Error("input must be an object");
547
+ }
548
+ return {
549
+ type: input.type.trim(),
550
+ ...typeof input.actionKey === "string" && input.actionKey.trim().length > 0 ? { actionKey: input.actionKey.trim() } : {},
551
+ operation: input.operation.trim(),
552
+ input,
553
+ ...input.metadata ? { metadata: input.metadata } : {}
554
+ };
555
+ }
556
+ function createEmailDeliveryInput(input) {
557
+ if (typeof input.subject !== "string" || input.subject.trim().length === 0) {
558
+ throw new Error("Email subject is required");
559
+ }
560
+ if (typeof input.textBody !== "string" || input.textBody.trim().length === 0) {
561
+ throw new Error("Email textBody is required");
562
+ }
563
+ return {
564
+ to: normalizeRecipients(input.to, "to"),
565
+ ...input.cc && input.cc.length > 0 ? { cc: normalizeRecipients(input.cc, "cc") } : {},
566
+ ...input.bcc && input.bcc.length > 0 ? { bcc: normalizeRecipients(input.bcc, "bcc") } : {},
567
+ subject: input.subject.trim(),
568
+ textBody: input.textBody.trim(),
569
+ ...typeof input.htmlBody === "string" && input.htmlBody.trim().length > 0 ? { htmlBody: input.htmlBody } : {}
570
+ };
571
+ }
572
+ function createEmailDeliveryAction(input) {
573
+ const emailInput = createEmailDeliveryInput(input);
574
+ return {
575
+ ...createIntegrationAction({
576
+ ...input.actionKey ? { actionKey: input.actionKey } : {},
577
+ type: "email",
578
+ operation: input.mode,
579
+ input: emailInput,
580
+ ...input.metadata ? { metadata: input.metadata } : {}
581
+ }),
582
+ type: "email",
583
+ operation: input.mode,
584
+ input: emailInput
585
+ };
586
+ }
587
+ function isIntegrationAction(action) {
588
+ return typeof action.type === "string" && typeof action.operation === "string";
589
+ }
590
+ function isEmailDeliveryAction(action) {
591
+ return action.type === "email" && (action.operation === "draft" || action.operation === "send");
592
+ }
593
+
353
594
  // src/results.ts
354
595
  var DEFAULT_CONTACT_FIELDS = ["email", "phone", "profile_url", "linkedin_url"];
355
596
  function hasValue(value) {
@@ -403,15 +644,21 @@ function createTableResult(rows, options = {}) {
403
644
  DEFAULT_TIMESTAMP_HEADER,
404
645
  SdkError,
405
646
  computeWebhookSignature,
647
+ createAssignmentSlugRouter,
648
+ createAutoSubmitAssignmentHandler,
649
+ createEmailDeliveryAction,
406
650
  createExpressWebhookHandler,
407
651
  createFastifyWebhookHandler,
408
652
  createHonoWebhookHandler,
653
+ createIntegrationAction,
409
654
  createNextWebhookHandler,
410
655
  createTablePayload,
411
656
  createTableResult,
412
657
  createWebhookHandler,
413
658
  executeWebhook,
414
659
  getContractVersion,
660
+ isEmailDeliveryAction,
661
+ isIntegrationAction,
415
662
  parseAssignmentV1,
416
663
  toAssignmentEnvelopeV1,
417
664
  verifyWebhookSignature
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts","../src/signature.ts","../src/contracts.ts","../src/webhook.ts","../src/adapters.ts","../src/results.ts"],"sourcesContent":["export { SdkError, ApiError } from \"./errors\";\nexport { AgentClient, type ClientOptions } from \"./client\";\nexport { computeWebhookSignature, verifyWebhookSignature } from \"./signature\";\nexport {\n DEFAULT_SIGNATURE_HEADER,\n DEFAULT_TIMESTAMP_HEADER,\n createWebhookHandler,\n executeWebhook,\n} from \"./webhook\";\nexport {\n createExpressWebhookHandler,\n createFastifyWebhookHandler,\n createHonoWebhookHandler,\n createNextWebhookHandler,\n} from \"./adapters\";\nexport { getContractVersion, parseAssignmentV1, toAssignmentEnvelopeV1 } from \"./contracts\";\nexport {\n createTablePayload,\n createTableResult,\n type CreateTableResultOptions,\n type TablePayload,\n type TableRow,\n} from \"./results\";\nexport type {\n ApiErrorBody,\n Assignment,\n AssignmentAckRequest,\n AssignmentAckStatus,\n AssignmentEnvelopeV1,\n AssignmentOutcome,\n AssignmentResult,\n AssignmentResultOutput,\n AssignmentResultSchema,\n AssignmentStatus,\n OutcomePayload,\n SdkContractVersion,\n SubmitErrorRequest,\n SubmitResultRequest,\n WebhookInput,\n} from \"./types\";\nexport type { WebhookHandlerOptions, WebhookHttpResponse } from \"./webhook\";\n","import type { ApiErrorBody } from \"./types\";\n\nexport class SdkError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SdkError\";\n }\n}\n\nexport class ApiError extends SdkError {\n readonly status: number;\n readonly code: string | undefined;\n readonly body: ApiErrorBody | null;\n readonly retryable: boolean;\n\n constructor(params: {\n status: number;\n message: string;\n code: string | undefined;\n body: ApiErrorBody | null;\n }) {\n super(params.message);\n this.name = \"ApiError\";\n this.status = params.status;\n this.code = params.code;\n this.body = params.body;\n this.retryable = params.status === 429 || params.status >= 500;\n }\n}\n","import { ApiError } from \"./errors\";\nimport type {\n ApiErrorBody,\n AssignmentAckRequest,\n AssignmentResult,\n SubmitErrorRequest,\n SubmitResultRequest,\n} from \"./types\";\n\nexport type ClientOptions = {\n baseUrl: string;\n apiKey: string;\n fetchImpl?: typeof fetch;\n};\n\nexport class AgentClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(options: ClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.apiKey = options.apiKey;\n this.fetchImpl = options.fetchImpl ?? fetch;\n }\n\n async ackAssignment(assignmentId: string, request: AssignmentAckRequest): Promise<void> {\n await this.post(`/agent/assignments/ack`, {\n assignment_id: assignmentId,\n ...request,\n });\n }\n\n async submitResult(input: SubmitResultRequest): Promise<void> {\n const payload: AssignmentResult = {\n status: input.status,\n ...(input.result ? { result: input.result } : {}),\n ...(input.error ? { error: input.error } : {}),\n };\n\n await this.post(`/agent/assignments/submit`, {\n assignment_id: input.assignmentId,\n ...payload,\n });\n }\n\n async submitError(input: SubmitErrorRequest): Promise<void> {\n await this.submitResult({\n assignmentId: input.assignmentId,\n status: \"timed_out\",\n error: input.error,\n ...(input.details ? { result: { details: input.details } } : {}),\n });\n }\n\n private async post(path: string, body: Record<string, unknown>): Promise<void> {\n const response = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw await this.toApiError(response);\n }\n }\n\n private async toApiError(response: Response): Promise<ApiError> {\n const raw = await response.text();\n let parsed: ApiErrorBody | null = null;\n\n if (raw) {\n try {\n parsed = JSON.parse(raw) as ApiErrorBody;\n } catch {\n parsed = { message: raw };\n }\n }\n\n return new ApiError({\n status: response.status,\n message:\n parsed?.message ?? `API request failed (${response.status}): ${raw || response.statusText}`,\n code: parsed?.code,\n body: parsed,\n });\n }\n}\n","import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { SdkError } from \"./errors\";\n\nexport function computeWebhookSignature(params: {\n webhookSecret: string;\n timestamp: string;\n body: string;\n}) {\n const signedPayload = `${params.timestamp}.${params.body}`;\n const digest = createHmac(\"sha256\", params.webhookSecret)\n .update(signedPayload, \"utf8\")\n .digest(\"hex\");\n return `sha256=${digest}`;\n}\n\nexport function verifyWebhookSignature(params: {\n webhookSecret: string;\n timestamp?: string;\n body: string;\n signature?: string;\n}) {\n if (!params.timestamp || !params.signature) {\n throw new SdkError(\"Missing webhook timestamp or signature\");\n }\n\n const expected = computeWebhookSignature({\n webhookSecret: params.webhookSecret,\n timestamp: params.timestamp,\n body: params.body,\n });\n\n const expectedBuffer = Buffer.from(expected, \"utf8\");\n const actualBuffer = Buffer.from(params.signature, \"utf8\");\n\n if (expectedBuffer.length !== actualBuffer.length) {\n throw new SdkError(\"Invalid webhook signature\");\n }\n\n if (!timingSafeEqual(expectedBuffer, actualBuffer)) {\n throw new SdkError(\"Invalid webhook signature\");\n }\n}\n","import { SdkError } from \"./errors\";\nimport type { Assignment, AssignmentEnvelopeV1, AssignmentResultSchema, SdkContractVersion } from \"./types\";\n\nconst CONTRACT_VERSION: SdkContractVersion = \"v1\";\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\";\n}\n\nfunction parseAssignmentRecord(record: Record<string, unknown>): Assignment {\n if (typeof record.assignment_id !== \"string\") {\n throw new SdkError(\"Missing assignment_id\");\n }\n if (typeof record.template_slug !== \"string\") {\n throw new SdkError(\"Missing template_slug\");\n }\n if (!isObject(record.outcome)) {\n throw new SdkError(\"Missing outcome\");\n }\n if (!isObject(record.result_schema)) {\n throw new SdkError(\"Missing result_schema\");\n }\n\n const outcome = record.outcome;\n if (typeof outcome.title !== \"string\") {\n throw new SdkError(\"Missing outcome.title\");\n }\n if (!isObject(outcome.payload)) {\n throw new SdkError(\"Missing outcome.payload\");\n }\n\n const parsedResultSchema = record.result_schema as AssignmentResultSchema;\n\n return {\n assignment_id: record.assignment_id,\n template_slug: record.template_slug,\n result_schema: parsedResultSchema,\n outcome: {\n title: outcome.title,\n payload: outcome.payload,\n ...(typeof outcome.requested_unit_price_value === \"number\"\n ? { requested_unit_price_value: outcome.requested_unit_price_value }\n : {}),\n ...(typeof outcome.requested_total_price_value === \"number\"\n ? { requested_total_price_value: outcome.requested_total_price_value }\n : {}),\n ...(typeof outcome.currency === \"string\" ? { currency: outcome.currency } : {}),\n ...(typeof outcome.time_window === \"string\" ? { time_window: outcome.time_window } : {}),\n },\n };\n}\n\nexport function parseAssignmentV1(body: string): Assignment {\n let payload: unknown;\n try {\n payload = JSON.parse(body);\n } catch {\n throw new SdkError(\"Invalid JSON payload\");\n }\n\n if (!isObject(payload)) {\n throw new SdkError(\"Invalid assignment payload\");\n }\n\n if (payload.version !== CONTRACT_VERSION) {\n throw new SdkError(\"Unsupported assignment contract version\");\n }\n if (!isObject(payload.assignment)) {\n throw new SdkError(\"Missing assignment envelope payload\");\n }\n\n return parseAssignmentRecord(payload.assignment);\n}\n\nexport function toAssignmentEnvelopeV1(assignment: Assignment): AssignmentEnvelopeV1 {\n return {\n version: CONTRACT_VERSION,\n assignment,\n };\n}\n\nexport function getContractVersion(): SdkContractVersion {\n return CONTRACT_VERSION;\n}\n","import { SdkError } from \"./errors\";\nimport { parseAssignmentV1 } from \"./contracts\";\nimport { verifyWebhookSignature } from \"./signature\";\nimport type { Assignment, AssignmentResult, WebhookInput } from \"./types\";\n\nexport const DEFAULT_SIGNATURE_HEADER = \"x-bounty-signature\";\nexport const DEFAULT_TIMESTAMP_HEADER = \"x-bounty-timestamp\";\n\nexport type WebhookHandlerOptions = {\n webhookSecret: string;\n onAssignment: (params: { assignment: Assignment }) => Promise<AssignmentResult>;\n verifySignature?: boolean;\n};\n\nexport type WebhookHttpResponse = {\n status: number;\n body: AssignmentResult;\n};\n\nexport function createWebhookHandler(options: WebhookHandlerOptions) {\n const shouldVerify = options.verifySignature ?? true;\n\n return async function handleWebhook(input: WebhookInput): Promise<AssignmentResult> {\n if (shouldVerify) {\n verifyWebhookSignature({\n webhookSecret: options.webhookSecret,\n body: input.body,\n ...(input.signature ? { signature: input.signature } : {}),\n ...(input.timestamp ? { timestamp: input.timestamp } : {}),\n });\n }\n\n const assignment = parseAssignmentV1(input.body);\n return options.onAssignment({ assignment });\n };\n}\n\nexport async function executeWebhook(\n handler: ReturnType<typeof createWebhookHandler>,\n input: WebhookInput,\n): Promise<WebhookHttpResponse> {\n try {\n const body = await handler(input);\n return {\n status: 200,\n body,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unexpected webhook error\";\n const sdkError = error instanceof SdkError ? error : new SdkError(message);\n return {\n status: 400,\n body: {\n status: \"timed_out\",\n error: sdkError.message,\n },\n };\n }\n}\n","import {\n DEFAULT_SIGNATURE_HEADER,\n DEFAULT_TIMESTAMP_HEADER,\n createWebhookHandler,\n executeWebhook,\n type WebhookHandlerOptions,\n} from \"./webhook\";\n\nfunction headerValue(headers: Record<string, string | string[] | undefined>, key: string) {\n const value = headers[key] ?? headers[key.toLowerCase()];\n if (Array.isArray(value)) {\n return value[0];\n }\n return value;\n}\n\nfunction normalizeBody(body: unknown): string {\n if (typeof body === \"string\") {\n return body;\n }\n if (body === undefined || body === null) {\n return \"\";\n }\n return JSON.stringify(body);\n}\n\nfunction toWebhookInput(params: {\n body: string;\n signature: string | undefined;\n timestamp: string | undefined;\n}) {\n return {\n body: params.body,\n ...(params.signature ? { signature: params.signature } : {}),\n ...(params.timestamp ? { timestamp: params.timestamp } : {}),\n };\n}\n\nexport function createExpressWebhookHandler(options: WebhookHandlerOptions) {\n const handler = createWebhookHandler(options);\n\n return async function expressWebhook(\n req: {\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n rawBody?: string;\n },\n res: {\n status: (code: number) => { json: (payload: unknown) => void };\n },\n ) {\n const body = req.rawBody ?? normalizeBody(req.body);\n const result = await executeWebhook(\n handler,\n toWebhookInput({\n body,\n signature: headerValue(req.headers, DEFAULT_SIGNATURE_HEADER),\n timestamp: headerValue(req.headers, DEFAULT_TIMESTAMP_HEADER),\n }),\n );\n\n res.status(result.status).json(result.body);\n };\n}\n\nexport function createFastifyWebhookHandler(options: WebhookHandlerOptions) {\n const handler = createWebhookHandler(options);\n\n return async function fastifyWebhook(\n request: {\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n rawBody?: string;\n },\n reply: {\n code: (statusCode: number) => { send: (payload: unknown) => void };\n },\n ) {\n const body = request.rawBody ?? normalizeBody(request.body);\n const result = await executeWebhook(\n handler,\n toWebhookInput({\n body,\n signature: headerValue(request.headers, DEFAULT_SIGNATURE_HEADER),\n timestamp: headerValue(request.headers, DEFAULT_TIMESTAMP_HEADER),\n }),\n );\n\n reply.code(result.status).send(result.body);\n };\n}\n\nexport function createNextWebhookHandler(options: WebhookHandlerOptions) {\n const handler = createWebhookHandler(options);\n\n return async function nextWebhook(request: Request): Promise<Response> {\n const body = await request.text();\n const result = await executeWebhook(\n handler,\n toWebhookInput({\n body,\n signature: request.headers.get(DEFAULT_SIGNATURE_HEADER) ?? undefined,\n timestamp: request.headers.get(DEFAULT_TIMESTAMP_HEADER) ?? undefined,\n }),\n );\n\n return new Response(JSON.stringify(result.body), {\n status: result.status,\n headers: { \"content-type\": \"application/json\" },\n });\n };\n}\n\nexport function createHonoWebhookHandler(options: WebhookHandlerOptions) {\n const handler = createWebhookHandler(options);\n\n return async function honoWebhook(c: {\n req: {\n text: () => Promise<string>;\n header: (name: string) => string | undefined;\n };\n json: (payload: unknown, status?: number) => Response;\n }) {\n const body = await c.req.text();\n const result = await executeWebhook(\n handler,\n toWebhookInput({\n body,\n signature: c.req.header(DEFAULT_SIGNATURE_HEADER),\n timestamp: c.req.header(DEFAULT_TIMESTAMP_HEADER),\n }),\n );\n\n return c.json(result.body, result.status);\n };\n}\n","import type { AssignmentResult } from \"./types\";\n\nexport type TableRow = Record<string, unknown>;\n\nexport type TablePayload = {\n table: {\n columns: string[];\n rows: TableRow[];\n };\n row_count: number;\n rows_unique: boolean;\n has_contact_method: boolean;\n summary?: string;\n};\n\nexport type CreateTableResultOptions = {\n columns?: string[];\n summary?: string;\n contactFields?: string[];\n dedupeBy?: string[];\n};\n\nconst DEFAULT_CONTACT_FIELDS = [\"email\", \"phone\", \"profile_url\", \"linkedin_url\"];\n\nfunction hasValue(value: unknown) {\n if (typeof value === \"string\") {\n return value.trim().length > 0;\n }\n return value !== null && value !== undefined;\n}\n\nfunction deriveColumns(rows: TableRow[]) {\n const ordered: string[] = [];\n for (const row of rows) {\n for (const key of Object.keys(row)) {\n if (!ordered.includes(key)) {\n ordered.push(key);\n }\n }\n }\n return ordered;\n}\n\nfunction makeRowKey(row: TableRow, keys: string[]) {\n const normalized = keys.map((key) => [key, row[key]]);\n return JSON.stringify(normalized);\n}\n\nexport function createTablePayload(\n rows: TableRow[],\n options: CreateTableResultOptions = {},\n): TablePayload {\n const columns = options.columns ?? deriveColumns(rows);\n const dedupeKeys = options.dedupeBy && options.dedupeBy.length > 0 ? options.dedupeBy : columns;\n const contactFields =\n options.contactFields && options.contactFields.length > 0\n ? options.contactFields\n : DEFAULT_CONTACT_FIELDS;\n\n const uniqueCount = new Set(rows.map((row) => makeRowKey(row, dedupeKeys))).size;\n const hasContactMethod = rows.every((row) => contactFields.some((field) => hasValue(row[field])));\n\n return {\n table: {\n columns,\n rows,\n },\n row_count: rows.length,\n rows_unique: uniqueCount === rows.length,\n has_contact_method: hasContactMethod,\n ...(options.summary ? { summary: options.summary } : {}),\n };\n}\n\nexport function createTableResult(\n rows: TableRow[],\n options: CreateTableResultOptions = {},\n): Pick<AssignmentResult, \"result\"> {\n return {\n result: createTablePayload(rows, options),\n };\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts","../src/signature.ts","../src/contracts.ts","../src/webhook.ts","../src/adapters.ts","../src/runtime.ts","../src/integrations.ts","../src/results.ts"],"sourcesContent":["export { SdkError, ApiError } from \"./errors\";\nexport { AgentClient, type ClientOptions } from \"./client\";\nexport { computeWebhookSignature, verifyWebhookSignature } from \"./signature\";\nexport {\n DEFAULT_SIGNATURE_HEADER,\n DEFAULT_TIMESTAMP_HEADER,\n createWebhookHandler,\n executeWebhook,\n} from \"./webhook\";\nexport {\n createExpressWebhookHandler,\n createFastifyWebhookHandler,\n createHonoWebhookHandler,\n createNextWebhookHandler,\n} from \"./adapters\";\nexport {\n createAssignmentSlugRouter,\n createAutoSubmitAssignmentHandler,\n type AssignmentExecutionHandler,\n type AssignmentExecutionResult,\n type AssignmentSlugRouterOptions,\n type AutoSubmitAssignmentHandlerOptions,\n} from \"./runtime\";\nexport { getContractVersion, parseAssignmentV1, toAssignmentEnvelopeV1 } from \"./contracts\";\nexport {\n createEmailDeliveryAction,\n createIntegrationAction,\n isEmailDeliveryAction,\n isIntegrationAction,\n type CreateEmailDeliveryActionInput,\n type CreateIntegrationActionInput,\n} from \"./integrations\";\nexport {\n createTablePayload,\n createTableResult,\n type CreateTableResultOptions,\n type TablePayload,\n type TableRow,\n} from \"./results\";\nexport type {\n ApiErrorBody,\n Assignment,\n AssignmentAction,\n AssignmentAckRequest,\n AssignmentAckStatus,\n AssignmentEnvelopeV1,\n AssignmentOutcome,\n AssignmentResult,\n AssignmentResultOutput,\n AssignmentResultSchema,\n EmailDeliveryAction,\n EmailDeliveryInput,\n EmailOutreachMode,\n EmailRecipient,\n IntegrationAction,\n AssignmentStatus,\n OutcomePayload,\n SdkContractVersion,\n SubmitErrorRequest,\n SubmitResultRequest,\n WebhookInput,\n} from \"./types\";\nexport type { WebhookHandlerOptions, WebhookHttpResponse } from \"./webhook\";\n","import type { ApiErrorBody } from \"./types\";\n\nexport class SdkError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"SdkError\";\n }\n}\n\nexport class ApiError extends SdkError {\n readonly status: number;\n readonly code: string | undefined;\n readonly body: ApiErrorBody | null;\n readonly retryable: boolean;\n\n constructor(params: {\n status: number;\n message: string;\n code: string | undefined;\n body: ApiErrorBody | null;\n }) {\n super(params.message);\n this.name = \"ApiError\";\n this.status = params.status;\n this.code = params.code;\n this.body = params.body;\n this.retryable = params.status === 429 || params.status >= 500;\n }\n}\n","import { ApiError } from \"./errors\";\nimport type {\n ApiErrorBody,\n AssignmentAckRequest,\n AssignmentResult,\n SubmitErrorRequest,\n SubmitResultRequest,\n} from \"./types\";\n\nexport type ClientOptions = {\n baseUrl: string;\n apiKey: string;\n fetchImpl?: typeof fetch;\n};\n\nexport class AgentClient {\n private readonly baseUrl: string;\n private readonly apiKey: string;\n private readonly fetchImpl: typeof fetch;\n\n constructor(options: ClientOptions) {\n this.baseUrl = options.baseUrl.replace(/\\/$/, \"\");\n this.apiKey = options.apiKey;\n this.fetchImpl = options.fetchImpl ?? fetch;\n }\n\n async ackAssignment(assignmentId: string, request: AssignmentAckRequest): Promise<void> {\n await this.post(`/agent/assignments/ack`, {\n assignment_id: assignmentId,\n ...request,\n });\n }\n\n async submitResult(input: SubmitResultRequest): Promise<void> {\n const payload: AssignmentResult = {\n status: input.status,\n ...(input.result ? { result: input.result } : {}),\n ...(input.error ? { error: input.error } : {}),\n };\n\n await this.post(`/agent/assignments/submit`, {\n assignment_id: input.assignmentId,\n ...payload,\n ...(input.actions ? { actions: input.actions } : {}),\n });\n }\n\n async submitError(input: SubmitErrorRequest): Promise<void> {\n await this.submitResult({\n assignmentId: input.assignmentId,\n status: \"timed_out\",\n error: input.error,\n ...(input.details ? { result: { details: input.details } } : {}),\n });\n }\n\n private async post(path: string, body: Record<string, unknown>): Promise<void> {\n const response = await this.fetchImpl(`${this.baseUrl}${path}`, {\n method: \"POST\",\n headers: {\n \"content-type\": \"application/json\",\n authorization: `Bearer ${this.apiKey}`,\n },\n body: JSON.stringify(body),\n });\n\n if (!response.ok) {\n throw await this.toApiError(response);\n }\n }\n\n private async toApiError(response: Response): Promise<ApiError> {\n const raw = await response.text();\n let parsed: ApiErrorBody | null = null;\n\n if (raw) {\n try {\n parsed = JSON.parse(raw) as ApiErrorBody;\n } catch {\n parsed = { message: raw };\n }\n }\n\n return new ApiError({\n status: response.status,\n message:\n parsed?.message ?? `API request failed (${response.status}): ${raw || response.statusText}`,\n code: parsed?.code,\n body: parsed,\n });\n }\n}\n","import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { SdkError } from \"./errors\";\n\nexport function computeWebhookSignature(params: {\n webhookSecret: string;\n timestamp: string;\n body: string;\n}) {\n const signedPayload = `${params.timestamp}.${params.body}`;\n const digest = createHmac(\"sha256\", params.webhookSecret)\n .update(signedPayload, \"utf8\")\n .digest(\"hex\");\n return `sha256=${digest}`;\n}\n\nexport function verifyWebhookSignature(params: {\n webhookSecret: string;\n timestamp?: string;\n body: string;\n signature?: string;\n}) {\n if (!params.timestamp || !params.signature) {\n throw new SdkError(\"Missing webhook timestamp or signature\");\n }\n\n const expected = computeWebhookSignature({\n webhookSecret: params.webhookSecret,\n timestamp: params.timestamp,\n body: params.body,\n });\n\n const expectedBuffer = Buffer.from(expected, \"utf8\");\n const actualBuffer = Buffer.from(params.signature, \"utf8\");\n\n if (expectedBuffer.length !== actualBuffer.length) {\n throw new SdkError(\"Invalid webhook signature\");\n }\n\n if (!timingSafeEqual(expectedBuffer, actualBuffer)) {\n throw new SdkError(\"Invalid webhook signature\");\n }\n}\n","import { SdkError } from \"./errors\";\nimport type { Assignment, AssignmentEnvelopeV1, AssignmentResultSchema, SdkContractVersion } from \"./types\";\n\nconst CONTRACT_VERSION: SdkContractVersion = \"v1\";\n\nfunction isObject(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === \"object\";\n}\n\nfunction parseAssignmentRecord(record: Record<string, unknown>): Assignment {\n if (typeof record.assignment_id !== \"string\") {\n throw new SdkError(\"Missing assignment_id\");\n }\n if (typeof record.template_slug !== \"string\") {\n throw new SdkError(\"Missing template_slug\");\n }\n if (!isObject(record.outcome)) {\n throw new SdkError(\"Missing outcome\");\n }\n if (!isObject(record.result_schema)) {\n throw new SdkError(\"Missing result_schema\");\n }\n\n const outcome = record.outcome;\n if (typeof outcome.title !== \"string\") {\n throw new SdkError(\"Missing outcome.title\");\n }\n if (!isObject(outcome.payload)) {\n throw new SdkError(\"Missing outcome.payload\");\n }\n\n const parsedResultSchema = record.result_schema as AssignmentResultSchema;\n\n return {\n assignment_id: record.assignment_id,\n template_slug: record.template_slug,\n result_schema: parsedResultSchema,\n outcome: {\n title: outcome.title,\n payload: outcome.payload,\n ...(typeof outcome.requested_unit_price_value === \"number\"\n ? { requested_unit_price_value: outcome.requested_unit_price_value }\n : {}),\n ...(typeof outcome.requested_total_price_value === \"number\"\n ? { requested_total_price_value: outcome.requested_total_price_value }\n : {}),\n ...(typeof outcome.currency === \"string\" ? { currency: outcome.currency } : {}),\n ...(typeof outcome.time_window === \"string\" ? { time_window: outcome.time_window } : {}),\n },\n };\n}\n\nexport function parseAssignmentV1(body: string): Assignment {\n let payload: unknown;\n try {\n payload = JSON.parse(body);\n } catch {\n throw new SdkError(\"Invalid JSON payload\");\n }\n\n if (!isObject(payload)) {\n throw new SdkError(\"Invalid assignment payload\");\n }\n\n if (payload.version !== CONTRACT_VERSION) {\n throw new SdkError(\"Unsupported assignment contract version\");\n }\n if (!isObject(payload.assignment)) {\n throw new SdkError(\"Missing assignment envelope payload\");\n }\n\n return parseAssignmentRecord(payload.assignment);\n}\n\nexport function toAssignmentEnvelopeV1(assignment: Assignment): AssignmentEnvelopeV1 {\n return {\n version: CONTRACT_VERSION,\n assignment,\n };\n}\n\nexport function getContractVersion(): SdkContractVersion {\n return CONTRACT_VERSION;\n}\n","import { SdkError } from \"./errors\";\nimport { parseAssignmentV1 } from \"./contracts\";\nimport { verifyWebhookSignature } from \"./signature\";\nimport type { Assignment, AssignmentResult, WebhookInput } from \"./types\";\n\nexport const DEFAULT_SIGNATURE_HEADER = \"x-bounty-signature\";\nexport const DEFAULT_TIMESTAMP_HEADER = \"x-bounty-timestamp\";\n\nexport type WebhookHandlerOptions = {\n webhookSecret: string;\n onAssignment: (params: { assignment: Assignment }) => Promise<AssignmentResult>;\n verifySignature?: boolean;\n};\n\nexport type WebhookHttpResponse = {\n status: number;\n body: AssignmentResult;\n};\n\nexport function createWebhookHandler(options: WebhookHandlerOptions) {\n const shouldVerify = options.verifySignature ?? true;\n\n return async function handleWebhook(input: WebhookInput): Promise<AssignmentResult> {\n if (shouldVerify) {\n verifyWebhookSignature({\n webhookSecret: options.webhookSecret,\n body: input.body,\n ...(input.signature ? { signature: input.signature } : {}),\n ...(input.timestamp ? { timestamp: input.timestamp } : {}),\n });\n }\n\n const assignment = parseAssignmentV1(input.body);\n return options.onAssignment({ assignment });\n };\n}\n\nexport async function executeWebhook(\n handler: ReturnType<typeof createWebhookHandler>,\n input: WebhookInput,\n): Promise<WebhookHttpResponse> {\n try {\n const body = await handler(input);\n return {\n status: 200,\n body,\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : \"Unexpected webhook error\";\n const sdkError = error instanceof SdkError ? error : new SdkError(message);\n return {\n status: 400,\n body: {\n status: \"rejected\",\n error: sdkError.message,\n },\n };\n }\n}\n","import {\n DEFAULT_SIGNATURE_HEADER,\n DEFAULT_TIMESTAMP_HEADER,\n createWebhookHandler,\n executeWebhook,\n type WebhookHttpResponse,\n type WebhookHandlerOptions,\n} from \"./webhook\";\nimport { SdkError } from \"./errors\";\n\nfunction headerValue(headers: Record<string, string | string[] | undefined>, key: string) {\n const value = headers[key] ?? headers[key.toLowerCase()];\n if (Array.isArray(value)) {\n return value[0];\n }\n return value;\n}\n\nfunction normalizeBody(body: unknown): string {\n if (typeof body === \"string\") {\n return body;\n }\n if (typeof Buffer !== \"undefined\" && Buffer.isBuffer(body)) {\n return body.toString(\"utf8\");\n }\n if (body === undefined || body === null) {\n return \"\";\n }\n return JSON.stringify(body);\n}\n\nasync function readExpressBody(req: {\n body?: unknown;\n rawBody?: string | Buffer;\n on?: (event: string, listener: (...args: unknown[]) => void) => void;\n}) {\n if (typeof req.rawBody === \"string\" || Buffer.isBuffer(req.rawBody)) {\n return normalizeBody(req.rawBody);\n }\n\n if (req.body !== undefined) {\n if (typeof req.body === \"object\" && req.body !== null && !Buffer.isBuffer(req.body)) {\n throw new SdkError(\n \"Express webhook route must receive raw bytes. Mount webhook routes before express.json() or exclude them from JSON parsing.\",\n );\n }\n return normalizeBody(req.body);\n }\n\n if (!req.on) {\n return \"\";\n }\n\n return await new Promise<string>((resolve, reject) => {\n const chunks: Uint8Array[] = [];\n req.on?.(\"data\", (chunk: unknown) => {\n if (typeof chunk === \"string\") {\n chunks.push(Buffer.from(chunk, \"utf8\"));\n } else if (chunk instanceof Uint8Array) {\n chunks.push(chunk);\n }\n });\n req.on?.(\"end\", () => {\n resolve(Buffer.concat(chunks).toString(\"utf8\"));\n });\n req.on?.(\"error\", (error: unknown) => {\n reject(error);\n });\n });\n}\n\nfunction toWebhookInput(params: {\n body: string;\n signature: string | undefined;\n timestamp: string | undefined;\n}) {\n return {\n body: params.body,\n ...(params.signature ? { signature: params.signature } : {}),\n ...(params.timestamp ? { timestamp: params.timestamp } : {}),\n };\n}\n\nfunction toBadRequest(error: unknown): WebhookHttpResponse {\n const message = error instanceof Error ? error.message : \"Unexpected webhook error\";\n return {\n status: 400,\n body: {\n status: \"rejected\",\n error: message,\n },\n };\n}\n\nexport function createExpressWebhookHandler(options: WebhookHandlerOptions) {\n const handler = createWebhookHandler(options);\n\n return async function expressWebhook(\n req: {\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n rawBody?: string;\n },\n res: {\n status: (code: number) => { json: (payload: unknown) => void };\n },\n ) {\n let result: WebhookHttpResponse;\n try {\n const body = await readExpressBody(req);\n result = await executeWebhook(\n handler,\n toWebhookInput({\n body,\n signature: headerValue(req.headers, DEFAULT_SIGNATURE_HEADER),\n timestamp: headerValue(req.headers, DEFAULT_TIMESTAMP_HEADER),\n }),\n );\n } catch (error) {\n result = toBadRequest(error);\n }\n\n res.status(result.status).json(result.body);\n };\n}\n\nexport function createFastifyWebhookHandler(options: WebhookHandlerOptions) {\n const handler = createWebhookHandler(options);\n\n return async function fastifyWebhook(\n request: {\n headers: Record<string, string | string[] | undefined>;\n body?: unknown;\n rawBody?: string;\n },\n reply: {\n code: (statusCode: number) => { send: (payload: unknown) => void };\n },\n ) {\n const body = request.rawBody ?? normalizeBody(request.body);\n const result = await executeWebhook(\n handler,\n toWebhookInput({\n body,\n signature: headerValue(request.headers, DEFAULT_SIGNATURE_HEADER),\n timestamp: headerValue(request.headers, DEFAULT_TIMESTAMP_HEADER),\n }),\n );\n\n reply.code(result.status).send(result.body);\n };\n}\n\nexport function createNextWebhookHandler(options: WebhookHandlerOptions) {\n const handler = createWebhookHandler(options);\n\n return async function nextWebhook(request: Request): Promise<Response> {\n const body = await request.text();\n const result = await executeWebhook(\n handler,\n toWebhookInput({\n body,\n signature: request.headers.get(DEFAULT_SIGNATURE_HEADER) ?? undefined,\n timestamp: request.headers.get(DEFAULT_TIMESTAMP_HEADER) ?? undefined,\n }),\n );\n\n return new Response(JSON.stringify(result.body), {\n status: result.status,\n headers: { \"content-type\": \"application/json\" },\n });\n };\n}\n\nexport function createHonoWebhookHandler(options: WebhookHandlerOptions) {\n const handler = createWebhookHandler(options);\n\n return async function honoWebhook(c: {\n req: {\n text: () => Promise<string>;\n header: (name: string) => string | undefined;\n };\n json: (payload: unknown, status?: number) => Response;\n }) {\n const body = await c.req.text();\n const result = await executeWebhook(\n handler,\n toWebhookInput({\n body,\n signature: c.req.header(DEFAULT_SIGNATURE_HEADER),\n timestamp: c.req.header(DEFAULT_TIMESTAMP_HEADER),\n }),\n );\n\n return c.json(result.body, result.status);\n };\n}\n","import { AgentClient, type ClientOptions } from \"./client\";\nimport { SdkError } from \"./errors\";\nimport type {\n Assignment,\n AssignmentAction,\n AssignmentResult,\n SubmitErrorRequest,\n SubmitResultRequest,\n} from \"./types\";\n\ntype RuntimeLogger = {\n info?: (...args: unknown[]) => void;\n error?: (...args: unknown[]) => void;\n};\n\nexport type AutoSubmitAssignmentHandlerOptions = {\n client: AgentClient | ClientOptions;\n runAssignment: (params: { assignment: Assignment }) => Promise<AssignmentExecutionOutput>;\n acceptAssignment?: (params: { assignment: Assignment }) => Promise<AssignmentResult> | AssignmentResult;\n createSubmitRequest?: (params: {\n assignment: Assignment;\n result: Record<string, unknown>;\n actions?: AssignmentAction[];\n }) => SubmitResultRequest;\n createSubmitErrorRequest?: (params: { assignment: Assignment; error: unknown }) => SubmitErrorRequest;\n executionMode?: \"background\" | \"blocking\";\n logger?: RuntimeLogger;\n};\n\nexport type AssignmentExecutionResult = {\n result: Record<string, unknown>;\n actions?: AssignmentAction[];\n};\n\nexport type AssignmentExecutionOutput = Record<string, unknown> | AssignmentExecutionResult;\n\nexport type AssignmentExecutionHandler = (\n params: { assignment: Assignment },\n) => Promise<AssignmentExecutionOutput>;\n\nexport type AssignmentSlugRouterOptions = {\n handlers: Record<string, AssignmentExecutionHandler>;\n fallback?: AssignmentExecutionHandler;\n normalizeSlug?: (slug: string) => string;\n};\n\nfunction toMessage(error: unknown) {\n if (error instanceof Error && error.message.trim().length > 0) {\n return error.message;\n }\n return \"Unknown assignment execution error\";\n}\n\nfunction defaultAcceptedResponse(assignment: Assignment): AssignmentResult {\n return {\n status: \"assigned\",\n result: {\n accepted: true,\n assignment_id: assignment.assignment_id,\n },\n };\n}\n\nfunction defaultSubmitRequest(params: {\n assignment: Assignment;\n result: Record<string, unknown>;\n actions?: AssignmentAction[];\n}): SubmitResultRequest {\n return {\n assignmentId: params.assignment.assignment_id,\n status: \"verifying\",\n result: params.result,\n ...(params.actions && params.actions.length > 0 ? { actions: params.actions } : {}),\n };\n}\n\nfunction defaultSubmitErrorRequest(params: { assignment: Assignment; error: unknown }): SubmitErrorRequest {\n return {\n assignmentId: params.assignment.assignment_id,\n error: toMessage(params.error),\n };\n}\n\nfunction asClient(client: AgentClient | ClientOptions) {\n return client instanceof AgentClient ? client : new AgentClient(client);\n}\n\nfunction normalizeExecutionOutput(output: AssignmentExecutionOutput): AssignmentExecutionResult {\n if (\n output &&\n typeof output === \"object\" &&\n !Array.isArray(output) &&\n \"result\" in output &&\n output.result &&\n typeof output.result === \"object\" &&\n !Array.isArray(output.result)\n ) {\n const actions =\n \"actions\" in output && Array.isArray(output.actions)\n ? (output.actions as AssignmentAction[])\n : undefined;\n return {\n result: output.result as Record<string, unknown>,\n ...(actions && actions.length > 0 ? { actions } : {}),\n };\n }\n\n if (!output || typeof output !== \"object\" || Array.isArray(output)) {\n throw new SdkError(\"Assignment execution must return an object result\");\n }\n\n return {\n result: output as Record<string, unknown>,\n };\n}\n\nexport function createAssignmentSlugRouter(options: AssignmentSlugRouterOptions): AssignmentExecutionHandler {\n const normalize = options.normalizeSlug ?? ((slug: string) => slug);\n const normalizedHandlers = new Map<string, AssignmentExecutionHandler>();\n\n for (const [slug, handler] of Object.entries(options.handlers)) {\n normalizedHandlers.set(normalize(slug), handler);\n }\n\n return async ({ assignment }) => {\n const slug = normalize(assignment.template_slug);\n const handler = normalizedHandlers.get(slug) ?? options.fallback;\n if (!handler) {\n throw new SdkError(`No assignment handler registered for template slug \"${assignment.template_slug}\"`);\n }\n return handler({ assignment });\n };\n}\n\nexport function createAutoSubmitAssignmentHandler(options: AutoSubmitAssignmentHandlerOptions) {\n const client = asClient(options.client);\n const mode = options.executionMode ?? \"background\";\n const logger = options.logger;\n\n async function processAssignment(assignment: Assignment) {\n try {\n const execution = normalizeExecutionOutput(await options.runAssignment({ assignment }));\n const submitRequest = options.createSubmitRequest\n ? options.createSubmitRequest({\n assignment,\n result: execution.result,\n ...(execution.actions ? { actions: execution.actions } : {}),\n })\n : defaultSubmitRequest({\n assignment,\n result: execution.result,\n ...(execution.actions ? { actions: execution.actions } : {}),\n });\n await client.submitResult(submitRequest);\n logger?.info?.(\"[agent-sdk] assignment_submitted\", {\n assignmentId: assignment.assignment_id,\n status: submitRequest.status,\n actionCount: submitRequest.actions?.length ?? 0,\n });\n } catch (error) {\n const submitErrorRequest = options.createSubmitErrorRequest\n ? options.createSubmitErrorRequest({ assignment, error })\n : defaultSubmitErrorRequest({ assignment, error });\n await client.submitError(submitErrorRequest);\n logger?.error?.(\"[agent-sdk] assignment_failed\", {\n assignmentId: assignment.assignment_id,\n error: submitErrorRequest.error,\n });\n }\n }\n\n return async function onAssignment({ assignment }: { assignment: Assignment }): Promise<AssignmentResult> {\n const accepted = options.acceptAssignment\n ? await options.acceptAssignment({ assignment })\n : defaultAcceptedResponse(assignment);\n\n if (accepted.status !== \"assigned\") {\n return accepted;\n }\n\n if (mode === \"blocking\") {\n await processAssignment(assignment);\n } else {\n void processAssignment(assignment).catch((error) => {\n logger?.error?.(\"[agent-sdk] assignment_background_failure\", {\n assignmentId: assignment.assignment_id,\n error: toMessage(error),\n });\n });\n }\n\n return accepted;\n };\n}\n","import type {\n AssignmentAction,\n EmailDeliveryAction,\n EmailDeliveryInput,\n EmailRecipient,\n IntegrationAction,\n} from \"./types\";\n\nexport type CreateIntegrationActionInput = {\n actionKey?: string;\n type: string;\n operation: string;\n input: Record<string, unknown>;\n metadata?: Record<string, unknown>;\n};\n\nexport type CreateEmailDeliveryActionInput = {\n actionKey?: string;\n mode: \"draft\" | \"send\";\n to: EmailRecipient[];\n cc?: EmailRecipient[];\n bcc?: EmailRecipient[];\n subject: string;\n textBody: string;\n htmlBody?: string;\n metadata?: Record<string, unknown>;\n};\n\nfunction normalizeRecipients(recipients: EmailRecipient[], label: string) {\n if (!Array.isArray(recipients) || recipients.length === 0) {\n throw new Error(`${label} must include at least one recipient`);\n }\n return recipients.map((recipient, index) => {\n if (!recipient || typeof recipient.email !== \"string\" || recipient.email.trim().length === 0) {\n throw new Error(`${label}[${index}] is missing email`);\n }\n return {\n email: recipient.email.trim(),\n ...(typeof recipient.name === \"string\" && recipient.name.trim().length > 0\n ? { name: recipient.name.trim() }\n : {}),\n };\n });\n}\n\nexport function createIntegrationAction(input: CreateIntegrationActionInput): IntegrationAction {\n if (typeof input.type !== \"string\" || input.type.trim().length === 0) {\n throw new Error(\"type is required\");\n }\n if (typeof input.operation !== \"string\" || input.operation.trim().length === 0) {\n throw new Error(\"operation is required\");\n }\n if (!input.input || typeof input.input !== \"object\" || Array.isArray(input.input)) {\n throw new Error(\"input must be an object\");\n }\n\n return {\n type: input.type.trim(),\n ...(typeof input.actionKey === \"string\" && input.actionKey.trim().length > 0\n ? { actionKey: input.actionKey.trim() }\n : {}),\n operation: input.operation.trim(),\n input,\n ...(input.metadata ? { metadata: input.metadata } : {}),\n };\n}\n\nfunction createEmailDeliveryInput(input: CreateEmailDeliveryActionInput): EmailDeliveryInput {\n if (typeof input.subject !== \"string\" || input.subject.trim().length === 0) {\n throw new Error(\"Email subject is required\");\n }\n if (typeof input.textBody !== \"string\" || input.textBody.trim().length === 0) {\n throw new Error(\"Email textBody is required\");\n }\n\n return {\n to: normalizeRecipients(input.to, \"to\"),\n ...(input.cc && input.cc.length > 0 ? { cc: normalizeRecipients(input.cc, \"cc\") } : {}),\n ...(input.bcc && input.bcc.length > 0 ? { bcc: normalizeRecipients(input.bcc, \"bcc\") } : {}),\n subject: input.subject.trim(),\n textBody: input.textBody.trim(),\n ...(typeof input.htmlBody === \"string\" && input.htmlBody.trim().length > 0\n ? { htmlBody: input.htmlBody }\n : {}),\n };\n}\n\nexport function createEmailDeliveryAction(\n input: CreateEmailDeliveryActionInput,\n): EmailDeliveryAction {\n const emailInput = createEmailDeliveryInput(input);\n return {\n ...createIntegrationAction({\n ...(input.actionKey ? { actionKey: input.actionKey } : {}),\n type: \"email\",\n operation: input.mode,\n input: emailInput as unknown as Record<string, unknown>,\n ...(input.metadata ? { metadata: input.metadata } : {}),\n }),\n type: \"email\",\n operation: input.mode,\n input: emailInput,\n };\n}\n\nexport function isIntegrationAction(action: AssignmentAction): action is IntegrationAction {\n return typeof action.type === \"string\" && typeof action.operation === \"string\";\n}\n\nexport function isEmailDeliveryAction(action: AssignmentAction): action is EmailDeliveryAction {\n return action.type === \"email\" && (action.operation === \"draft\" || action.operation === \"send\");\n}\n","import type { AssignmentResult } from \"./types\";\n\nexport type TableRow = Record<string, unknown>;\n\nexport type TablePayload = {\n table: {\n columns: string[];\n rows: TableRow[];\n };\n row_count: number;\n rows_unique: boolean;\n has_contact_method: boolean;\n summary?: string;\n};\n\nexport type CreateTableResultOptions = {\n columns?: string[];\n summary?: string;\n contactFields?: string[];\n dedupeBy?: string[];\n};\n\nconst DEFAULT_CONTACT_FIELDS = [\"email\", \"phone\", \"profile_url\", \"linkedin_url\"];\n\nfunction hasValue(value: unknown) {\n if (typeof value === \"string\") {\n return value.trim().length > 0;\n }\n return value !== null && value !== undefined;\n}\n\nfunction deriveColumns(rows: TableRow[]) {\n const ordered: string[] = [];\n for (const row of rows) {\n for (const key of Object.keys(row)) {\n if (!ordered.includes(key)) {\n ordered.push(key);\n }\n }\n }\n return ordered;\n}\n\nfunction makeRowKey(row: TableRow, keys: string[]) {\n const normalized = keys.map((key) => [key, row[key]]);\n return JSON.stringify(normalized);\n}\n\nexport function createTablePayload(\n rows: TableRow[],\n options: CreateTableResultOptions = {},\n): TablePayload {\n const columns = options.columns ?? deriveColumns(rows);\n const dedupeKeys = options.dedupeBy && options.dedupeBy.length > 0 ? options.dedupeBy : columns;\n const contactFields =\n options.contactFields && options.contactFields.length > 0\n ? options.contactFields\n : DEFAULT_CONTACT_FIELDS;\n\n const uniqueCount = new Set(rows.map((row) => makeRowKey(row, dedupeKeys))).size;\n const hasContactMethod = rows.every((row) => contactFields.some((field) => hasValue(row[field])));\n\n return {\n table: {\n columns,\n rows,\n },\n row_count: rows.length,\n rows_unique: uniqueCount === rows.length,\n has_contact_method: hasContactMethod,\n ...(options.summary ? { summary: options.summary } : {}),\n };\n}\n\nexport function createTableResult(\n rows: TableRow[],\n options: CreateTableResultOptions = {},\n): Pick<AssignmentResult, \"result\"> {\n return {\n result: createTablePayload(rows, options),\n };\n}\n"],"mappings":"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","names":[]}