feat(FN-2307): merge fusion/fn-2307 (auto-resolved)
- docs(FN-2307): complete Step 3 — document Hermes runtime selection - test(FN-2307): complete Step 2 — add Hermes runtime compatibility tests - feat(FN-2307): complete Step 1 — align Hermes runtime metadata
This commit is contained in:
@@ -44,6 +44,32 @@ After installation, select the Paperclip runtime for an agent by setting `runtim
|
|||||||
|
|
||||||
For details on runtime selection, fallback behavior, and constraints, see the [Paperclip Runtime Plugin documentation](../plugins/fusion-plugin-paperclip-runtime/README.md).
|
For details on runtime selection, fallback behavior, and constraints, see the [Paperclip Runtime Plugin documentation](../plugins/fusion-plugin-paperclip-runtime/README.md).
|
||||||
|
|
||||||
|
### Optional: Install the Hermes Runtime Plugin (Experimental)
|
||||||
|
|
||||||
|
The Hermes Runtime Plugin (`fusion-plugin-hermes-runtime`) registers an experimental runtime hint (`"hermes"`) so agents can explicitly target Hermes in runtime selection.
|
||||||
|
|
||||||
|
Install the plugin:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
fn plugin add ./plugins/fusion-plugin-hermes-runtime
|
||||||
|
```
|
||||||
|
|
||||||
|
Configure an agent to use Hermes:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Hermes Executor",
|
||||||
|
"role": "executor",
|
||||||
|
"runtimeConfig": {
|
||||||
|
"runtimeHint": "hermes"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ Hermes is currently a deferred placeholder. Runtime registration and selection work, but execution intentionally reports "not implemented" until [FN-2264](https://github.com/gsxdsm/fusion/issues/FN-2264).
|
||||||
|
|
||||||
|
For Hermes-specific details, see the [Hermes Runtime Plugin documentation](../plugins/fusion-plugin-hermes-runtime/README.md).
|
||||||
|
|
||||||
## Install Fusion
|
## Install Fusion
|
||||||
|
|
||||||
Install the published CLI package globally:
|
Install the published CLI package globally:
|
||||||
|
|||||||
@@ -232,6 +232,7 @@ Fusion supports multiple agent runtimes through a plugin-based runtime system. T
|
|||||||
|------------|------|-------------|
|
|------------|------|-------------|
|
||||||
| `pi` | Default PI Runtime | Built-in runtime using the `pi` agent (default) |
|
| `pi` | Default PI Runtime | Built-in runtime using the `pi` agent (default) |
|
||||||
| `paperclip` | Paperclip Runtime | Plugin-provided runtime (requires `fusion-plugin-paperclip-runtime`) |
|
| `paperclip` | Paperclip Runtime | Plugin-provided runtime (requires `fusion-plugin-paperclip-runtime`) |
|
||||||
|
| `hermes` | Hermes Runtime (experimental) | Plugin-provided experimental runtime hint (requires `fusion-plugin-hermes-runtime`; execution deferred to FN-2264) |
|
||||||
|
|
||||||
### Runtime Resolution Order
|
### Runtime Resolution Order
|
||||||
|
|
||||||
@@ -239,7 +240,7 @@ When creating an agent session, Fusion resolves the runtime as follows:
|
|||||||
|
|
||||||
1. **No `runtimeHint` configured** → Use default `pi` runtime
|
1. **No `runtimeHint` configured** → Use default `pi` runtime
|
||||||
2. **`runtimeHint` is `"pi"` or `"default"`** → Use default `pi` runtime
|
2. **`runtimeHint` is `"pi"` or `"default"`** → Use default `pi` runtime
|
||||||
3. **`runtimeHint` is a plugin runtime ID** (e.g., `"paperclip"`) → Look up and instantiate the plugin runtime
|
3. **`runtimeHint` is a plugin runtime ID** (e.g., `"paperclip"` or `"hermes"`) → Look up and instantiate the plugin runtime
|
||||||
4. **Plugin runtime unavailable** → Fall back to default `pi` runtime (with warning log)
|
4. **Plugin runtime unavailable** → Fall back to default `pi` runtime (with warning log)
|
||||||
|
|
||||||
### Configuring Runtime Selection
|
### Configuring Runtime Selection
|
||||||
@@ -256,6 +257,18 @@ Runtime selection is configured at the **agent level** via `runtimeConfig.runtim
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Hermes Executor",
|
||||||
|
"role": "executor",
|
||||||
|
"runtimeConfig": {
|
||||||
|
"runtimeHint": "hermes"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ `runtimeHint: "hermes"` is currently experimental and deferred. Runtime resolution works, but execution remains intentionally unimplemented until FN-2264.
|
||||||
|
|
||||||
**Important:** There is no task-level runtime configuration. Tasks inherit the runtime from their assigned agent's `runtimeConfig`.
|
**Important:** There is no task-level runtime configuration. Tasks inherit the runtime from their assigned agent's `runtimeConfig`.
|
||||||
|
|
||||||
### Fallback Behavior
|
### Fallback Behavior
|
||||||
@@ -263,22 +276,23 @@ Runtime selection is configured at the **agent level** via `runtimeConfig.runtim
|
|||||||
If a configured runtime is unavailable (plugin not installed, not enabled, or factory error), Fusion logs a warning and falls back to the default `pi` runtime:
|
If a configured runtime is unavailable (plugin not installed, not enabled, or factory error), Fusion logs a warning and falls back to the default `pi` runtime:
|
||||||
|
|
||||||
```
|
```
|
||||||
[runtime-resolver] [executor] Runtime "paperclip" unavailable (not_found), falling back to default pi runtime
|
[runtime-resolver] [executor] Runtime "hermes" unavailable (not_found), falling back to default pi runtime
|
||||||
```
|
```
|
||||||
|
|
||||||
The fallback ensures tasks continue executing even if the configured runtime plugin is unavailable.
|
The fallback ensures tasks continue executing even if the configured runtime plugin is unavailable.
|
||||||
|
|
||||||
### Installing Plugin Runtimes
|
### Installing Plugin Runtimes
|
||||||
|
|
||||||
To use a plugin-provided runtime like Paperclip:
|
To use plugin-provided runtimes like Paperclip or Hermes:
|
||||||
|
|
||||||
1. Install the plugin:
|
1. Install one or both plugins:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
fn plugin add ./plugins/fusion-plugin-paperclip-runtime
|
fn plugin add ./plugins/fusion-plugin-paperclip-runtime
|
||||||
|
fn plugin add ./plugins/fusion-plugin-hermes-runtime
|
||||||
```
|
```
|
||||||
|
|
||||||
2. Create an agent with the appropriate `runtimeConfig`:
|
2. Create agents with the appropriate `runtimeConfig`:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -290,9 +304,19 @@ fn plugin add ./plugins/fusion-plugin-paperclip-runtime
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Hermes Executor",
|
||||||
|
"role": "executor",
|
||||||
|
"runtimeConfig": {
|
||||||
|
"runtimeHint": "hermes"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
3. Assign the agent to tasks that should use this runtime.
|
3. Assign the agent to tasks that should use this runtime.
|
||||||
|
|
||||||
For more details, see the [Paperclip Runtime Plugin documentation](../plugins/fusion-plugin-paperclip-runtime/README.md).
|
For more details, see the [Paperclip Runtime Plugin documentation](../plugins/fusion-plugin-paperclip-runtime/README.md) and [Hermes Runtime Plugin documentation](../plugins/fusion-plugin-hermes-runtime/README.md).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@@ -424,7 +448,7 @@ To clear all overrides, set `promptOverrides` to `null`:
|
|||||||
|
|
||||||
### 4) Agent runtime configuration (example agent config)
|
### 4) Agent runtime configuration (example agent config)
|
||||||
|
|
||||||
Runtime selection is configured at the agent level via `runtimeConfig`. This example shows an agent configured to use the Paperclip runtime:
|
Runtime selection is configured at the agent level via `runtimeConfig`. These examples show agents configured to use Paperclip and Hermes runtime hints:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
@@ -436,16 +460,28 @@ Runtime selection is configured at the agent level via `runtimeConfig`. This exa
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
To create this agent via the API:
|
```json
|
||||||
|
{
|
||||||
|
"name": "Hermes Executor",
|
||||||
|
"role": "executor",
|
||||||
|
"runtimeConfig": {
|
||||||
|
"runtimeHint": "hermes"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ Hermes remains experimental/deferred (FN-2264). Runtime hint selection is available now; full runtime execution behavior is not.
|
||||||
|
|
||||||
|
To create a Hermes-configured agent via the API:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -X POST http://localhost:4040/api/agents \
|
curl -X POST http://localhost:4040/api/agents \
|
||||||
-H "Content-Type: application/json" \
|
-H "Content-Type: application/json" \
|
||||||
-d '{
|
-d '{
|
||||||
"name": "Paperclip Executor",
|
"name": "Hermes Executor",
|
||||||
"role": "executor",
|
"role": "executor",
|
||||||
"runtimeConfig": {
|
"runtimeConfig": {
|
||||||
"runtimeHint": "paperclip"
|
"runtimeHint": "hermes"
|
||||||
}
|
}
|
||||||
}'
|
}'
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -914,6 +914,90 @@ describe("PluginRunner", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("Hermes runtime compatibility", () => {
|
||||||
|
it("should resolve hermes runtime when registered", () => {
|
||||||
|
const hermesRuntime = {
|
||||||
|
metadata: {
|
||||||
|
runtimeId: "hermes",
|
||||||
|
name: "Hermes Runtime",
|
||||||
|
description: "Experimental Hermes runtime integration for Fusion tasks (implementation deferred to FN-2264)",
|
||||||
|
version: "0.1.0",
|
||||||
|
},
|
||||||
|
factory: vi.fn().mockReturnValue({}),
|
||||||
|
};
|
||||||
|
mockPluginLoader.getPluginRuntimes.mockReturnValue([
|
||||||
|
{ pluginId: "fusion-plugin-hermes-runtime", runtime: hermesRuntime as any },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const result = pluginRunner.getRuntimeById("hermes");
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
expect(result?.pluginId).toBe("fusion-plugin-hermes-runtime");
|
||||||
|
expect(result?.runtime.metadata.runtimeId).toBe("hermes");
|
||||||
|
expect(result?.runtime.metadata.name).toBe("Hermes Runtime");
|
||||||
|
expect(result?.runtime.metadata.description).toContain("deferred to FN-2264");
|
||||||
|
expect(result?.runtime.metadata.version).toBe("0.1.0");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should expose hermes runtime metadata correctly", () => {
|
||||||
|
const hermesRuntime = {
|
||||||
|
metadata: {
|
||||||
|
runtimeId: "hermes",
|
||||||
|
name: "Hermes Runtime",
|
||||||
|
description: "Experimental Hermes runtime integration for Fusion tasks (implementation deferred to FN-2264)",
|
||||||
|
version: "0.1.0",
|
||||||
|
},
|
||||||
|
factory: vi.fn().mockReturnValue({}),
|
||||||
|
};
|
||||||
|
mockPluginLoader.getPluginRuntimes.mockReturnValue([
|
||||||
|
{ pluginId: "fusion-plugin-hermes-runtime", runtime: hermesRuntime as any },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const runtimes = pluginRunner.getPluginRuntimes();
|
||||||
|
const hermes = runtimes.find(r => r.runtime.metadata.runtimeId === "hermes");
|
||||||
|
|
||||||
|
expect(hermes).toBeDefined();
|
||||||
|
expect(hermes?.runtime.metadata).toEqual({
|
||||||
|
runtimeId: "hermes",
|
||||||
|
name: "Hermes Runtime",
|
||||||
|
description: "Experimental Hermes runtime integration for Fusion tasks (implementation deferred to FN-2264)",
|
||||||
|
version: "0.1.0",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should allow factory invocation for hermes runtime", async () => {
|
||||||
|
const hermesPlaceholderRuntime = {
|
||||||
|
runtimeId: "hermes",
|
||||||
|
version: "0.1.0",
|
||||||
|
status: "deferred",
|
||||||
|
message: "Hermes runtime implementation is deferred to FN-2264.",
|
||||||
|
execute: vi.fn().mockRejectedValue(new Error("FN-2264")),
|
||||||
|
};
|
||||||
|
const hermesRuntime = {
|
||||||
|
metadata: {
|
||||||
|
runtimeId: "hermes",
|
||||||
|
name: "Hermes Runtime",
|
||||||
|
description: "Experimental Hermes runtime integration for Fusion tasks (implementation deferred to FN-2264)",
|
||||||
|
version: "0.1.0",
|
||||||
|
},
|
||||||
|
factory: vi.fn().mockReturnValue(hermesPlaceholderRuntime),
|
||||||
|
};
|
||||||
|
mockPluginLoader.getPluginRuntimes.mockReturnValue([
|
||||||
|
{ pluginId: "fusion-plugin-hermes-runtime", runtime: hermesRuntime as any },
|
||||||
|
]);
|
||||||
|
|
||||||
|
const result = pluginRunner.getRuntimeById("hermes");
|
||||||
|
expect(result).toBeDefined();
|
||||||
|
|
||||||
|
const context = { pluginId: "fusion-plugin-hermes-runtime" };
|
||||||
|
const runtime = await result!.runtime.factory(context as any) as typeof hermesPlaceholderRuntime;
|
||||||
|
|
||||||
|
expect(hermesRuntime.factory).toHaveBeenCalledWith(context);
|
||||||
|
expect(runtime).toBe(hermesPlaceholderRuntime);
|
||||||
|
expect(runtime.runtimeId).toBe("hermes");
|
||||||
|
expect(runtime.status).toBe("deferred");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("getLoader() / getStore()", () => {
|
describe("getLoader() / getStore()", () => {
|
||||||
it("should return the plugin loader", () => {
|
it("should return the plugin loader", () => {
|
||||||
const loader = pluginRunner.getLoader();
|
const loader = pluginRunner.getLoader();
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ cp -r fusion-plugin-hermes-runtime ~/.fusion/plugins/
|
|||||||
### Option 2: Install via CLI
|
### Option 2: Install via CLI
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
fn plugin install /path/to/fusion-plugin-hermes-runtime
|
fn plugin add ./plugins/fusion-plugin-hermes-runtime
|
||||||
```
|
```
|
||||||
|
|
||||||
## Current Status
|
## Current Status
|
||||||
@@ -42,11 +42,25 @@ fn plugin install /path/to/fusion-plugin-hermes-runtime
|
|||||||
|
|
||||||
The plugin registers a runtime with the following metadata:
|
The plugin registers a runtime with the following metadata:
|
||||||
|
|
||||||
- **Runtime ID:** `hermes-runtime`
|
- **Runtime ID:** `hermes`
|
||||||
- **Name:** `Hermes AI Runtime`
|
- **Name:** `Hermes Runtime`
|
||||||
- **Description:** AI agent execution runtime for Fusion tasks
|
- **Description:** Experimental Hermes runtime integration for Fusion tasks (implementation deferred to FN-2264)
|
||||||
- **Version:** `0.1.0`
|
- **Version:** `0.1.0`
|
||||||
|
|
||||||
|
To route an agent to Hermes, set `runtimeConfig.runtimeHint` to `"hermes"`:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"name": "Hermes Executor",
|
||||||
|
"role": "executor",
|
||||||
|
"runtimeConfig": {
|
||||||
|
"runtimeHint": "hermes"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> ⚠️ Hermes is currently an experimental placeholder runtime. Session creation succeeds, but `execute()` intentionally throws until FN-2264 is implemented.
|
||||||
|
|
||||||
### Deferred Implementation
|
### Deferred Implementation
|
||||||
|
|
||||||
The runtime factory currently returns a placeholder object. When `execute()` is called, it throws an error referencing FN-2264:
|
The runtime factory currently returns a placeholder object. When `execute()` is called, it throws an error referencing FN-2264:
|
||||||
@@ -90,9 +104,9 @@ The plugin includes comprehensive tests covering:
|
|||||||
"author": "Fusion Team",
|
"author": "Fusion Team",
|
||||||
"homepage": "https://github.com/gsxdsm/fusion",
|
"homepage": "https://github.com/gsxdsm/fusion",
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"runtimeId": "hermes-runtime",
|
"runtimeId": "hermes",
|
||||||
"name": "Hermes AI Runtime",
|
"name": "Hermes Runtime",
|
||||||
"description": "AI agent execution runtime for Fusion tasks",
|
"description": "Experimental Hermes runtime integration for Fusion tasks (implementation deferred to FN-2264)",
|
||||||
"version": "0.1.0"
|
"version": "0.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -105,7 +119,7 @@ The plugin exports the following for testing and verification:
|
|||||||
- `default` - The FusionPlugin instance
|
- `default` - The FusionPlugin instance
|
||||||
- `hermesRuntimeMetadata` - Runtime manifest metadata object
|
- `hermesRuntimeMetadata` - Runtime manifest metadata object
|
||||||
- `hermesRuntimeFactory` - Factory function for creating runtime instances
|
- `hermesRuntimeFactory` - Factory function for creating runtime instances
|
||||||
- `HERMES_RUNTIME_ID` - Runtime ID constant (`"hermes-runtime"`)
|
- `HERMES_RUNTIME_ID` - Runtime ID constant (`"hermes"`)
|
||||||
|
|
||||||
## Related
|
## Related
|
||||||
|
|
||||||
|
|||||||
@@ -6,9 +6,9 @@
|
|||||||
"author": "Fusion Team",
|
"author": "Fusion Team",
|
||||||
"homepage": "https://github.com/gsxdsm/fusion",
|
"homepage": "https://github.com/gsxdsm/fusion",
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"runtimeId": "hermes-runtime",
|
"runtimeId": "hermes",
|
||||||
"name": "Hermes AI Runtime",
|
"name": "Hermes Runtime",
|
||||||
"description": "AI agent execution runtime for Fusion tasks",
|
"description": "Experimental Hermes runtime integration for Fusion tasks (implementation deferred to FN-2264)",
|
||||||
"version": "0.1.0"
|
"version": "0.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,8 @@ describe("hermes-runtime plugin", () => {
|
|||||||
it("should have correct runtime metadata", () => {
|
it("should have correct runtime metadata", () => {
|
||||||
expect(plugin.runtime?.metadata).toBeDefined();
|
expect(plugin.runtime?.metadata).toBeDefined();
|
||||||
expect(plugin.runtime?.metadata.runtimeId).toBe(HERMES_RUNTIME_ID);
|
expect(plugin.runtime?.metadata.runtimeId).toBe(HERMES_RUNTIME_ID);
|
||||||
expect(plugin.runtime?.metadata.name).toBe("Hermes AI Runtime");
|
expect(plugin.runtime?.metadata.name).toBe("Hermes Runtime");
|
||||||
|
expect(plugin.runtime?.metadata.description).toContain("deferred to FN-2264");
|
||||||
expect(plugin.runtime?.metadata.version).toBe("0.1.0");
|
expect(plugin.runtime?.metadata.version).toBe("0.1.0");
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -151,8 +152,8 @@ describe("hermes-runtime plugin", () => {
|
|||||||
describe("deferred implementation behavior", () => {
|
describe("deferred implementation behavior", () => {
|
||||||
it("should export hermesRuntimeMetadata", () => {
|
it("should export hermesRuntimeMetadata", () => {
|
||||||
expect(hermesRuntimeMetadata).toBeDefined();
|
expect(hermesRuntimeMetadata).toBeDefined();
|
||||||
expect(hermesRuntimeMetadata.runtimeId).toBe("hermes-runtime");
|
expect(hermesRuntimeMetadata.runtimeId).toBe("hermes");
|
||||||
expect(hermesRuntimeMetadata.name).toBe("Hermes AI Runtime");
|
expect(hermesRuntimeMetadata.name).toBe("Hermes Runtime");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should export hermesRuntimeFactory", () => {
|
it("should export hermesRuntimeFactory", () => {
|
||||||
@@ -161,7 +162,7 @@ describe("hermes-runtime plugin", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it("should export HERMES_RUNTIME_ID constant", () => {
|
it("should export HERMES_RUNTIME_ID constant", () => {
|
||||||
expect(HERMES_RUNTIME_ID).toBe("hermes-runtime");
|
expect(HERMES_RUNTIME_ID).toBe("hermes");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("runtime factory should return placeholder object", () => {
|
it("runtime factory should return placeholder object", () => {
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ import type {
|
|||||||
|
|
||||||
// ── Hermes Runtime Metadata ───────────────────────────────────────────────────
|
// ── Hermes Runtime Metadata ───────────────────────────────────────────────────
|
||||||
|
|
||||||
const HERMES_RUNTIME_ID = "hermes-runtime";
|
const HERMES_RUNTIME_ID = "hermes";
|
||||||
const HERMES_RUNTIME_VERSION = "0.1.0";
|
const HERMES_RUNTIME_VERSION = "0.1.0";
|
||||||
|
|
||||||
const hermesRuntimeMetadata: PluginRuntimeManifestMetadata = {
|
const hermesRuntimeMetadata: PluginRuntimeManifestMetadata = {
|
||||||
runtimeId: HERMES_RUNTIME_ID,
|
runtimeId: HERMES_RUNTIME_ID,
|
||||||
name: "Hermes AI Runtime",
|
name: "Hermes Runtime",
|
||||||
description: "AI agent execution runtime for Fusion tasks",
|
description: "Experimental Hermes runtime integration for Fusion tasks (implementation deferred to FN-2264)",
|
||||||
version: HERMES_RUNTIME_VERSION,
|
version: HERMES_RUNTIME_VERSION,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user