mirror of
https://github.com/alkimake/paperclip.git
synced 2026-06-19 04: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>
|
||||
)}
|
||||
</>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue