mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-08 01:57:31 +01:00
Persist optional connection instructions and deliver authorized snapshots to agent execution prompts. Keep provider templates with each app definition, preserve edits and opt-outs, and replace sessions when guidance or access changes. Use shared production settings across setup and Permissions, with source visibility in agent Instructions. Add the initial memory-provider defaults and managed Honcho workspace configuration. Include migration 0298 and regression coverage for generic providers, runtime delivery, authorization, and catalog regeneration. Co-Authored-By: Paperclip <noreply@paperclip.ing>
66 lines
2.1 KiB
TypeScript
66 lines
2.1 KiB
TypeScript
import type { AdapterExecutionContext, AdapterExecutionResult } from "../types.js";
|
|
import { asString, asNumber, parseObject } from "../utils.js";
|
|
import { guardedHttpAdapterFetch } from "./remote-fetch.js";
|
|
|
|
export async function execute(ctx: AdapterExecutionContext): Promise<AdapterExecutionResult> {
|
|
const { config, runId, agent, context } = ctx;
|
|
const url = asString(config.url, "");
|
|
if (!url) throw new Error("HTTP adapter missing url");
|
|
|
|
const method = asString(config.method, "POST");
|
|
const timeoutMs = asNumber(config.timeoutMs, 0);
|
|
const headers = parseObject(config.headers) as Record<string, string>;
|
|
const payloadTemplate = parseObject(config.payloadTemplate);
|
|
const body = {
|
|
...payloadTemplate,
|
|
agentId: agent.id,
|
|
runId,
|
|
context,
|
|
connectionInstructions: context.connectionInstructions ?? null,
|
|
...(ctx.runtimeTools ? { paperclipRuntimeTools: ctx.runtimeTools } : {}),
|
|
};
|
|
|
|
const controller = new AbortController();
|
|
const timer = timeoutMs > 0 ? setTimeout(() => controller.abort(), timeoutMs) : null;
|
|
|
|
try {
|
|
// HTTP adapters have no child-process spawn event. Signal immediately
|
|
// before starting the remote request so dispatch gates can release without
|
|
// waiting for the endpoint to respond.
|
|
ctx.onDispatch?.();
|
|
const res = await guardedHttpAdapterFetch(url, {
|
|
method,
|
|
headers: {
|
|
"content-type": "application/json",
|
|
...headers,
|
|
},
|
|
body: JSON.stringify(body),
|
|
...(timer ? { signal: controller.signal } : {}),
|
|
});
|
|
|
|
if (!res.ok) {
|
|
throw new Error(`HTTP invoke failed with status ${res.status}`);
|
|
}
|
|
|
|
return {
|
|
exitCode: 0,
|
|
signal: null,
|
|
timedOut: false,
|
|
summary: `HTTP ${method} ${url}`,
|
|
};
|
|
} catch (err) {
|
|
if (timer && err instanceof Error && err.name === "AbortError") {
|
|
return {
|
|
exitCode: null,
|
|
signal: null,
|
|
timedOut: true,
|
|
errorMessage: `HTTP ${method} ${url} timed out after ${timeoutMs}ms`,
|
|
errorCode: "timeout",
|
|
};
|
|
}
|
|
throw err;
|
|
} finally {
|
|
if (timer) clearTimeout(timer);
|
|
}
|
|
}
|