feat(api): agent identity + personality (makeup) file endpoints

- POST /nodes/:teamId/identity — set the on-board agent's name
  (agents.default.identity.name + reload) so it adopts the team's choice.
- GET/PUT /nodes/:teamId/personality/:file — proxy the node's
  /api/personality allowlist API (SOUL/IDENTITY/USER/AGENTS/TOOLS/
  HEARTBEAT/MEMORY), so the MAKEUP cards can read + overwrite the agent's
  makeup files and restart it. Both proxy the board gateway with the
  node's bearer token.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
This commit is contained in:
Omar Sobh
2026-07-27 10:55:34 +02:00
co-authored by Claude Opus 4.8
parent 0156f97b36
commit 0797923933
6 changed files with 141 additions and 0 deletions
+65
View File
@@ -0,0 +1,65 @@
import { useEffect } from 'react'
import { useNavigate } from 'react-router-dom'
import { AddLayerForm } from '@/components/AddLayerForm'
import { PanelHeading, ProceedButton } from '@/components/cockpit/PanelChrome'
import { useSession } from '@/store/session'
const L2_PREFILL =
'i2c_scan to enumerate both ADXL355Z; matrix_text and matrix_count for on-board readouts; adxl355_stream for live vibration.'
const L3_PREFILL =
'Report only on exception; escalate ambiguous or high-consequence calls to the cloud model; never suppress a stale-sensor alarm.'
export function Module2() {
const navigate = useNavigate()
const l2 = useSession((s) => s.add.L2)
const l3 = useSession((s) => s.add.L3)
const tried = useSession((s) => s.tried)
const setAddLayer = useSession((s) => s.setAddLayer)
const completePhase = useSession((s) => s.completePhase)
const ready = l2.trim().length > 0 && l3.trim().length > 0
// If the team ran the three agent prompts in "Meet your agent", seed Layers 2 & 3
// with a starting draft (only if untouched).
useEffect(() => {
if (tried < 3) return
if (!useSession.getState().add.L2.trim()) setAddLayer('L2', L2_PREFILL)
if (!useSession.getState().add.L3.trim()) setAddLayer('L3', L3_PREFILL)
}, [tried, setAddLayer])
const onProceed = () => {
completePhase('m2')
navigate('/workshop/add')
}
return (
<section>
<PanelHeading
title="Module 2 · Skills & policies"
intro="Capture what your agent can do and the policy that governs it — Layers 2 and 3 of your Agent Design Document."
size={46}
/>
<div className="mt-9 space-y-5">
<AddLayerForm
layer="L2"
title="ADD · Layer 2 — Skills"
description="What skills can the agent invoke to act on its domain?"
placeholder="Flash a sketch to the MCU; scroll a message; drive the damper; sample the IMU."
/>
<AddLayerForm
layer="L3"
title="ADD · Layer 3 — Policies & failure"
description="The actuation gate — and what happens when things break. A fail-safe must never quietly report 'normal'."
placeholder="Report only on exception; escalate ambiguous calls to the cloud; never suppress a stale-sensor alarm."
/>
</div>
<div className="mt-6 flex justify-end">
<ProceedButton disabled={!ready} onClick={onProceed}>
Proceed to Module 3 →
</ProceedButton>
</div>
</section>
)
}