Agents
ThinkingBox
Max's thinking box: the running account of what he thought, which tools he called, what he sent and what came back.
Guidelines#
It stays open while he works and folds to one line once he answers.
Use it for the working-out above an agent reply. It styles correctly only inside an element with the maxchat class.
What you provide
steps:ThinkingStep[]frombuildThinkingSteps: thoughts{ kind: "thought", id, text, live }and tools{ kind: "tool", id, name, label, phase, input?, output?, errorText? }, wherephaseis running, done or error.streaming: whether Max is still working.
Anatomy (.mx-think*)
- A 1px
--mx-lineborder and a 10px radius, tinted--mx-aipurple while live. - The 12.5px/550 header names the running tool with a shimmering title and a seconds counter. Afterwards it reads "Here's how I got there" with a summary such as "2 thoughts · 3 tools".
- Thoughts are 12.5px italic
--mx-ink-3behind a 2px rule, purple while live. - Tool rows are 8px-radius cards with a 7px dot: purple and pulsing while running,
--mx-newgreen when done, red when failed. A click reveals "Sent" and "Got back" (or "Error") in an 11px mono block, at most 220px tall.
Motion: the box rises in with mx-in (6px, 0.3s, cubic-bezier(0.16, 1, 0.3, 1)). The title shimmers on a 2000ms loop, and the spark and running dots pulse. Reduced motion stops all three.
Don't hide failed calls or cut payloads silently: long results end with a visible marker.
Facts#
| Group | Agents |
|---|---|
| Product | Max |
| Global | window.DigitalCrew.ThinkingBox |
| Source | max-agent: src/features/agent/ui/thinking-box.tsx |
| Import in the app | import { ThinkingBox } from "@/features/agent/ui/thinking-box"; |
API#
TypeScript declarations emitted from src/features/agent/ui/thinking-box.tsx.
export declare const ThinkingBox: any;Example#
The code of the preview above: plain React.createElement against window.DigitalCrew, with realistic data.
<div id="root" class="p-6"></div>
<script>
(function () {
var h = React.createElement, DC = window.DigitalCrew, I = DC.Icons;
var LIVE = [
{ kind: "thought", id: "t1", live: false, text: "She asked for fintech CFOs in Paris who changed jobs this quarter. Start with LinkedIn, then enrich what comes back." },
{ kind: "tool", id: "call-1", name: "linkedin_search_people", label: "LinkedIn search people", phase: "done",
input: { title: "CFO OR \"Finance Director\"", industry: "Financial Services", location: "Île-de-France", changed_jobs_within_days: 90 },
output: { total: 14, returned: 14 } },
{ kind: "tool", id: "call-2", name: "enrich_contacts", label: "Enrich contacts", phase: "running", input: { prospect_ids: 14 } },
{ kind: "thought", id: "t2", live: true, text: "Three profiles have no company domain yet; I'll flag them instead of guessing." }
];
var DONE = [
LIVE[0], LIVE[1],
{ kind: "tool", id: "call-2", name: "enrich_contacts", label: "Enrich contacts", phase: "done", input: { prospect_ids: 14 }, output: { enriched: 11, missing_domain: 3 } },
{ kind: "tool", id: "call-3", name: "crm_create_list", label: "CRM create list", phase: "error", input: { name: "Fintech CFOs, Paris" }, errorText: "A list with this name already exists." },
{ kind: "thought", id: "t3", live: false, text: "Added them to the existing list instead." }
];
function Label(text) { return h("div", { className: "mb-1.5 text-[11px] font-medium uppercase tracking-wide text-muted-foreground" }, text); }
function App() {
return h("div", { className: "maxchat mx-auto max-w-[620px] gap-4 rounded-2xl border border-border/60 p-5", style: { height: "auto" } },
h("div", null, Label("While Max works"), h(DC.ThinkingBox, { steps: LIVE, streaming: true })),
h("div", null, Label("After he answers (click to reopen)"), h(DC.ThinkingBox, { steps: DONE, streaming: false }),
h("p", { className: "text-[14.5px] leading-relaxed", style: { color: "var(--mx-ink-2)" } },
"I found 14 CFOs who started a new role since July. Data found for 11 of 14; the other 3 need a company domain.")));
}
ReactDOM.createRoot(document.getElementById("root")).render(h(DC.TooltipProvider, { delayDuration: 80 }, h(App)));
})();
</script>