feat(FN-2706): merge fusion/fn-2706 (auto-resolved)

- feat(FN-2706): complete Step 6 — document Paperclip REST runtime behavior
- test(FN-2706): cover getAgentIdentity success and request payload assertions
- fix(FN-2706): align promptWithFallback signature with runtime contract
- fix(FN-2706): add session dispose compatibility for engine callers
- fix(FN-2706): refine Paperclip API client error and config handling
- test(FN-2706): complete Step 4 — cover paperclip api client and adapter flow
- feat(FN-2706): complete Step 3 — wire plugin settings and remove engine guard
- feat(FN-2706): complete Step 2 — rewrite paperclip runtime adapter
- fix(FN-2706): restore compatibility exports during runtime migration
- feat(FN-2706): complete Step 1 — add Paperclip REST client
This commit is contained in:
Fusion
2026-04-27 10:28:51 -07:00
committed by gsxdsm
parent 6d1089bc25
commit f85d369bfc
18 changed files with 1307 additions and 904 deletions

View File

@@ -1,55 +1,31 @@
/**
* Paperclip Runtime Plugin
*
* Provides the Paperclip runtime for Fusion AI agents, backed by the user's
* configured pi provider and model.
*
* ## Runtime Capabilities
*
* This plugin implements the AgentRuntime interface, providing:
* - Session creation via createFnAgent
* - Prompt with automatic retry and compaction
* - Model description extraction
* - Session disposal support
*/
import { definePlugin } from "@fusion/plugin-sdk";
import { probePaperclipInstance, resolvePaperclipConfig } from "./pi-module.js";
import { PaperclipRuntimeAdapter } from "./runtime-adapter.js";
import type {
FusionPlugin,
PluginRuntimeRegistration,
} from "@fusion/plugin-sdk";
RuntimeLogger,
} from "./types.js";
// ── Runtime Registration ─────────────────────────────────────────────────────
/**
* Paperclip runtime factory.
*
* Creates a new PaperclipRuntimeAdapter instance when the runtime is resolved.
*
* @returns Promise resolving to a PaperclipRuntimeAdapter instance
*/
async function paperclipRuntimeFactory(): Promise<PaperclipRuntimeAdapter> {
return new PaperclipRuntimeAdapter();
function getSettingsConfig(settings: unknown) {
return resolvePaperclipConfig((settings ?? {}) as Record<string, unknown>);
}
async function paperclipRuntimeFactory(ctx: { settings?: unknown; logger?: RuntimeLogger }): Promise<unknown> {
const config = getSettingsConfig(ctx.settings);
return new PaperclipRuntimeAdapter(config, ctx.logger);
}
/**
* Paperclip runtime registration for Fusion's plugin runtime system.
* Uses the PluginRuntimeRegistration contract from FN-2256.
*/
const paperclipRuntime: PluginRuntimeRegistration = {
metadata: {
runtimeId: "paperclip",
name: "Paperclip Runtime",
description:
"Paperclip-backed AI session using the user's configured pi provider and model",
description: "Paperclip-backed AI session via Paperclip REST API",
version: "1.0.0",
},
factory: paperclipRuntimeFactory,
};
// ── Plugin Definition ─────────────────────────────────────────────────────────
const plugin: FusionPlugin = definePlugin({
manifest: {
id: "fusion-plugin-paperclip-runtime",
@@ -62,16 +38,26 @@ const plugin: FusionPlugin = definePlugin({
runtime: {
runtimeId: "paperclip",
name: "Paperclip Runtime",
description:
"Paperclip-backed AI session using the user's configured pi provider and model",
description: "Paperclip-backed AI session via Paperclip REST API",
version: "1.0.0",
},
},
state: "installed",
runtime: paperclipRuntime,
hooks: {
onLoad: (ctx) => {
ctx.logger.info("Paperclip Runtime Plugin loaded");
onLoad: async (ctx) => {
const config = getSettingsConfig(ctx.settings);
ctx.logger.info(`Paperclip Runtime Plugin loaded (apiUrl=${config.apiUrl})`);
const probe = await probePaperclipInstance(config.apiUrl, config.apiKey);
if (probe.ok) {
ctx.logger.info(
`Paperclip probe succeeded (deploymentMode=${probe.deploymentMode ?? "unknown"})`,
);
return;
}
ctx.logger.warn(`Paperclip probe failed: ${probe.error}`);
},
},
});