@agrentingai/paperclip-adapter 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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../server/src/index.ts","../../server/src/client.ts","../../server/src/crypto.ts","../../server/src/webhook-handler.ts","../../server/src/polling.ts","../../server/src/balance-monitor.ts","../../server/src/comment-sync.ts","../../server/src/adapter.ts"],"sourcesContent":["export { createServerAdapter } from \"./adapter.js\";\nexport { AgrentingClient } from \"./client.js\";\nexport {\n createWebhookHandler,\n registerTaskMapping,\n unregisterTaskMapping,\n getActiveTaskMappings,\n} from \"./webhook-handler.js\";\nexport type {\n AgrentingWebhookPayload,\n PaperclipApiClient,\n WebhookHandlerOptions,\n} from \"./webhook-handler.js\";\nexport {\n formatAgentResponse,\n forwardCommentToAgrenting,\n processIncomingMessage,\n} from \"./comment-sync.js\";\nexport { pollTaskUntilDone, getWebhookGracePeriodMs, POLL_INTERVALS_MS, MAX_POLLS, getBackoffMs } from \"./polling.js\";\nexport type { PollOptions, PollResult } from \"./polling.js\";\nexport {\n checkBalance,\n canSubmitTask,\n formatLowBalanceComment,\n formatInsufficientBalanceComment,\n} from \"./balance-monitor.js\";\nexport type { BalanceInfo, BalanceCheckOptions } from \"./balance-monitor.js\";\nexport { verifyWebhookSignature } from \"./crypto.js\";\nexport {\n registerWebhook,\n deregisterWebhook,\n hireAgent,\n getAgentProfile,\n sendMessageToTask,\n getTaskMessages,\n reassignTask,\n listCapabilities,\n sendMessageToHiring,\n getHiringMessages,\n retryHiring,\n getHiring,\n listHirings,\n autoSelectAgent,\n executeWithRetry,\n} from \"./adapter.js\";\nexport type {\n AgrentingAdapterConfig,\n AgrentingExecutionResult,\n AgrentingTaskStatus,\n AgrentingTask,\n AgentInfo,\n AgentProfile,\n HireAgentResult,\n SendMessageOptions,\n SendMessageResult,\n ReassignTaskResult,\n PaymentInfo,\n TransactionInfo,\n DiscoverAgentsOptions,\n CreateTaskPaymentOptions,\n Hiring,\n TaskMessage,\n HiringMessage,\n Capability,\n AutoSelectOptions,\n RetryHiringOptions,\n} from \"./types.js\";\n","import type {\n AgrentingAdapterConfig,\n AgrentingTask,\n AgentInfo,\n AgentProfile,\n BalanceInfo,\n HireAgentResult,\n PaymentInfo,\n ReassignTaskResult,\n SendMessageOptions,\n SendMessageResult,\n TransactionInfo,\n DiscoverAgentsOptions,\n CreateTaskPaymentOptions,\n Hiring,\n TaskMessage,\n HiringMessage,\n Capability,\n RetryHiringOptions,\n} from \"./types.js\";\n\nconst DEFAULT_TIMEOUT_MS = 30_000;\nconst MAX_RETRIES = 3;\n\n/**\n * HTTP client for the Agrenting REST API.\n * Wraps fetch with auth headers and base URL handling.\n */\nexport class AgrentingClient {\n private baseUrl: string;\n private apiKey: string;\n\n constructor(config: AgrentingAdapterConfig) {\n this.baseUrl = config.agrentingUrl.replace(/\\/+$/, \"\");\n this.apiKey = config.apiKey;\n }\n\n private headers(): Record<string, string> {\n return {\n \"Content-Type\": \"application/json\",\n \"X-API-Key\": this.apiKey,\n };\n }\n\n private async request<T>(\n method: string,\n path: string,\n body?: unknown\n ): Promise<T> {\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), DEFAULT_TIMEOUT_MS);\n\n try {\n const response = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers: this.headers(),\n body: body ? JSON.stringify(body) : undefined,\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const text = await response.text();\n const shouldRetry = response.status === 429 || response.status >= 500;\n\n if (shouldRetry && attempt < MAX_RETRIES) {\n clearTimeout(timer);\n // Respect Retry-After header on 429, otherwise use exponential backoff\n const retryAfter = response.headers.get(\"Retry-After\");\n let delayMs = Math.min(1000 * 2 ** attempt, 30_000);\n if (retryAfter) {\n // Retry-After can be seconds (integer) or a date string (HTTP-date)\n const seconds = parseInt(retryAfter, 10);\n if (!Number.isNaN(seconds) && seconds > 0) {\n delayMs = seconds * 1000;\n } else {\n // Try parsing as HTTP date\n const dateMs = Date.parse(retryAfter);\n if (!Number.isNaN(dateMs)) {\n delayMs = Math.max(0, dateMs - Date.now());\n }\n }\n }\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n continue;\n }\n\n throw new Error(\n `Agrenting API ${response.status}: ${text.slice(0, 500)}`\n );\n }\n\n const envelope = (await response.json()) as Record<string, unknown>;\n if (Array.isArray(envelope.errors) && envelope.errors.length) {\n throw new Error(`API errors: ${(envelope.errors as string[]).join(\", \")}`);\n }\n return (envelope.data ?? envelope) as T;\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n if (attempt < MAX_RETRIES) {\n clearTimeout(timer);\n const delayMs = Math.min(1000 * 2 ** attempt, 30_000);\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n continue;\n }\n throw lastError;\n } finally {\n clearTimeout(timer);\n }\n }\n\n // Should never reach here, but satisfy the compiler\n throw lastError ?? new Error(\"Unexpected retry loop exit\");\n }\n\n /** Submit a new task to Agrenting.\n * When `maxPrice` is set, the task includes pricing info.\n * Call `createTaskPayment` after this to actually lock escrow funds.\n */\n async createTask(params: {\n providerAgentId: string;\n capability: string;\n input: string;\n /** Max price in USD. If set, the task will have a price for escrow. */\n maxPrice?: string;\n /** Payment type: \"crypto\" | \"escrow\" | \"nowpayments\" */\n paymentType?: string;\n }): Promise<AgrentingTask> {\n const body: Record<string, unknown> = {\n provider_agent_id: params.providerAgentId,\n capability: params.capability,\n input: params.input,\n };\n if (params.maxPrice) {\n body.max_price = params.maxPrice;\n }\n return this.request(\"POST\", \"/api/v1/tasks\", body);\n }\n\n /** Create a payment for an existing task to lock escrow funds.\n * This is the step that actually deducts funds from the client's balance\n * and places them in escrow for the task.\n */\n async createTaskPayment(\n taskId: string,\n options: CreateTaskPaymentOptions = {}\n ): Promise<PaymentInfo> {\n const body: Record<string, unknown> = {\n task_id: taskId,\n };\n if (options.cryptoCurrency) body.crypto_currency = options.cryptoCurrency;\n if (options.paymentType) body.payment_type = options.paymentType;\n return this.request(\"POST\", `/api/v1/tasks/${taskId}/payments`, body);\n }\n\n /** Get payment info for a task */\n async getTaskPayment(taskId: string): Promise<PaymentInfo> {\n return this.request(\"GET\", `/api/v1/tasks/${taskId}/payments`);\n }\n\n /** Get the status and result of a task */\n async getTask(taskId: string): Promise<AgrentingTask> {\n return this.request<AgrentingTask>(\"GET\", `/api/v1/tasks/${taskId}`);\n }\n\n /** Get task timeline events (progress, attempts, status changes) */\n async getTaskTimeline(taskId: string): Promise<{\n events: Array<{\n event_type: string;\n timestamp: string;\n progress_percent?: number;\n progress_message?: string;\n details?: Record<string, unknown>;\n }>;\n }> {\n return this.request(\"GET\", `/api/v1/tasks/${taskId}/timeline`);\n }\n\n /** Get attempt history for a task */\n async getTaskAttempts(taskId: string): Promise<{\n attempts: Array<{\n id: string;\n status: string;\n created_at: string;\n completed_at?: string;\n error_reason?: string;\n }>;\n }> {\n return this.request(\"GET\", `/api/v1/tasks/${taskId}/attempts`);\n }\n\n /** Get current progress of a task */\n async getTaskProgress(taskId: string): Promise<{\n status: string;\n progress_percent: number;\n progress_message?: string;\n updated_at: string;\n }> {\n const task = await this.getTask(taskId);\n return {\n status: task.status,\n progress_percent: task.progress_percent ?? 0,\n progress_message: task.progress_message,\n updated_at: task.updated_at,\n };\n }\n\n /** Register a webhook to receive task lifecycle events.\n * Sends a flat request body matching the backend's expected shape.\n */\n async registerWebhook(params: {\n callbackUrl: string;\n eventTypes?: string[];\n }): Promise<{\n id: string;\n callback_url: string;\n event_types: string[];\n secret_key: string;\n status: string;\n }> {\n return this.request(\"POST\", \"/api/v1/webhooks\", {\n callback_url: params.callbackUrl,\n event_types: params.eventTypes ?? [\n \"task.created\",\n \"task.claimed\",\n \"task.in_progress\",\n \"task.completed\",\n \"task.failed\",\n \"task.cancelled\",\n ],\n });\n }\n\n /** List registered webhooks */\n async listWebhooks(): Promise<\n Array<{\n id: string;\n callback_url: string;\n event_types: string[];\n status: string;\n last_delivery_at?: string;\n failure_count: number;\n }>\n > {\n return this.request(\"GET\", \"/api/v1/webhooks\");\n }\n\n /** Delete a registered webhook */\n async deleteWebhook(webhookId: string): Promise<void> {\n return this.request(\"DELETE\", `/api/v1/webhooks/${webhookId}`);\n }\n\n /** Cancel a task by ID */\n async cancelTask(taskId: string): Promise<AgrentingTask> {\n return this.request(\"POST\", `/api/v1/tasks/${taskId}/cancel`);\n }\n\n /** Discover marketplace agents available for hire.\n * Filters by capability, price range, reputation, and availability.\n */\n async discoverAgents(\n options: DiscoverAgentsOptions = {}\n ): Promise<AgentInfo[]> {\n const params = new URLSearchParams();\n if (options.capability) params.set(\"capability\", options.capability);\n if (options.minPrice) params.set(\"min_price\", options.minPrice.toFixed(2));\n if (options.maxPrice) params.set(\"max_price\", options.maxPrice.toFixed(2));\n if (options.minReputation)\n params.set(\"min_reputation\", String(options.minReputation));\n if (options.sortBy) params.set(\"sort_by\", options.sortBy);\n if (options.limit) params.set(\"limit\", String(options.limit));\n\n return this.request<AgentInfo[]>(\n \"GET\",\n `/api/v1/agents/discover?${params}`\n );\n }\n\n /** Fetch the current platform balance including available, escrowed, and total. */\n async getBalance(): Promise<BalanceInfo> {\n return this.request(\"GET\", \"/api/v1/ledger/balance\");\n }\n\n /** List recent transactions for the authenticated agent. */\n async getTransactions(\n options: { limit?: number; offset?: number; type?: string } = {}\n ): Promise<TransactionInfo[]> {\n const params = new URLSearchParams();\n if (options.limit) params.set(\"limit\", String(options.limit));\n if (options.offset) params.set(\"offset\", String(options.offset));\n if (options.type) params.set(\"type\", options.type);\n\n return this.request<TransactionInfo[]>(\n \"GET\",\n `/api/v1/ledger/transactions?${params}`\n );\n }\n\n /** Deposit funds into the Agrenting ledger. */\n async deposit(params: {\n amount: string;\n currency?: string;\n paymentMethod?: string;\n }): Promise<{\n transaction_id: string;\n status: string;\n deposit_address?: string;\n payment_url?: string;\n }> {\n return this.request(\"POST\", \"/api/v1/ledger/deposit\", {\n amount: params.amount,\n currency: params.currency ?? \"USD\",\n payment_method: params.paymentMethod ?? \"crypto\",\n });\n }\n\n /** Withdraw funds from the Agrenting ledger to an external wallet. */\n async withdraw(params: {\n amount: string;\n currency?: string;\n withdrawalAddressId?: string;\n }): Promise<{\n transaction_id: string;\n status: string;\n }> {\n return this.request(\"POST\", \"/api/v1/ledger/withdraw\", {\n amount: params.amount,\n currency: params.currency ?? \"USD\",\n withdrawal_address_id: params.withdrawalAddressId,\n });\n }\n\n /** Create a payment intent for off-platform payment processing. */\n async createPaymentIntent(params: {\n amount: string;\n currency?: string;\n paymentType?: string;\n }): Promise<{\n id: string;\n status: string;\n payment_url?: string;\n address?: string;\n }> {\n return this.request(\"POST\", \"/api/v1/payments/create-intent\", {\n amount: params.amount,\n currency: params.currency ?? \"USD\",\n payment_type: params.paymentType ?? \"crypto\",\n });\n }\n\n /** Validate connectivity and API key by fetching the account balance */\n async testConnection(): Promise<{ ok: boolean; message: string }> {\n try {\n const data = await this.request<{\n available?: string;\n escrow?: string;\n total?: string;\n currency?: string;\n }>(\"GET\", \"/api/v1/ledger/balance\");\n return {\n ok: true,\n message: `Connected. Balance: ${data.total ?? data.available ?? \"N/A\"} ${data.currency ?? \"USD\"} (Available: ${data.available ?? \"N/A\"})`,\n };\n } catch (err) {\n return {\n ok: false,\n message: err instanceof Error ? err.message : \"Unknown connection error\",\n };\n }\n }\n\n /** Upload a document (e.g. instructions) to Agrenting.\n * Uses the dedicated uploads endpoint which accepts base64-encoded content,\n * separate from the deal-scoped `/api/v1/documents` endpoint.\n */\n async uploadDocument(params: {\n name: string;\n content: string;\n contentType?: string;\n documentType?: string;\n taskId?: string;\n }): Promise<{\n id: string;\n name: string;\n file_url: string;\n content_type: string;\n file_hash: string;\n document_type: string;\n }> {\n const contentBase64 = Buffer.from(params.content).toString(\"base64\");\n return this.request(\"POST\", \"/api/v1/uploads\", {\n name: params.name,\n content: contentBase64,\n content_type: params.contentType ?? \"text/plain\",\n document_type: params.documentType ?? \"instructions\",\n task_id: params.taskId,\n });\n }\n\n /** Get the full profile of an agent by DID.\n * Returns capabilities, pricing tiers, reviews, and availability.\n */\n async getAgentProfile(agentDid: string): Promise<AgentProfile> {\n return this.request(\"GET\", `/api/v1/agents/${encodeURIComponent(agentDid)}`);\n }\n\n /** Hire/bind an agent to your account.\n * Returns adapter config so Paperclip can auto-provision the agent.\n */\n async hireAgent(\n agentDid: string,\n options: { pricingModel?: string } = {}\n ): Promise<HireAgentResult> {\n const body: Record<string, unknown> = {};\n if (options.pricingModel) body.pricing_model = options.pricingModel;\n return this.request(\n \"POST\",\n `/api/v1/agents/${encodeURIComponent(agentDid)}/hire`,\n body\n );\n }\n\n /** Send a message to a running task (mid-task instructions, feedback, or questions).\n * Enables bidirectional communication between the Paperclip user and the remote agent.\n */\n async sendMessageToTask(\n taskId: string,\n options: SendMessageOptions\n ): Promise<SendMessageResult> {\n return this.request(\"POST\", `/api/v1/tasks/${taskId}/messages`, {\n message: options.message,\n message_type: options.messageType ?? \"instruction\",\n });\n }\n\n /** Get messages for a task.\n * GET /api/v1/tasks/:id/messages\n */\n async getTaskMessages(taskId: string): Promise<TaskMessage[]> {\n return this.request<TaskMessage[]>(\n \"GET\",\n `/api/v1/tasks/${taskId}/messages`\n );\n }\n\n /** Reassign a failed or cancelled task to a different agent.\n * If `newAgentDid` is omitted, the platform picks the best available agent.\n */\n async reassignTask(\n taskId: string,\n newAgentDid?: string\n ): Promise<ReassignTaskResult> {\n const body: Record<string, unknown> = {};\n if (newAgentDid) {\n body.new_provider_agent_did = newAgentDid;\n }\n return this.request<ReassignTaskResult>(\n \"POST\",\n `/api/v1/tasks/${taskId}/reassign`,\n body\n );\n }\n\n /** List all available capabilities with descriptions and usage stats.\n * GET /api/v1/capabilities\n */\n async listCapabilities(): Promise<Capability[]> {\n return this.request<Capability[]>(\"GET\", \"/api/v1/capabilities\");\n }\n\n /** Send a message to a hiring for communication with the hired agent.\n * POST /api/v1/hirings/:id/messages\n */\n async sendMessageToHiring(\n hiringId: string,\n content: string\n ): Promise<HiringMessage> {\n if (content.length > 5000) {\n throw new Error(\"Message content exceeds 5000 character limit\");\n }\n return this.request<HiringMessage>(\n \"POST\",\n `/api/v1/hirings/${hiringId}/messages`,\n { content }\n );\n }\n\n /** Get messages for a hiring.\n * GET /api/v1/hirings/:id/messages\n */\n async getHiringMessages(hiringId: string): Promise<HiringMessage[]> {\n return this.request<HiringMessage[]>(\n \"GET\",\n `/api/v1/hirings/${hiringId}/messages`\n );\n }\n\n /** Retry a failed hiring.\n * POST /api/v1/hirings/:id/retry\n */\n async retryHiring(\n hiringId: string,\n options: RetryHiringOptions = {}\n ): Promise<Hiring> {\n const body: Record<string, unknown> = {};\n if (options.reason) {\n body.reason = options.reason;\n }\n return this.request<Hiring>(\n \"POST\",\n `/api/v1/hirings/${hiringId}/retry`,\n body\n );\n }\n\n /** Get a hiring by ID.\n * GET /api/v1/hirings/:id\n */\n async getHiring(hiringId: string): Promise<Hiring> {\n return this.request<Hiring>(\"GET\", `/api/v1/hirings/${hiringId}`);\n }\n\n /** List hirings for the authenticated agent.\n * GET /api/v1/hirings\n */\n async listHirings(options: {\n status?: string;\n limit?: number;\n offset?: number;\n } = {}): Promise<Hiring[]> {\n const params = new URLSearchParams();\n if (options.status) params.set(\"status\", options.status);\n if (options.limit) params.set(\"limit\", String(options.limit));\n if (options.offset) params.set(\"offset\", String(options.offset));\n const query = params.toString() ? `?${params}` : \"\";\n return this.request<Hiring[]>(\"GET\", `/api/v1/hirings${query}`);\n }\n\n /** List agents filtered by capability for auto-select.\n * GET /api/v1/agents?capability=X\n */\n async listAgentsByCapability(capability: string): Promise<AgentProfile[]> {\n return this.request<AgentProfile[]>(\n \"GET\",\n `/api/v1/agents?capability=${encodeURIComponent(capability)}`\n );\n }\n}\n","/**\n * Shared cryptographic utilities for the Agrenting adapter.\n */\n\n/**\n * Verify an HMAC-SHA256 signature against a raw request body.\n * Uses constant-time comparison to prevent timing attacks.\n */\nexport async function verifyWebhookSignature(\n rawBody: string,\n signature: string,\n secret: string\n): Promise<boolean> {\n const crypto = await import(\"crypto\");\n const expected = crypto\n .createHmac(\"sha256\", secret)\n .update(rawBody)\n .digest(\"base64\");\n const sigBuf = Buffer.from(signature);\n const expectedBuf = Buffer.from(expected);\n if (sigBuf.byteLength !== expectedBuf.byteLength) {\n return false;\n }\n return crypto.timingSafeEqual(sigBuf, expectedBuf);\n}\n","/**\n * Paperclip-side webhook handler for Agrenting task events.\n *\n * This module provides:\n * - An HTTP request handler that processes incoming webhook payloads from Agrenting\n * - Task ID to Paperclip issue ID mapping registry\n * - Automatic issue status updates and comment posting on task events\n *\n * Usage: Paperclip mounts this handler at `POST /api/webhooks/agrenting/:companyId`.\n * The handler receives raw body, headers, and a Paperclip API client to update issues.\n */\n\nimport type { IncomingHttpHeaders } from \"http\";\nimport type { AgrentingAdapterConfig } from \"./types.js\";\nimport { verifyWebhookSignature } from \"./crypto.js\";\n\n// ---------------------------------------------------------------------------\n// Task → Issue mapping registry\n// ---------------------------------------------------------------------------\n\ninterface TaskMapping {\n issueId: string;\n companyId: string;\n config: AgrentingAdapterConfig;\n startedAt: number;\n status: string;\n}\n\nconst taskRegistry = new Map<string, TaskMapping>();\n\nconst TASK_REGISTRY_TTL_MS = 2 * 60 * 60 * 1000; // 2h — max age before cleanup\nconst TASK_REGISTRY_CLEANUP_INTERVAL_MS = 60_000; // 60s sweep interval\nlet registryCleanupTimer: ReturnType<typeof setInterval> | null = null;\n\n/**\n * Sweep taskRegistry for entries older than the TTL.\n * Called periodically to bound memory growth if terminal events are lost.\n */\nfunction sweepStaleRegistryEntries(): void {\n const now = Date.now();\n for (const [id, entry] of taskRegistry) {\n if (now - entry.startedAt > TASK_REGISTRY_TTL_MS) {\n taskRegistry.delete(id);\n }\n }\n}\n\n/**\n * Start the periodic registry cleanup timer.\n * Safe to call multiple times — only one timer runs at a time.\n */\nexport function startRegistryCleanup(): void {\n if (registryCleanupTimer) return;\n registryCleanupTimer = setInterval(sweepStaleRegistryEntries, TASK_REGISTRY_CLEANUP_INTERVAL_MS);\n registryCleanupTimer.unref();\n}\n\n/**\n * Stop the periodic registry cleanup timer.\n */\nexport function stopRegistryCleanup(): void {\n if (registryCleanupTimer) {\n clearInterval(registryCleanupTimer);\n registryCleanupTimer = null;\n }\n}\n\n/**\n * Register a mapping between an Agrenting task ID and a Paperclip issue.\n * Call this before executing a task so the webhook handler knows which issue to update.\n */\nexport function registerTaskMapping(\n taskId: string,\n issueId: string,\n companyId: string,\n config: AgrentingAdapterConfig\n): void {\n taskRegistry.set(taskId, {\n issueId,\n companyId,\n config,\n startedAt: Date.now(),\n status: \"pending\",\n });\n}\n\n/**\n * Remove a task mapping from the registry.\n */\nexport function unregisterTaskMapping(taskId: string): void {\n taskRegistry.delete(taskId);\n}\n\n/**\n * Get all active task mappings.\n */\nexport function getActiveTaskMappings(): ReadonlyMap<string, TaskMapping> {\n return taskRegistry;\n}\n\n// ---------------------------------------------------------------------------\n// Webhook payload types\n// ---------------------------------------------------------------------------\n\nexport interface AgrentingWebhookPayload {\n task_id: string;\n status: string;\n output?: string;\n error_reason?: string;\n progress_percent?: number;\n progress_message?: string;\n completed_at?: string;\n created_at?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Paperclip API client interface\n// ---------------------------------------------------------------------------\n\nexport interface PaperclipApiClient {\n /** Update an issue's status and optionally post a comment */\n updateIssue(issueId: string, body: {\n status?: string;\n comment?: string;\n }): Promise<void>;\n\n /** Post a comment on an issue without changing status */\n postComment(issueId: string, body: string): Promise<void>;\n}\n\n// ---------------------------------------------------------------------------\n// Event handlers\n// ---------------------------------------------------------------------------\n\ninterface EventHandlerContext {\n api: PaperclipApiClient;\n mapping: TaskMapping;\n payload: AgrentingWebhookPayload;\n}\n\nconst eventHandlers: Record<\n string,\n (ctx: EventHandlerContext) => Promise<void>\n> = {\n \"task.created\": async (ctx) => {\n ctx.mapping.status = \"pending\";\n await ctx.api.postComment(\n ctx.mapping.issueId,\n `**Agrenting task created** — Task \\`${ctx.payload.task_id}\\` submitted and awaiting claim.`\n );\n },\n\n \"task.claimed\": async (ctx) => {\n ctx.mapping.status = \"claimed\";\n await ctx.api.postComment(\n ctx.mapping.issueId,\n `**Agrenting task claimed** — An agent has picked up the task and is preparing to work.`\n );\n },\n\n \"task.in_progress\": async (ctx) => {\n ctx.mapping.status = \"in_progress\";\n const progress = ctx.payload.progress_percent\n ? ` (${ctx.payload.progress_percent}%)`\n : \"\";\n const message = ctx.payload.progress_message\n ? ` — ${ctx.payload.progress_message}`\n : \"\";\n await ctx.api.postComment(\n ctx.mapping.issueId,\n `**Task in progress**${progress}${message}`\n );\n },\n\n \"task.completed\": async (ctx) => {\n ctx.mapping.status = \"completed\";\n const duration = ((Date.now() - ctx.mapping.startedAt) / 1000).toFixed(1);\n await ctx.api.updateIssue(ctx.mapping.issueId, {\n status: \"done\",\n comment: `**Agrenting task completed** — Task \\`${ctx.payload.task_id}\\` finished in ${duration}s.${\n ctx.payload.output ? `\\n\\n### Output\\n\\n${ctx.payload.output}` : \"\"\n }`,\n });\n unregisterTaskMapping(ctx.payload.task_id);\n },\n\n \"task.failed\": async (ctx) => {\n ctx.mapping.status = \"failed\";\n await ctx.api.updateIssue(ctx.mapping.issueId, {\n status: \"blocked\",\n comment: `**Agrenting task failed** — Task \\`${ctx.payload.task_id}\\` encountered an error.\\n\\n**Error:** ${ctx.payload.error_reason ?? \"No error reason provided.\"}`,\n });\n unregisterTaskMapping(ctx.payload.task_id);\n },\n\n \"task.cancelled\": async (ctx) => {\n ctx.mapping.status = \"cancelled\";\n await ctx.api.updateIssue(ctx.mapping.issueId, {\n status: \"cancelled\",\n comment: `**Agrenting task cancelled** — Task \\`${ctx.payload.task_id}\\` was cancelled.`,\n });\n unregisterTaskMapping(ctx.payload.task_id);\n },\n};\n\n// ---------------------------------------------------------------------------\n// Webhook handler factory\n// ---------------------------------------------------------------------------\n\nexport interface WebhookHandlerOptions {\n /** Secret used to verify HMAC signatures */\n webhookSecret: string;\n /** Paperclip API client for updating issues */\n api: PaperclipApiClient;\n /** Optional: handle unknown event types */\n onUnknownEvent?: (event: string, payload: AgrentingWebhookPayload) => void;\n}\n\n/**\n * Create a webhook handler function suitable for mounting in an HTTP server.\n *\n * The returned handler expects `(rawBody, headers)` and returns a Promise\n * resolving to `{ status, body, headers }` for the HTTP response.\n *\n * This design is framework-agnostic: Paperclip can wrap it in Express,\n * Fastify, or a raw Node.js http server.\n */\nexport function createWebhookHandler(options: WebhookHandlerOptions) {\n startRegistryCleanup();\n return async function handleWebhookRequest(\n rawBody: string,\n headers: IncomingHttpHeaders\n ): Promise<{ status: number; body: string; headers?: Record<string, string> }> {\n const signature =\n (headers[\"x-webhook-signature\"] as string) ??\n (headers[\"X-Webhook-Signature\"] as string) ??\n \"\";\n const eventType =\n (headers[\"x-webhook-event\"] as string) ??\n (headers[\"X-Webhook-Event\"] as string) ??\n \"\";\n\n // Parse payload\n let payload: AgrentingWebhookPayload;\n try {\n payload = JSON.parse(rawBody);\n } catch {\n return { status: 400, body: \"Invalid JSON\" };\n }\n\n // Verify signature\n const valid = await verifyWebhookSignature(\n rawBody,\n signature,\n options.webhookSecret\n );\n if (!valid) {\n return { status: 401, body: \"Invalid signature\" };\n }\n\n // Look up task mapping\n const taskId = payload.task_id;\n if (!taskId) {\n return { status: 400, body: \"Missing task_id in payload\" };\n }\n\n const mapping = taskRegistry.get(taskId);\n if (!mapping) {\n // Webhook received but no active mapping — task may have been handled\n // by the in-process listener already, or the mapping was cleaned up.\n return { status: 200, body: \"OK (no active mapping)\" };\n }\n\n // Dispatch to event handler\n const handler = eventHandlers[eventType];\n if (handler) {\n try {\n await handler({ api: options.api, mapping, payload });\n } catch (err) {\n console.error(\"[adapter-agrenting] Webhook handler error:\", err);\n return {\n status: 500,\n body: \"Internal error\",\n };\n }\n } else {\n options.onUnknownEvent?.(eventType, payload);\n }\n\n return { status: 200, body: \"OK\" };\n };\n}\n","/**\n * Fallback polling logic for Agrenting task status.\n *\n * Used when webhooks are delayed or fail to deliver.\n * Polls with exponential backoff: 10s → 30s → 60s → 120s (max 10 polls).\n */\n\nimport { AgrentingClient } from \"./client.js\";\nimport type {\n AgrentingAdapterConfig,\n AgrentingExecutionResult,\n AgrentingTask,\n} from \"./types.js\";\n\n/** Poll intervals in milliseconds (exponential backoff) — shared across polling modes */\nexport const POLL_INTERVALS_MS = [10_000, 30_000, 60_000, 120_000];\nexport const MAX_POLLS = 10;\n\n/** Compute the backoff duration for a given poll attempt (0-indexed). */\nexport function getBackoffMs(attempt: number): number {\n const index = Math.min(attempt, POLL_INTERVALS_MS.length - 1);\n return POLL_INTERVALS_MS[index];\n}\n\nexport interface PollOptions {\n config: AgrentingAdapterConfig;\n taskId: string;\n /** Deadline in ms (Date.now() + timeoutMs) */\n deadline: number;\n /** Optional callback fired on each poll cycle with the current task state */\n onStatusUpdate?: (task: AgrentingTask, pollAttempt: number) => void;\n /** Starting poll attempt (useful for resuming after a webhook delay) */\n startAttempt?: number;\n /** AbortSignal to cancel polling early (e.g., when a webhook resolves first) */\n signal?: AbortSignal;\n}\n\nexport interface PollResult {\n /** Final execution result */\n result: AgrentingExecutionResult;\n /** Number of polls performed */\n pollCount: number;\n /** Whether the result came from polling (true) or was already resolved */\n viaPolling: boolean;\n}\n\n/**\n * Poll the Agrenting task API with exponential backoff until the task\n * reaches a terminal state or the deadline is reached.\n */\nexport async function pollTaskUntilDone(\n options: PollOptions\n): Promise<PollResult> {\n const client = new AgrentingClient(options.config);\n let pollAttempt = options.startAttempt ?? 0;\n const startTime = Date.now();\n\n while (pollAttempt < MAX_POLLS) {\n // Check if polling was aborted (e.g., webhook resolved first)\n if (options.signal?.aborted) {\n return {\n result: {\n success: false,\n error: \"Polling aborted\",\n taskId: options.taskId,\n durationMs: Date.now() - startTime,\n },\n pollCount: pollAttempt,\n viaPolling: true,\n };\n }\n\n const now = Date.now();\n if (now >= options.deadline) {\n return {\n result: {\n success: false,\n error: `Task timed out after ${options.config.timeoutSec ?? 600}s`,\n taskId: options.taskId,\n durationMs: now - startTime,\n },\n pollCount: pollAttempt,\n viaPolling: true,\n };\n }\n\n // Wait for the next poll interval (respects abort signal).\n // Skip the wait on the first iteration so the first poll is immediate.\n if (pollAttempt > 0) {\n const waitMs = getBackoffMs(pollAttempt);\n await new Promise<void>((resolve) => {\n const timer = setTimeout(resolve, waitMs);\n if (options.signal) {\n options.signal.addEventListener(\"abort\", () => {\n clearTimeout(timer);\n resolve();\n }, { once: true });\n }\n });\n }\n\n const task = await client.getTask(options.taskId);\n pollAttempt++;\n\n options.onStatusUpdate?.(task, pollAttempt);\n\n if (task.status === \"completed\") {\n return {\n result: {\n success: true,\n output: task.output,\n taskId: options.taskId,\n durationMs: Date.now() - startTime,\n },\n pollCount: pollAttempt,\n viaPolling: true,\n };\n }\n\n if (task.status === \"failed\") {\n return {\n result: {\n success: false,\n error: task.error_reason ?? \"Task failed with no reason provided\",\n taskId: options.taskId,\n durationMs: Date.now() - startTime,\n },\n pollCount: pollAttempt,\n viaPolling: true,\n };\n }\n\n if (task.status === \"cancelled\") {\n return {\n result: {\n success: false,\n error: \"Task was cancelled\",\n taskId: options.taskId,\n durationMs: Date.now() - startTime,\n },\n pollCount: pollAttempt,\n viaPolling: true,\n };\n }\n }\n\n // Max polls reached without terminal state — do one final check\n const finalTask = await client.getTask(options.taskId);\n if (finalTask.status === \"completed\") {\n return {\n result: {\n success: true,\n output: finalTask.output,\n taskId: options.taskId,\n durationMs: Date.now() - startTime,\n },\n pollCount: pollAttempt + 1,\n viaPolling: true,\n };\n }\n\n return {\n result: {\n success: false,\n error: `Task did not complete after ${pollAttempt} polls (max ${MAX_POLLS})`,\n taskId: options.taskId,\n durationMs: Date.now() - startTime,\n },\n pollCount: pollAttempt,\n viaPolling: true,\n };\n}\n\n/**\n * Calculate when to activate fallback polling.\n * Returns the number of ms to wait before switching from webhook\n * wait mode to polling mode.\n */\nexport function getWebhookGracePeriodMs(config: AgrentingAdapterConfig): number {\n // Default: 60 seconds. If the timeout is very short, use a fraction of it.\n const timeoutMs = (config.timeoutSec ?? 600) * 1000;\n return Math.min(60_000, timeoutMs * 0.1);\n}\n","/**\n * Balance monitoring for the Agrenting adapter.\n *\n * Monitors the platform balance via `GET /api/v1/ledger/balance`\n * and provides low-balance warnings and pre-submission checks.\n */\n\nimport { AgrentingClient } from \"./client.js\";\nimport type { AgrentingAdapterConfig } from \"./types.js\";\n\nexport interface BalanceInfo {\n available: number;\n escrow: number;\n total: number;\n currency: string;\n isLow: boolean;\n isInsufficient: boolean;\n}\n\nexport interface BalanceCheckOptions {\n config: AgrentingAdapterConfig;\n /** Low balance threshold in USD (default: $10) */\n lowBalanceThresholdUsd?: number;\n /** Minimum balance required to submit a task in USD (default: $1) */\n minSubmissionBalanceUsd?: number;\n}\n\n/**\n * Fetch the current platform balance and evaluate thresholds.\n * The server returns { available, escrow, total } — we use `available`\n * for threshold checks since escrowed funds are already committed.\n */\nexport async function checkBalance(\n options: BalanceCheckOptions\n): Promise<BalanceInfo> {\n const client = new AgrentingClient(options.config);\n const lowThreshold = options.lowBalanceThresholdUsd ?? 10;\n const minSubmission = options.minSubmissionBalanceUsd ?? 1;\n\n try {\n const raw = await client.getBalance();\n const available = parseFloat(raw.available);\n const escrow = parseFloat(raw.escrow);\n const total = parseFloat(raw.total);\n\n const anyNaN = Number.isNaN(available) || Number.isNaN(escrow) || Number.isNaN(total);\n if (anyNaN) {\n return {\n available: 0,\n escrow: 0,\n total: 0,\n currency: raw.currency ?? \"USD\",\n isLow: true,\n isInsufficient: true,\n };\n }\n\n return {\n available,\n escrow,\n total,\n currency: raw.currency ?? \"USD\",\n isLow: available < lowThreshold,\n isInsufficient: available < minSubmission,\n };\n } catch {\n // If we can't fetch balance, assume insufficient to avoid failed submissions\n return {\n available: 0,\n escrow: 0,\n total: 0,\n currency: \"USD\",\n isLow: true,\n isInsufficient: true,\n };\n }\n}\n\n/**\n * Pre-submission balance check.\n * Returns { ok: true } if sufficient, or { ok: false, reason } if not.\n */\nexport async function canSubmitTask(\n options: BalanceCheckOptions\n): Promise<{ ok: true } | { ok: false; reason: string }> {\n const balanceInfo = await checkBalance(options);\n\n if (balanceInfo.isInsufficient) {\n return {\n ok: false,\n reason: `Insufficient balance: ${formatUsd(balanceInfo.available)}. Minimum required: ${formatUsd(options.minSubmissionBalanceUsd ?? 1)}.`,\n };\n }\n\n return { ok: true };\n}\n\n/**\n * Format a USD amount as a human-readable dollar string.\n */\nfunction formatUsd(amount: number): string {\n return `$${amount.toFixed(2)}`;\n}\n\n/**\n * Generate a warning comment for low balance.\n * Returns the markdown comment to post on the Paperclip issue.\n */\nexport function formatLowBalanceComment(balanceInfo: BalanceInfo): string {\n return `**Agrenting balance warning** — Available: ${formatUsd(balanceInfo.available)} ${balanceInfo.currency} (Escrowed: ${formatUsd(balanceInfo.escrow)}). Funds are running low. Add credits to avoid task submission failures.`;\n}\n\n/**\n * Generate a blocking comment for insufficient balance.\n */\nexport function formatInsufficientBalanceComment(balanceInfo: BalanceInfo): string {\n return `**Agrenting task blocked** — Insufficient balance: ${formatUsd(balanceInfo.available)} ${balanceInfo.currency}. Please add credits to your Agrenting account before retrying.`;\n}\n","/**\n * Comment formatting utilities for bidirectional sync between\n * Paperclip issues and Agrenting task message threads.\n */\n\nimport type { AgrentingAdapterConfig, TaskMessage, SendMessageResult } from \"./types.js\";\nimport { AgrentingClient } from \"./client.js\";\n\n/**\n * Process an Agrenting agent response and return the comment body\n * that should be posted on the Paperclip issue.\n *\n * This is called by the webhook handler when it receives task output\n * or progress messages that should appear as comments.\n */\nexport function formatAgentResponse(\n agentName: string,\n message: string\n): string {\n return `**${agentName} says:**\\n\\n${message}`;\n}\n\n/**\n * Forward a comment from Paperclip to the Agrenting task.\n * Used for bidirectional comment sync when the user adds a comment\n * to a Paperclip issue that has an active Agrenting task.\n *\n * @param config - Agrenting adapter configuration\n * @param taskId - The Agrenting task ID\n * @param comment - The comment content to forward\n * @param authorName - Optional author name for attribution\n * @returns The created TaskMessage or null if forwarding failed\n */\nexport async function forwardCommentToAgrenting(\n config: AgrentingAdapterConfig,\n taskId: string,\n comment: string,\n authorName?: string\n): Promise<SendMessageResult | null> {\n const client = new AgrentingClient(config);\n\n // Format the comment for Agrenting\n const formattedComment = authorName\n ? `[${authorName}]: ${comment}`\n : comment;\n\n try {\n return await client.sendMessageToTask(taskId, { message: formattedComment });\n } catch (err) {\n // Log but don't throw — comment sync is non-critical\n console.error(\n `[adapter-agrenting] Failed to forward comment to task ${taskId}:`,\n err instanceof Error ? err.message : String(err)\n );\n return null;\n }\n}\n\n/**\n * Process incoming Agrenting messages and format them for Paperclip.\n * Called by the webhook handler when it receives task messages.\n *\n * @param message - The incoming TaskMessage from Agrenting\n * @returns Formatted comment body for Paperclip\n */\nexport function processIncomingMessage(\n message: TaskMessage\n): string {\n const senderName = message.sender_name ?? \"Agent\";\n return formatAgentResponse(senderName, message.content);\n}\n","import { AgrentingClient } from \"./client.js\";\nimport type {\n AgrentingAdapterConfig,\n AgrentingExecutionResult,\n AgrentingTaskStatus,\n AgentInfo,\n AgentProfile,\n BalanceInfo as BalanceInfoRaw,\n HireAgentResult,\n PaymentInfo,\n ReassignTaskResult,\n SendMessageResult,\n TransactionInfo,\n DiscoverAgentsOptions,\n CreateTaskPaymentOptions,\n Hiring,\n TaskMessage,\n HiringMessage,\n Capability,\n AutoSelectOptions,\n} from \"./types.js\";\nimport { registerTaskMapping } from \"./webhook-handler.js\";\nimport { pollTaskUntilDone } from \"./polling.js\";\nimport { canSubmitTask } from \"./balance-monitor.js\";\nimport { verifyWebhookSignature } from \"./crypto.js\";\nimport { formatAgentResponse } from \"./comment-sync.js\";\n\nconst DEFAULT_WEBHOOK_PORT = 8765;\nconst MAX_WEBHOOK_BODY_SIZE = 1024 * 1024; // 1MB — prevent OOM from oversized bodies\nconst STALE_TASK_CLEANUP_INTERVAL_MS = 60_000; // 60s\nconst STALE_TASK_TTL_MS = 2 * 60 * 60 * 1000; // 2h — max age before cleanup sweeps it\n\n/** In-memory store for webhook listeners keyed by task ID */\nconst pendingTasks = new Map<\n string,\n {\n resolve: (result: AgrentingExecutionResult) => void;\n status: AgrentingTaskStatus;\n progressPercent: number;\n progressMessage?: string;\n startedAt: number;\n createdAt: number;\n settled: boolean;\n }\n>();\n\nlet webhookServer: ReturnType<typeof import(\"http\").createServer> | null = null;\nlet staleCleanupTimer: ReturnType<typeof setInterval> | null = null;\n\n/**\n * Sweep pendingTasks for entries that are settled or older than the TTL,\n * removing them from the map to bound memory usage.\n */\nfunction sweepStaleTasks(): void {\n const now = Date.now();\n for (const [id, entry] of pendingTasks) {\n if (entry.settled || now - entry.createdAt > STALE_TASK_TTL_MS) {\n pendingTasks.delete(id);\n }\n }\n}\n\n/**\n * JSON Schema for Agrenting adapter configuration fields.\n * Used by Paperclip server to validate adapter config at creation time.\n */\nexport function getConfigSchema(): Record<string, unknown> {\n return {\n type: \"object\",\n required: [\"agrentingUrl\", \"apiKey\", \"agentDid\"],\n properties: {\n agrentingUrl: {\n type: \"string\",\n format: \"uri\",\n description: \"Agrenting platform URL (e.g. https://www.agrenting.com)\",\n default: \"https://www.agrenting.com\",\n },\n apiKey: {\n type: \"string\",\n description: \"Agrenting API key for authentication\",\n sensitive: true,\n },\n agentDid: {\n type: \"string\",\n description:\n \"Decentralized identifier of the target agent (did:agrenting:...)\",\n },\n webhookSecret: {\n type: \"string\",\n description: \"Webhook signing secret for task completion callbacks\",\n sensitive: true,\n },\n webhookCallbackUrl: {\n type: \"string\",\n format: \"uri\",\n description:\n \"URL where Agrenting should POST task events (e.g. https://your-host:8765/webhook)\",\n },\n pricingModel: {\n type: \"string\",\n enum: [\"fixed\", \"per-token\", \"subscription\"],\n description: \"Pricing model for this agent\",\n default: \"fixed\",\n },\n timeoutSec: {\n type: \"integer\",\n minimum: 10,\n maximum: 3600,\n description: \"Task timeout in seconds\",\n default: 600,\n },\n instructionsBundleMode: {\n type: \"string\",\n enum: [\"managed\", \"inline\"],\n description: \"How agent instructions are delivered\",\n default: \"inline\",\n },\n },\n };\n}\n\n/**\n * Validate the adapter configuration and test connectivity.\n */\nexport async function testEnvironment(\n config: AgrentingAdapterConfig\n): Promise<{ ok: boolean; message: string }> {\n const client = new AgrentingClient(config);\n return client.testConnection();\n}\n\n/**\n * Start an HTTP listener that receives webhook callbacks from Agrenting.\n * Returns the base URL of the listener (for registering with Agrenting).\n *\n * The listener resolves pending `execute()` calls when task events arrive.\n * Only call this once per process — subsequent calls return the existing server.\n */\nexport async function startWebhookListener(\n config: AgrentingAdapterConfig\n): Promise<string> {\n if (webhookServer) {\n const addr = webhookServer.address();\n const port =\n typeof addr === \"object\" && addr ? addr.port : DEFAULT_WEBHOOK_PORT;\n return `http://localhost:${port}/webhook`;\n }\n\n const http = await import(\"http\");\n const port = process.env.PAPERCLIP_WEBHOOK_PORT\n ? parseInt(process.env.PAPERCLIP_WEBHOOK_PORT, 10)\n : DEFAULT_WEBHOOK_PORT;\n\n return new Promise((resolve, reject) => {\n const server = http.createServer(async (req, res) => {\n if (req.method !== \"POST\" || req.url !== \"/webhook\") {\n res.writeHead(404);\n res.end(\"Not found\");\n return;\n }\n\n let bodyChunks: Buffer[] = [];\n let bodyLength = 0;\n let bodyTooLarge = false;\n req.on(\"data\", (chunk: Buffer) => {\n bodyLength += chunk.length;\n if (bodyLength > MAX_WEBHOOK_BODY_SIZE) {\n bodyTooLarge = true;\n res.writeHead(413);\n res.end(\"Request body too large\");\n req.destroy();\n return;\n }\n bodyChunks.push(chunk);\n });\n\n req.on(\"end\", async () => {\n if (bodyTooLarge) return;\n const rawBody = Buffer.concat(bodyChunks).toString(\"utf8\");\n bodyChunks = []; // free reference for GC\n const taskId = req.headers[\"x-webhook-task-id\"] as string | undefined;\n const signature =\n (req.headers[\"x-webhook-signature\"] as string) || \"\";\n\n let payload: Record<string, unknown>;\n try {\n payload = JSON.parse(rawBody);\n } catch {\n res.writeHead(400);\n res.end(\"Invalid JSON\");\n return;\n }\n\n // Verify signature if secret is configured\n if (config.webhookSecret) {\n if (!signature) {\n res.writeHead(401);\n res.end(\"Missing signature\");\n return;\n }\n const valid = await verifyWebhookSignature(\n rawBody,\n signature,\n config.webhookSecret\n );\n if (!valid) {\n res.writeHead(401);\n res.end(\"Invalid signature\");\n return;\n }\n }\n\n // Extract task ID from payload if not in header\n const resolvedTaskId =\n taskId ??\n (payload.task_id as string) ??\n (payload.taskId as string);\n\n if (resolvedTaskId) {\n const pending = pendingTasks.get(resolvedTaskId);\n if (pending && !pending.settled) {\n const status = (payload.status as AgrentingTaskStatus) ?? pending.status;\n pending.status = status;\n pending.progressPercent =\n (payload.progress_percent as number) ?? pending.progressPercent;\n pending.progressMessage =\n (payload.progress_message as string) ?? pending.progressMessage;\n\n if (status === \"completed\") {\n pending.settled = true;\n pending.resolve({\n success: true,\n output: (payload.output as string) ?? JSON.stringify(payload.output ?? {}),\n taskId: resolvedTaskId,\n durationMs: Date.now() - pending.startedAt,\n });\n } else if (status === \"failed\") {\n pending.settled = true;\n pending.resolve({\n success: false,\n error:\n (payload.error_reason as string) ??\n \"Task failed with no reason provided\",\n taskId: resolvedTaskId,\n durationMs: Date.now() - pending.startedAt,\n });\n } else if (status === \"cancelled\") {\n pending.settled = true;\n pending.resolve({\n success: false,\n error: \"Task was cancelled\",\n taskId: resolvedTaskId,\n durationMs: Date.now() - pending.startedAt,\n });\n }\n }\n }\n\n res.writeHead(200, { \"Content-Type\": \"text/plain\" });\n res.end(\"OK\");\n });\n });\n\n server.listen(port, () => {\n webhookServer = server;\n // Start periodic cleanup of stale entries\n if (!staleCleanupTimer) {\n staleCleanupTimer = setInterval(sweepStaleTasks, STALE_TASK_CLEANUP_INTERVAL_MS);\n staleCleanupTimer.unref();\n }\n resolve(`http://localhost:${port}/webhook`);\n });\n\n server.on(\"error\", reject);\n });\n}\n\nconst WEBHOOK_STOP_TIMEOUT_MS = 5_000;\n\n/**\n * Stop the webhook listener if it was started.\n * Closes all active connections and waits up to 5s for a clean shutdown.\n */\nexport async function stopWebhookListener(): Promise<void> {\n if (!webhookServer) {\n return;\n }\n\n if (staleCleanupTimer) {\n clearInterval(staleCleanupTimer);\n staleCleanupTimer = null;\n }\n\n const server = webhookServer;\n webhookServer = null;\n\n // Force-close all active connections (Node 18.2+) so server.close() doesn't hang\n if (\"closeAllConnections\" in server && typeof server.closeAllConnections === \"function\") {\n (server as import(\"http\").Server<typeof import(\"http\").IncomingMessage, typeof import(\"http\").ServerResponse>).closeAllConnections();\n }\n\n return new Promise((resolve) => {\n const timeout = setTimeout(() => {\n resolve();\n }, WEBHOOK_STOP_TIMEOUT_MS);\n timeout.unref();\n\n server.close(() => {\n clearTimeout(timeout);\n resolve();\n });\n });\n}\n\n/**\n * Register a webhook with Agrenting to receive task lifecycle events.\n * Returns the webhook ID and secret key.\n */\nexport async function registerWebhook(\n config: AgrentingAdapterConfig,\n callbackUrl?: string\n): Promise<{\n id: string;\n secretKey: string;\n callbackUrl: string;\n}> {\n const client = new AgrentingClient(config);\n const url = callbackUrl ?? (await startWebhookListener(config));\n\n const result = await client.registerWebhook({\n callbackUrl: url,\n eventTypes: [\n \"task.created\",\n \"task.claimed\",\n \"task.in_progress\",\n \"task.completed\",\n \"task.failed\",\n \"task.cancelled\",\n ],\n });\n\n return {\n id: result.id,\n secretKey: result.secret_key,\n callbackUrl: result.callback_url,\n };\n}\n\n/**\n * Deregister a webhook from Agrenting to stop receiving task lifecycle events.\n * Use this to clean up orphaned webhooks when they are no longer needed.\n */\nexport async function deregisterWebhook(\n config: AgrentingAdapterConfig,\n webhookId: string\n): Promise<void> {\n const client = new AgrentingClient(config);\n await client.deleteWebhook(webhookId);\n}\n\n/**\n * Execute a task by submitting it to the Agrenting platform.\n *\n * Uses webhook callbacks when `webhookCallbackUrl` is configured in the adapter config\n * (or when `startWebhookListener()` has been called). Falls back to polling\n * when webhooks are not available.\n *\n * When `maxPrice` is provided, the task is created with a budget and escrow funds\n * are locked via `createTaskPayment()` after submission.\n */\nexport async function execute(\n config: AgrentingAdapterConfig,\n params: {\n input: string;\n capability: string;\n instructions?: string;\n /** Maximum price in USD to budget for this task. Triggers escrow payment. */\n maxPrice?: string;\n /** Payment type: \"crypto\" | \"escrow\" | \"nowpayments\". Defaults to \"crypto\". */\n paymentType?: string;\n }\n): Promise<AgrentingExecutionResult> {\n const client = new AgrentingClient(config);\n const startTime = Date.now();\n\n // Upload instructions if managed mode is configured\n if (\n config.instructionsBundleMode === \"managed\" &&\n params.instructions\n ) {\n await client.uploadDocument({\n name: \"instructions\",\n content: params.instructions,\n documentType: \"instructions\",\n });\n }\n\n // Pre-submission balance check (non-blocking — logs warning but doesn't prevent)\n const balanceCheck = await canSubmitTask({ config });\n if (!balanceCheck.ok) {\n // Log but don't block — let the task fail naturally\n console.warn(`[adapter-agrenting] ${balanceCheck.reason}`);\n }\n\n // Submit the task to Agrenting\n const task = await client.createTask({\n providerAgentId: config.agentDid,\n capability: params.capability,\n input: params.input,\n maxPrice: params.maxPrice,\n paymentType: params.paymentType,\n });\n\n const taskId = task.id;\n\n // Lock escrow funds if a max price was specified.\n // If payment fails, cancel the orphaned task to avoid leaving it stuck on the server.\n let payment: PaymentInfo | undefined;\n if (params.maxPrice) {\n try {\n const paymentOptions: CreateTaskPaymentOptions = {};\n if (params.paymentType) paymentOptions.paymentType = params.paymentType;\n payment = await client.createTaskPayment(taskId, paymentOptions);\n console.log(`[adapter-agrenting] Escrow locked for task ${taskId}: ${payment.amount} ${payment.currency} (${payment.status})`);\n } catch (err) {\n console.error(`[adapter-agrenting] Failed to lock escrow for task ${taskId}, cancelling orphaned task:`, err);\n try {\n await client.cancelTask(taskId);\n } catch {\n // Best-effort cleanup — log but don't throw, the payment error is the real problem\n }\n return {\n success: false,\n error: `Escrow payment failed: ${err instanceof Error ? err.message : String(err)}`,\n taskId,\n durationMs: Date.now() - startTime,\n };\n }\n }\n\n // Register for webhook callbacks only when webhook mode is actually configured.\n // The taskRegistry in webhook-handler.ts is for the Paperclip-side webhook handler\n // (issue status updates), while pendingTasks below is for the in-process listener\n // (resolving execute() promises). They serve different purposes.\n if (config.webhookCallbackUrl || config.webhookSecret) {\n registerTaskMapping(taskId, taskId, config.agrentingUrl, config);\n return executeWithWebhook(client, config, taskId, startTime);\n }\n\n // Fall back to polling — delegate to pollTaskUntilDone\n return executeWithPolling(config, taskId, startTime);\n}\n\n/**\n * Execute with webhook: register a listener, submit task, wait for callback.\n * Falls back to polling if no webhook received within the grace period.\n */\nasync function executeWithWebhook(\n _client: AgrentingClient,\n config: AgrentingAdapterConfig,\n taskId: string,\n startTime: number\n): Promise<AgrentingExecutionResult> {\n // Ensure the listener is running\n await startWebhookListener(config);\n\n const deadline = startTime + (config.timeoutSec ?? 600) * 1000;\n\n // AbortController for clean cancellation when webhook resolves first\n const abortController = new AbortController();\n\n // Register the pending task so the webhook handler can resolve it\n const pending = new Promise<AgrentingExecutionResult>((resolve) => {\n pendingTasks.set(taskId, {\n resolve,\n status: \"pending\",\n progressPercent: 0,\n startedAt: startTime,\n createdAt: Date.now(),\n settled: false,\n });\n }).then((result) => {\n // Webhook resolved — abort any in-flight polling\n abortController.abort();\n return result;\n });\n\n // Race between webhook callback and timeout\n const timeout = new Promise<AgrentingExecutionResult>((resolve) => {\n const ms = deadline - Date.now();\n setTimeout(() => {\n const entry = pendingTasks.get(taskId);\n if (entry && !entry.settled) {\n entry.settled = true;\n }\n resolve({\n success: false,\n error: `Task timed out after ${config.timeoutSec ?? 600}s`,\n taskId,\n durationMs: Date.now() - startTime,\n });\n }, Math.max(ms, 0));\n });\n\n // If webhook doesn't resolve within grace period, fall back to polling.\n // Polling is deferred so it only starts when the timeout actually fires,\n // avoiding wasted HTTP calls when the webhook wins.\n return Promise.race([pending, timeout.then(async (result) => {\n if (!result.success && result.error?.includes(\"timed out\")) {\n const pollingFallback = await pollTaskUntilDone({\n config,\n taskId,\n deadline,\n signal: abortController.signal,\n });\n return pollingFallback.result;\n }\n return result;\n })]);\n}\n\n/**\n * Execute with polling by delegating to pollTaskUntilDone.\n * Avoids reimplementing the backoff loop that polling.ts already provides.\n */\nasync function executeWithPolling(\n config: AgrentingAdapterConfig,\n taskId: string,\n startTime: number\n): Promise<AgrentingExecutionResult> {\n const deadline = startTime + (config.timeoutSec ?? 600) * 1000;\n const { result } = await pollTaskUntilDone({ config, taskId, deadline });\n return result;\n}\n\n/**\n * Get the current progress of a task including percentage and message.\n * Useful for progress monitoring in UI dashboards.\n */\nexport async function getTaskProgress(\n config: AgrentingAdapterConfig,\n taskId: string\n): Promise<{\n status: AgrentingTaskStatus;\n progressPercent: number;\n progressMessage?: string;\n timeline: Array<{\n event_type: string;\n timestamp: string;\n progress_percent?: number;\n progress_message?: string;\n }>;\n}> {\n const client = new AgrentingClient(config);\n const [progress, timeline] = await Promise.all([\n client.getTaskProgress(taskId),\n client.getTaskTimeline(taskId),\n ]);\n\n return {\n status: progress.status as AgrentingTaskStatus,\n progressPercent: progress.progress_percent,\n progressMessage: progress.progress_message,\n timeline: timeline.events,\n };\n}\n\n/**\n * Discover marketplace agents available for hire.\n * Filters by capability, price range, reputation, and availability.\n */\nexport async function discoverAgents(\n config: AgrentingAdapterConfig,\n options: DiscoverAgentsOptions = {}\n): Promise<AgentInfo[]> {\n const client = new AgrentingClient(config);\n return client.discoverAgents(options);\n}\n\n/**\n * Get the current platform balance including available, escrowed, and total amounts.\n */\nexport async function getBalance(\n config: AgrentingAdapterConfig\n): Promise<BalanceInfoRaw> {\n const client = new AgrentingClient(config);\n return client.getBalance();\n}\n\n/**\n * List recent ledger transactions.\n */\nexport async function getTransactions(\n config: AgrentingAdapterConfig,\n options: { limit?: number; offset?: number; type?: string } = {}\n): Promise<TransactionInfo[]> {\n const client = new AgrentingClient(config);\n return client.getTransactions(options);\n}\n\n/**\n * Deposit funds into the Agrenting ledger.\n */\nexport async function deposit(\n config: AgrentingAdapterConfig,\n params: { amount: string; currency?: string; paymentMethod?: string }\n): Promise<{ transaction_id: string; status: string; deposit_address?: string; payment_url?: string }> {\n const client = new AgrentingClient(config);\n return client.deposit(params);\n}\n\n/**\n * Withdraw funds from the Agrenting ledger to an external wallet.\n */\nexport async function withdraw(\n config: AgrentingAdapterConfig,\n params: { amount: string; currency?: string; withdrawalAddressId?: string }\n): Promise<{ transaction_id: string; status: string }> {\n const client = new AgrentingClient(config);\n return client.withdraw(params);\n}\n\n/**\n * Get the payment status and escrow details for a task.\n */\nexport async function getTaskPayment(\n config: AgrentingAdapterConfig,\n taskId: string\n): Promise<PaymentInfo | undefined> {\n const client = new AgrentingClient(config);\n try {\n return await client.getTaskPayment(taskId);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Cancel a running task.\n */\nexport async function cancelTask(\n config: AgrentingAdapterConfig,\n taskId: string\n): Promise<{ success: boolean; error?: string }> {\n const client = new AgrentingClient(config);\n try {\n await client.cancelTask(taskId);\n pendingTasks.delete(taskId);\n return { success: true };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : \"Failed to cancel task\",\n };\n }\n}\n\n// -------------------------------------------------------------------------\n// New adapter functions for hire, messaging, auto-select, and retry\n// -------------------------------------------------------------------------\n\n/** Task retry configuration */\nconst TASK_MAX_RETRIES = 2;\nconst TASK_RETRY_BASE_DELAY_MS = 1000; // 1s initial delay\nconst TASK_RETRY_MAX_DELAY_MS = 30_000; // 30s max delay\n\n/**\n * Hire an agent by DID. Returns hiring record and adapter config for auto-provisioning.\n * This is the primary entry point for the \"browse marketplace, click Hire\" flow.\n */\nexport async function hireAgent(\n config: AgrentingAdapterConfig,\n agentDid: string\n): Promise<HireAgentResult> {\n const client = new AgrentingClient(config);\n return client.hireAgent(agentDid);\n}\n\n/**\n * Get full agent profile by DID.\n * Returns description, capabilities, pricing, reputation, and availability.\n */\nexport async function getAgentProfile(\n config: AgrentingAdapterConfig,\n agentDid: string\n): Promise<AgentProfile> {\n const client = new AgrentingClient(config);\n return client.getAgentProfile(agentDid);\n}\n\n/**\n * Send a message to an active task for bidirectional communication.\n * Used for sending follow-up instructions to the remote agent mid-task.\n */\nexport async function sendMessageToTask(\n config: AgrentingAdapterConfig,\n taskId: string,\n message: string\n): Promise<SendMessageResult> {\n const client = new AgrentingClient(config);\n return client.sendMessageToTask(taskId, { message });\n}\n\n/**\n * Get messages for a task (bidirectional comment history).\n */\nexport async function getTaskMessages(\n config: AgrentingAdapterConfig,\n taskId: string\n): Promise<TaskMessage[]> {\n const client = new AgrentingClient(config);\n return client.getTaskMessages(taskId);\n}\n\n/**\n * Reassign a failed/cancelled task to a different agent.\n * If newAgentDid is not provided, the system will auto-select a replacement.\n */\nexport async function reassignTask(\n config: AgrentingAdapterConfig,\n taskId: string,\n newAgentDid?: string\n): Promise<ReassignTaskResult> {\n const client = new AgrentingClient(config);\n return client.reassignTask(taskId, newAgentDid);\n}\n\n/**\n * List all available capabilities with descriptions and usage stats.\n * Helps with agent discovery and validation.\n */\nexport async function listCapabilities(\n config: AgrentingAdapterConfig\n): Promise<Capability[]> {\n const client = new AgrentingClient(config);\n return client.listCapabilities();\n}\n\n/**\n * Send a message to a hiring for communication with the hired agent.\n */\nexport async function sendMessageToHiring(\n config: AgrentingAdapterConfig,\n hiringId: string,\n message: string\n): Promise<HiringMessage> {\n const client = new AgrentingClient(config);\n return client.sendMessageToHiring(hiringId, message);\n}\n\n/**\n * Get messages for a hiring.\n */\nexport async function getHiringMessages(\n config: AgrentingAdapterConfig,\n hiringId: string\n): Promise<HiringMessage[]> {\n const client = new AgrentingClient(config);\n return client.getHiringMessages(hiringId);\n}\n\n/**\n * Retry a failed hiring.\n */\nexport async function retryHiring(\n config: AgrentingAdapterConfig,\n hiringId: string,\n options?: { reason?: string }\n): Promise<Hiring> {\n const client = new AgrentingClient(config);\n return client.retryHiring(hiringId, options);\n}\n\n/**\n * Get a hiring by ID.\n */\nexport async function getHiring(\n config: AgrentingAdapterConfig,\n hiringId: string\n): Promise<Hiring> {\n const client = new AgrentingClient(config);\n return client.getHiring(hiringId);\n}\n\n/**\n * List hirings for the authenticated agent.\n */\nexport async function listHirings(\n config: AgrentingAdapterConfig,\n options?: { status?: string; limit?: number; offset?: number }\n): Promise<Hiring[]> {\n const client = new AgrentingClient(config);\n return client.listHirings(options);\n}\n\n/**\n * Auto-select mode: given a capability requirement, discover the best agent,\n * hire them, and return the adapter config for immediate use.\n *\n * Selection algorithm:\n * 1. Call listCapabilities() to validate capability exists\n * 2. Call GET /api/v1/agents filtered by capability\n * 3. Sort by: availability first, then reputation_score desc, then base_price asc\n * 4. Call hireAgent() to auto-provision\n * 5. Return adapter config\n */\nexport async function autoSelectAgent(\n config: AgrentingAdapterConfig,\n options: AutoSelectOptions\n): Promise<HireAgentResult & { selectedAgent: AgentProfile }> {\n const client = new AgrentingClient(config);\n\n // 1. Validate capability exists\n const capabilities = await client.listCapabilities();\n const capabilityExists = capabilities.some(\n (c) => c.name === options.capability || c.name.toLowerCase() === options.capability.toLowerCase()\n );\n if (!capabilityExists) {\n throw new Error(`Capability \"${options.capability}\" not found. Available: ${capabilities.map(c => c.name).join(\", \")}`);\n }\n\n // 2. Get agents filtered by capability\n const agents = await client.listAgentsByCapability(options.capability);\n if (agents.length === 0) {\n throw new Error(`No agents available for capability \"${options.capability}\"`);\n }\n\n // 3. Filter by options and sort\n let filtered = agents;\n\n // Filter by max price\n if (options.maxPrice) {\n const maxPriceNum = parseFloat(options.maxPrice);\n filtered = filtered.filter((a) => {\n if (!a.base_price) return true; // No price info = assume fits budget\n return parseFloat(a.base_price) <= maxPriceNum;\n });\n }\n\n // Filter by min reputation\n if (options.minReputation) {\n const minRep = options.minReputation;\n filtered = filtered.filter((a) => {\n if (!a.reputation_score) return false; // No reputation = excluded\n return a.reputation_score >= minRep;\n });\n }\n\n if (filtered.length === 0) {\n throw new Error(\n `No agents match criteria for capability \"${options.capability}\" (maxPrice=${options.maxPrice ?? \"any\"}, minReputation=${options.minReputation ?? \"any\"})`\n );\n }\n\n // Sort: availability first, then by specified sort criteria\n const sortBy = options.sortBy ?? \"reputation_score\";\n\n // Prefer available agents if requested\n if (options.preferAvailable ?? true) {\n filtered.sort((a, b) => {\n const aAvail = a.availability_status === \"available\" ? 0 : 1;\n const bAvail = b.availability_status === \"available\" ? 0 : 1;\n if (aAvail !== bAvail) return aAvail - bAvail;\n return 0;\n });\n }\n\n // Secondary sort\n filtered.sort((a, b) => {\n if (sortBy === \"reputation_score\") {\n return (b.reputation_score ?? 0) - (a.reputation_score ?? 0);\n }\n if (sortBy === \"base_price\") {\n const aPrice = parseFloat(a.base_price ?? \"999999\");\n const bPrice = parseFloat(b.base_price ?? \"999999\");\n return aPrice - bPrice;\n }\n if (sortBy === \"availability\") {\n const aAvail = a.availability_status === \"available\" ? 0 : 1;\n const bAvail = b.availability_status === \"available\" ? 0 : 1;\n return aAvail - bAvail;\n }\n return 0;\n });\n\n // 4. Hire the best agent\n const selectedAgent = filtered[0];\n const hireResult = await client.hireAgent(selectedAgent.did);\n\n // 5. Return combined result\n return {\n ...hireResult,\n selectedAgent,\n };\n}\n\n/**\n * Execute a task with retry logic.\n * If the task fails, it will be retried up to TASK_MAX_RETRIES times\n * with exponential backoff.\n */\nexport async function executeWithRetry(\n config: AgrentingAdapterConfig,\n params: {\n input: string;\n capability: string;\n instructions?: string;\n maxPrice?: string;\n paymentType?: string;\n maxRetries?: number;\n }\n): Promise<AgrentingExecutionResult> {\n const maxRetries = params.maxRetries ?? TASK_MAX_RETRIES;\n let lastResult: AgrentingExecutionResult | undefined;\n let lastError: Error | null = null;\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n lastResult = await execute(config, params);\n\n if (lastResult.success) {\n return lastResult;\n }\n\n // If task failed but we have retries remaining, wait and retry\n if (attempt < maxRetries && lastResult.error) {\n const delayMs = Math.min(\n TASK_RETRY_BASE_DELAY_MS * Math.pow(2, attempt),\n TASK_RETRY_MAX_DELAY_MS\n );\n console.warn(\n `[adapter-agrenting] Task failed on attempt ${attempt + 1}, retrying in ${delayMs}ms: ${lastResult.error}`\n );\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n continue;\n }\n\n return lastResult;\n } catch (err) {\n lastError = err instanceof Error ? err : new Error(String(err));\n\n if (attempt < maxRetries) {\n const delayMs = Math.min(\n TASK_RETRY_BASE_DELAY_MS * Math.pow(2, attempt),\n TASK_RETRY_MAX_DELAY_MS\n );\n console.warn(\n `[adapter-agrenting] Execution error on attempt ${attempt + 1}, retrying in ${delayMs}ms: ${lastError.message}`\n );\n await new Promise((resolve) => setTimeout(resolve, delayMs));\n continue;\n }\n }\n }\n\n // All retries exhausted\n return {\n success: false,\n error: lastError?.message ?? lastResult?.error ?? \"Task failed after all retries\",\n taskId: lastResult?.taskId,\n durationMs: lastResult?.durationMs ?? 0,\n };\n}\n\n/**\n * Forward a comment from Paperclip to the Agrenting task.\n * Used for bidirectional comment sync when the user adds a comment\n * to a Paperclip issue that has an active Agrenting task.\n */\nexport async function forwardCommentToAgrenting(\n config: AgrentingAdapterConfig,\n taskId: string,\n comment: string,\n authorName?: string\n): Promise<SendMessageResult | null> {\n const client = new AgrentingClient(config);\n\n // Format the comment for Agrenting\n const formattedComment = authorName\n ? `[${authorName}]: ${comment}`\n : comment;\n\n try {\n return await client.sendMessageToTask(taskId, { message: formattedComment });\n } catch (err) {\n // Log but don't throw — comment sync is non-critical\n console.error(\n `[adapter-agrenting] Failed to forward comment to task ${taskId}:`,\n err instanceof Error ? err.message : String(err)\n );\n return null;\n }\n}\n\n/**\n * Process incoming Agrenting messages and format them for Paperclip.\n * Called by the webhook handler when it receives task messages.\n */\nexport function processIncomingMessage(\n message: TaskMessage\n): string {\n const senderName = message.sender_name ?? \"Agent\";\n return formatAgentResponse(senderName, message.content);\n}\n\n/**\n * Create the server-side adapter module.\n * This is the entry point for Paperclip's server adapter registry.\n */\nexport function createServerAdapter() {\n return {\n name: \"agrenting\" as const,\n execute,\n testEnvironment,\n getConfigSchema,\n startWebhookListener,\n stopWebhookListener,\n registerWebhook,\n deregisterWebhook,\n getTaskProgress,\n getTaskPayment,\n cancelTask,\n discoverAgents,\n getAgentProfile,\n hireAgent,\n sendMessageToTask,\n getTaskMessages,\n reassignTask,\n listCapabilities,\n sendMessageToHiring,\n getHiringMessages,\n retryHiring,\n getHiring,\n listHirings,\n autoSelectAgent,\n executeWithRetry,\n forwardCommentToAgrenting,\n processIncomingMessage,\n getBalance,\n getTransactions,\n deposit,\n withdraw,\n };\n}\n"],"mappings":"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","names":["port","forwardCommentToAgrenting","processIncomingMessage"]}