feat(FN-2262): merge fusion/fn-2262 (auto-resolved)
- feat(FN-2262): document Paperclip runtime configuration and constraints - docs(FN-2261): update README with implementation details - feat(FN-2261): add paperclip runtime resolution compatibility tests - feat(FN-2261): add runtime adapter and registration tests - feat(FN-2261): integrate adapter into plugin entrypoint - feat(FN-2261): implement PaperclipRuntimeAdapter - fix(FN-2261): remove pi-coding-agent re-exports from types.ts - feat(FN-2261): define runtime types for Paperclip plugin - feat(FN-2260): merge fusion/fn-2260
This commit is contained in:
@@ -52,13 +52,9 @@ describe("paperclip-runtime plugin", () => {
|
||||
|
||||
describe("runtime factory invocation", () => {
|
||||
beforeEach(() => {
|
||||
// Mock @fusion/engine for createFnAgent
|
||||
vi.mock("@fusion/engine", () => ({
|
||||
vi.mock("../../../../packages/engine/src/pi.js", () => ({
|
||||
createFnAgent: vi.fn().mockResolvedValue({ session: {} }),
|
||||
promptWithFallback: vi.fn(),
|
||||
}));
|
||||
// Mock describeModel
|
||||
vi.mock("../../engine/src/pi.js", () => ({
|
||||
describeModel: vi.fn().mockReturnValue("mock/model"),
|
||||
}));
|
||||
});
|
||||
@@ -73,7 +69,7 @@ describe("paperclip-runtime plugin", () => {
|
||||
});
|
||||
|
||||
it("should return an adapter with correct id and name", async () => {
|
||||
const runtime = await plugin.runtime!.factory({} as any);
|
||||
const runtime = (await plugin.runtime!.factory({} as any)) as PaperclipRuntimeAdapter;
|
||||
expect(runtime.id).toBe("paperclip");
|
||||
expect(runtime.name).toBe("Paperclip Runtime");
|
||||
});
|
||||
|
||||
@@ -9,18 +9,12 @@ import { PaperclipRuntimeAdapter } from "../runtime-adapter.js";
|
||||
|
||||
// ── Mock Modules ────────────────────────────────────────────────────────────────
|
||||
|
||||
// Mock @fusion/engine for createFnAgent and promptWithFallback
|
||||
const mockCreateFnAgent = vi.fn();
|
||||
const mockPromptWithFallback = vi.fn();
|
||||
|
||||
vi.mock("@fusion/engine", () => ({
|
||||
vi.mock("../../../../packages/engine/src/pi.js", () => ({
|
||||
createFnAgent: mockCreateFnAgent,
|
||||
promptWithFallback: mockPromptWithFallback,
|
||||
}));
|
||||
|
||||
// Mock the relative import of describeModel from pi.ts
|
||||
// This uses require() in the adapter, so we mock the entire module
|
||||
vi.mock("../../engine/src/pi.js", () => ({
|
||||
describeModel: vi.fn().mockReturnValue("mock/anthropic-claude"),
|
||||
}));
|
||||
|
||||
@@ -169,7 +163,7 @@ describe("PaperclipRuntimeAdapter", () => {
|
||||
describe("describeModel", () => {
|
||||
it("should return model description from pi describeModel", () => {
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const { describeModel } = require("../../engine/src/pi.js");
|
||||
const { describeModel } = require("../../../../packages/engine/src/pi.js");
|
||||
|
||||
const mockSession = { model: { provider: "anthropic", id: "claude-sonnet-4-5" } };
|
||||
const result = adapter.describeModel(mockSession as any);
|
||||
|
||||
@@ -30,8 +30,12 @@
|
||||
* ```
|
||||
*/
|
||||
|
||||
import type { AgentRuntime, AgentRuntimeOptions, AgentSessionResult } from "./types.js";
|
||||
import type { AgentSession } from "@mariozechner/pi-coding-agent";
|
||||
import type {
|
||||
AgentRuntime,
|
||||
AgentRuntimeOptions,
|
||||
AgentSession,
|
||||
AgentSessionResult,
|
||||
} from "./types.js";
|
||||
|
||||
// ── describeModel (from pi.ts, not re-exported from @fusion/engine) ─────────────
|
||||
//
|
||||
@@ -40,8 +44,16 @@ import type { AgentSession } from "@mariozechner/pi-coding-agent";
|
||||
// This is acceptable within the monorepo workspace. External plugins would need a
|
||||
// different approach (e.g., the engine could export it publicly in the future).
|
||||
//
|
||||
type PiModule = {
|
||||
createFnAgent: (options: unknown) => Promise<AgentSessionResult>;
|
||||
promptWithFallback: (session: unknown, prompt: string, options?: unknown) => Promise<void>;
|
||||
describeModel: (session: unknown) => string;
|
||||
};
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
const { describeModel: getModelDescription } = require("../../engine/src/pi.js");
|
||||
const loadPiModule = (): PiModule => require("../../../packages/engine/src/pi.js") as PiModule;
|
||||
|
||||
const { describeModel: getModelDescription } = loadPiModule();
|
||||
|
||||
/**
|
||||
* Paperclip runtime adapter implementing the Fusion AgentRuntime interface.
|
||||
@@ -69,7 +81,7 @@ export class PaperclipRuntimeAdapter implements AgentRuntime {
|
||||
* @returns Promise resolving to the session result with session and optional sessionFile
|
||||
*/
|
||||
async createSession(options: AgentRuntimeOptions): Promise<AgentSessionResult> {
|
||||
const { createFnAgent } = await import("@fusion/engine");
|
||||
const { createFnAgent } = loadPiModule();
|
||||
return createFnAgent({
|
||||
cwd: options.cwd,
|
||||
systemPrompt: options.systemPrompt,
|
||||
@@ -103,7 +115,7 @@ export class PaperclipRuntimeAdapter implements AgentRuntime {
|
||||
* @param options - Optional prompt options (e.g., images for vision)
|
||||
*/
|
||||
async promptWithFallback(session: AgentSession, prompt: string, options?: unknown): Promise<void> {
|
||||
const { promptWithFallback: pwf } = await import("@fusion/engine");
|
||||
const { promptWithFallback: pwf } = loadPiModule();
|
||||
return pwf(session, prompt, options);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,74 +1,58 @@
|
||||
/**
|
||||
* Paperclip Runtime Plugin - Type Definitions
|
||||
*
|
||||
* Re-exports runtime contract types from @fusion/engine and plugin types from @fusion/plugin-sdk.
|
||||
* These types define the interface that the Paperclip runtime adapter must implement.
|
||||
*
|
||||
* ## Type Sources
|
||||
*
|
||||
* - `AgentRuntime`, `AgentRuntimeOptions`, `AgentSessionResult`: from @fusion/engine (FN-2256 contract)
|
||||
* - `PluginRuntimeRegistration`, `PluginRuntimeManifestMetadata`, `FusionPlugin`: from @fusion/plugin-sdk
|
||||
*
|
||||
* ## Internal Types
|
||||
*
|
||||
* `AgentSession` and `ToolDefinition` are used internally in the adapter implementation
|
||||
* but are NOT re-exported here since they come from @mariozechner/pi-coding-agent,
|
||||
* which is not a direct dependency of this plugin. They are accessible via
|
||||
* `AgentSessionResult.session` and `AgentRuntimeOptions.customTools` respectively.
|
||||
* The plugin runtime contract is defined locally in this example plugin to avoid
|
||||
* a hard compile-time dependency on internal engine package exports.
|
||||
*/
|
||||
|
||||
// ── Agent Runtime Contract (from @fusion/engine) ──────────────────────────────
|
||||
// ── Local Agent Runtime Contract ──────────────────────────────────────────────
|
||||
|
||||
/** Minimal session shape used by the runtime adapter. */
|
||||
export interface AgentSession {
|
||||
dispose?: () => Promise<void> | void;
|
||||
}
|
||||
|
||||
/** Options for creating an agent session. Mirrors createFnAgent inputs used by the adapter. */
|
||||
export interface AgentRuntimeOptions {
|
||||
cwd: string;
|
||||
systemPrompt: string;
|
||||
tools?: unknown;
|
||||
customTools?: unknown;
|
||||
onText?: (text: string) => void;
|
||||
onThinking?: (text: string) => void;
|
||||
onToolStart?: (toolName: string, args?: unknown) => void;
|
||||
onToolEnd?: (toolName: string, result?: unknown) => void;
|
||||
defaultProvider?: string;
|
||||
defaultModelId?: string;
|
||||
fallbackProvider?: string;
|
||||
fallbackModelId?: string;
|
||||
defaultThinkingLevel?: string;
|
||||
sessionManager?: unknown;
|
||||
skillSelection?: unknown;
|
||||
skills?: string[];
|
||||
}
|
||||
|
||||
/** Result of creating a session. */
|
||||
export interface AgentSessionResult {
|
||||
session: AgentSession;
|
||||
sessionFile?: string;
|
||||
}
|
||||
|
||||
/** Agent runtime adapter interface. */
|
||||
export interface AgentRuntime {
|
||||
id: string;
|
||||
name: string;
|
||||
createSession(options: AgentRuntimeOptions): Promise<AgentSessionResult>;
|
||||
promptWithFallback(session: AgentSession, prompt: string, options?: unknown): Promise<void>;
|
||||
describeModel(session: AgentSession): string;
|
||||
dispose?(session: AgentSession): Promise<void>;
|
||||
}
|
||||
|
||||
// ── Plugin Registration Types (from @fusion/plugin-sdk) ─────────────────────
|
||||
|
||||
export type {
|
||||
/**
|
||||
* Agent runtime adapter interface.
|
||||
*
|
||||
* All session runtimes (default pi runtime, plugin-provided runtimes) must
|
||||
* implement this interface to ensure consistent behavior across engine subsystems.
|
||||
*/
|
||||
AgentRuntime,
|
||||
/**
|
||||
* Options for creating an agent session.
|
||||
* Mirrors the options accepted by createFnAgent.
|
||||
*/
|
||||
AgentRuntimeOptions,
|
||||
/**
|
||||
* Result of creating an agent session.
|
||||
*/
|
||||
AgentSessionResult,
|
||||
} from "@fusion/engine";
|
||||
|
||||
// ── Plugin Registration Types (from @fusion/plugin-sdk) ───────────────────────
|
||||
|
||||
export type {
|
||||
/**
|
||||
* Plugin runtime registration metadata.
|
||||
* Contains identity and versioning information for a runtime.
|
||||
*/
|
||||
PluginRuntimeManifestMetadata,
|
||||
/**
|
||||
* Plugin runtime factory function.
|
||||
* Creates a runtime instance when the plugin is loaded.
|
||||
*/
|
||||
PluginRuntimeFactory,
|
||||
/**
|
||||
* Plugin runtime registration with metadata and factory.
|
||||
* The primary registration format used by Fusion's plugin system.
|
||||
*/
|
||||
PluginRuntimeRegistration,
|
||||
/**
|
||||
* Fusion plugin definition.
|
||||
* The main export type for all Fusion plugins.
|
||||
*/
|
||||
FusionPlugin,
|
||||
} from "@fusion/plugin-sdk";
|
||||
|
||||
// ── Note on describeModel ──────────────────────────────────────────────────────
|
||||
//
|
||||
// describeModel is NOT exported from @fusion/engine's public API.
|
||||
// It is defined in packages/engine/src/pi.ts but only used internally.
|
||||
// Plugin adapters should import describeModel directly from the relative path:
|
||||
// import { describeModel } from "../../engine/src/pi.js";
|
||||
//
|
||||
// This relative import is only valid within the monorepo workspace.
|
||||
// External plugins would need a different approach.
|
||||
|
||||
Reference in New Issue
Block a user