Files
fusion/plugins/fusion-plugin-hermes-runtime/dist/runtime-adapter.js
semih 3578a96561 Merge upstream/main (1547 commits) into local main
Resolved 7 conflicts and reconciled local patches with upstream's evolved API:

- packages/core/src/plugin-loader.ts: dropped local createContextFor()/buildContext()
  in favor of upstream's createRouteContext() which provides the same TaskStore-
  override capability our patch added.

- packages/dashboard/src/routes.ts: removed local manual plugin-route mounter
  (upstream's createPluginRouter handles this with richer response support);
  kept registerPluginExemptPath loop so external webhook plugins (telemetry-
  watcher, Grafana/Sentry) still bypass daemon-token auth. Removed obsolete
  resolveHeartbeatMonitorFor (replaced by upstream's resolveHeartbeatMonitor).

- packages/dashboard/src/routes/register-agent-runtime-routes.ts: ported
  4 call sites to upstream's isHeartbeatMonitorForProject + resolveHeartbeatMonitor
  dual-fallback pattern (multi-project monitor resolution).

- packages/cli/package.json: combined upstream's pi-ai 0.73.0 + dockerode
  bumps with our cross-spawn dep for vendored pi-claude-cli.

- pnpm-workspace.yaml: kept telemetry-watcher entry alongside upstream's new
  plugin entries (droid-runtime, cursor-runtime, agent-browser, whatsapp-chat,
  roadmap, even-realities-glasses, even-cards, reports).

- packages/dashboard/app/components/SetupWizardModal.css: kept z-index:110
  fix (wizard stacks above ModelOnboardingModal) and added upstream's
  overflow-y/overscroll-behavior on .setup-wizard-overlay.

- pnpm-lock.yaml: took upstream verbatim; pnpm install regenerated to
  include cross-spawn.

Typechecks: @fusion/core and @fusion/dashboard pass cleanly.
2026-05-11 08:24:34 +00:00

84 lines
3.5 KiB
JavaScript

/**
* Hermes Runtime Adapter — drives the local `hermes` CLI as a subprocess.
*
* Each call to `promptWithFallback` invokes `hermes chat -q ... -Q --source tool`
* and captures the resulting `session_id:` line. Subsequent calls on the same
* session pass `--resume <id>` to continue the conversation.
*/
import { invokeHermesCli, resolveCliSettings } from "./cli-spawn.js";
function buildRuntimeContextSection(options) {
const skillNames = Array.isArray(options.skills) ? options.skills.filter((value) => typeof value === "string" && value.trim().length > 0) : [];
const skillSelection = options.skillSelection;
const selectionSkillNames = Array.isArray(skillSelection?.requestedSkillNames)
? skillSelection.requestedSkillNames.filter((value) => typeof value === "string" && value.trim().length > 0)
: [];
const mergedSkills = skillNames.length > 0 ? skillNames : selectionSkillNames;
const lines = [
"Fusion runtime context:",
`- Tool mode: ${options.tools ?? "coding"}`,
];
if (mergedSkills.length > 0) {
lines.push(`- Requested skills: ${mergedSkills.join(", ")}`);
}
lines.push("- If fn_* tools are available in your runtime, use them directly for coordination/memory/task actions.");
return lines.join("\n");
}
export class HermesRuntimeAdapter {
id = "hermes";
name = "Hermes Runtime";
settings;
constructor(settings) {
this.settings = resolveCliSettings(settings);
}
async createSession(options) {
const session = {
model: undefined,
systemPrompt: options.systemPrompt,
messages: [],
apiKey: undefined,
thinkingLevel: undefined,
sessionId: "",
lastModelDescription: this.describeFromSettings(),
callbacks: {
onText: options.onText,
onThinking: options.onThinking,
onToolStart: options.onToolStart,
onToolEnd: options.onToolEnd,
},
runtimeContext: options.runtimeContext,
fusedSystemPrompt: [options.systemPrompt.trim(), buildRuntimeContextSection(options).trim()].filter((part) => part.length > 0).join("\n\n"),
dispose: () => undefined,
};
return { session, sessionFile: undefined };
}
async promptWithFallback(session, prompt, _options) {
const resumeId = session.sessionId || undefined;
const promptWithContext = resumeId
? prompt
: `${session.fusedSystemPrompt}\n\nUser request:\n${prompt}`;
const result = await invokeHermesCli(promptWithContext, this.settings, resumeId);
session.sessionId = result.sessionId;
session.lastModelDescription = this.describeFromSettings();
if (result.body) {
session.callbacks.onText?.(result.body);
}
}
describeModel(session) {
return session.lastModelDescription || this.describeFromSettings();
}
async dispose(_session) {
// No persistent resources to release — the hermes CLI process exits per turn.
}
describeFromSettings() {
const provider = this.settings.provider;
const model = this.settings.model;
if (provider && model)
return `hermes/${provider}/${model}`;
if (model)
return `hermes/${model}`;
if (provider)
return `hermes/${provider}`;
return "hermes";
}
}
//# sourceMappingURL=runtime-adapter.js.map