mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-16 19:00:38 +09:00
feat(hermes): upgrade hermes-paperclip-adapter + UI adapter + skills + detectModel
Upgrades hermes-paperclip-adapter from 0.1.1 to ^0.2.0 and wires in all new
capabilities introduced in v0.2.0:
Server
- Upgrade hermes-paperclip-adapter 0.1.1 -> ^0.2.0 (pending PR#10 merge)
- Wire listSkills + syncSkills from hermes-paperclip-adapter/server
- Add detectModel to hermesLocalAdapter (reads ~/.hermes/config.yaml)
- Add detectAdapterModel() function + /adapters/:type/detect-model route
- Export detectAdapterModel from server/src/adapters/index.ts
Types
- Add optional detectModel? to ServerAdapterModule in adapter-utils
UI
- Add hermes-paperclip-adapter ^0.2.0 to ui/package.json (for /ui exports)
- New ui/src/adapters/hermes-local/ — config fields + UI adapter module
- Register hermesLocalUIAdapter in UI adapter registry
- New HermesIcon (caduceus SVG) for adapter pickers
- AgentConfigForm: detect-model button, creatable model input, preserve
adapter-agnostic fields (env, promptTemplate) when switching adapter type
- NewAgentDialog + OnboardingWizard: add Hermes to adapter picker
- Agents, OrgChart, InviteLanding, NewAgent, agent-config-primitives: add
hermes_local label + enable in adapter sets
- AgentDetail: smarter run summary excerpt extraction
- RunTranscriptView: improved Hermes stdout rendering
NOTE: requires hermes-paperclip-adapter@0.2.0 on npm.
Blocked on NousResearch/hermes-paperclip-adapter#10 merging.
This commit is contained in:
parent
0ac01a04e5
commit
1583a2d65a
22 changed files with 634 additions and 33 deletions
|
|
@ -1075,10 +1075,28 @@ function LatestRunCard({ runs, agentId }: { runs: HeartbeatRun[]; agentId: strin
|
|||
const isLive = run.status === "running" || run.status === "queued";
|
||||
const statusInfo = runStatusIcons[run.status] ?? { icon: Clock, color: "text-neutral-400" };
|
||||
const StatusIcon = statusInfo.icon;
|
||||
const summary = run.resultJson
|
||||
const summaryRaw = run.resultJson
|
||||
? String((run.resultJson as Record<string, unknown>).summary ?? (run.resultJson as Record<string, unknown>).result ?? "")
|
||||
: run.error ?? "";
|
||||
|
||||
// Extract a clean 2-3 line excerpt: first non-empty, non-header, non-list-mark lines
|
||||
const summary = useMemo(() => {
|
||||
if (!summaryRaw) return "";
|
||||
const lines = summaryRaw
|
||||
.replace(/^#{1,6}\s+/gm, "")
|
||||
.split("\n")
|
||||
.map((l) => l.trim())
|
||||
.filter((l) => l.length > 0 && !l.startsWith("---") && !l.startsWith("|") && !l.startsWith("```"));
|
||||
const excerpt: string[] = [];
|
||||
let chars = 0;
|
||||
for (const line of lines) {
|
||||
if (excerpt.length >= 3 || chars + line.length > 280) break;
|
||||
excerpt.push(line);
|
||||
chars += line.length;
|
||||
}
|
||||
return excerpt.join(" ");
|
||||
}, [summaryRaw]);
|
||||
|
||||
return (
|
||||
<div className="space-y-3">
|
||||
<div className="flex w-full items-center justify-between">
|
||||
|
|
@ -2351,6 +2369,7 @@ function AgentSkillsTab({
|
|||
const queryClient = useQueryClient();
|
||||
const [skillDraft, setSkillDraft] = useState<string[]>([]);
|
||||
const [lastSavedSkills, setLastSavedSkills] = useState<string[]>([]);
|
||||
const [unmanagedOpen, setUnmanagedOpen] = useState(false);
|
||||
const lastSavedSkillsRef = useRef<string[]>([]);
|
||||
const hasHydratedSkillSnapshotRef = useRef(false);
|
||||
const skipNextSkillAutosaveRef = useRef(true);
|
||||
|
|
@ -2680,12 +2699,19 @@ function AgentSkillsTab({
|
|||
|
||||
{unmanagedSkillRows.length > 0 && (
|
||||
<section className="border-y border-border">
|
||||
<div className="border-b border-border bg-muted/40 px-3 py-2">
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
className="flex cursor-pointer items-center gap-2 border-b border-border bg-muted/40 px-3 py-2 select-none"
|
||||
onClick={() => setUnmanagedOpen((v) => !v)}
|
||||
onKeyDown={(e) => { if (e.key === "Enter" || e.key === " ") { e.preventDefault(); setUnmanagedOpen((v) => !v); } }}
|
||||
>
|
||||
<span className="text-xs font-medium text-muted-foreground">
|
||||
User-installed skills, not managed by Paperclip
|
||||
({unmanagedSkillRows.length}) User-installed skills, not managed by Paperclip
|
||||
</span>
|
||||
{unmanagedOpen ? <ChevronDown className="h-3.5 w-3.5 text-muted-foreground" /> : <ChevronRight className="h-3.5 w-3.5 text-muted-foreground" />}
|
||||
</div>
|
||||
{unmanagedSkillRows.map(renderSkillRow)}
|
||||
{unmanagedOpen && unmanagedSkillRows.map(renderSkillRow)}
|
||||
</section>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ const adapterLabels: Record<string, string> = {
|
|||
gemini_local: "Gemini",
|
||||
opencode_local: "OpenCode",
|
||||
cursor: "Cursor",
|
||||
hermes_local: "Hermes",
|
||||
openclaw_gateway: "OpenClaw Gateway",
|
||||
process: "Process",
|
||||
http: "HTTP",
|
||||
|
|
|
|||
|
|
@ -20,11 +20,12 @@ const adapterLabels: Record<string, string> = {
|
|||
pi_local: "Pi (local)",
|
||||
openclaw_gateway: "OpenClaw Gateway",
|
||||
cursor: "Cursor (local)",
|
||||
hermes_local: "Hermes Agent",
|
||||
process: "Process",
|
||||
http: "HTTP",
|
||||
};
|
||||
|
||||
const ENABLED_INVITE_ADAPTERS = new Set(["claude_local", "codex_local", "gemini_local", "opencode_local", "pi_local", "cursor"]);
|
||||
const ENABLED_INVITE_ADAPTERS = new Set(["claude_local", "codex_local", "gemini_local", "opencode_local", "pi_local", "cursor", "hermes_local"]);
|
||||
|
||||
function dateTime(value: string) {
|
||||
return new Date(value).toLocaleString();
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ const SUPPORTED_ADVANCED_ADAPTER_TYPES = new Set<CreateConfigValues["adapterType
|
|||
"opencode_local",
|
||||
"pi_local",
|
||||
"cursor",
|
||||
"hermes_local",
|
||||
"openclaw_gateway",
|
||||
]);
|
||||
|
||||
|
|
|
|||
|
|
@ -122,6 +122,7 @@ const adapterLabels: Record<string, string> = {
|
|||
gemini_local: "Gemini",
|
||||
opencode_local: "OpenCode",
|
||||
cursor: "Cursor",
|
||||
hermes_local: "Hermes",
|
||||
openclaw_gateway: "OpenClaw Gateway",
|
||||
process: "Process",
|
||||
http: "HTTP",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue