{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"event-context-panel","type":"registry:component","title":"EventContextPanel","description":"Client event context panel that uses @ekairos/events/react directly.","files":[{"path":"registry/default/ekairos/events/event-context-panel.tsx","type":"registry:component","content":"\"use client\";\n\nimport { type FormEvent, useMemo, useState } from \"react\";\nimport {\n  INPUT_TEXT_ITEM_TYPE,\n  type AppendArgs,\n  type ContextEventForUI,\n  type ReasoningLevel,\n  useContext,\n} from \"@ekairos/events/react\";\n\nexport type EventContextPanelProps = {\n  db: any;\n  apiUrl: string;\n  initialContextId?: string;\n  contextKey?: string;\n  onContextUpdate?: (contextId: string) => void;\n  prepareAppendArgs?: (args: AppendArgs) => Promise<AppendArgs> | AppendArgs;\n  prepareRequestBody?: (params: {\n    messages: any[];\n    webSearch?: boolean;\n    reasoningLevel?: ReasoningLevel;\n    contextId?: string;\n  }) => Promise<Record<string, unknown>> | Record<string, unknown>;\n  streamChunkDelayMs?: number;\n  className?: string;\n  placeholder?: string;\n  defaultPrompt?: string;\n  webSearch?: boolean;\n  reasoningLevel?: ReasoningLevel;\n};\n\nfunction cx(...values: Array<string | false | null | undefined>) {\n  return values.filter(Boolean).join(\" \");\n}\n\nfunction readEventText(event: ContextEventForUI) {\n  const parts = Array.isArray(event.content?.parts) ? event.content.parts : [];\n  const text = parts\n    .map((part: any) => {\n      if (typeof part?.text === \"string\") return part.text;\n      if (typeof part?.content === \"string\") return part.content;\n      return \"\";\n    })\n    .filter(Boolean)\n    .join(\"\\n\");\n\n  return text || event.type || event.id;\n}\n\nfunction getRole(event: ContextEventForUI) {\n  const type = String(event.type ?? \"\");\n  return type === INPUT_TEXT_ITEM_TYPE || type === \"input\" || type.startsWith(\"user.\")\n    ? \"user\"\n    : \"assistant\";\n}\n\nexport function EventContextPanel({\n  db,\n  apiUrl,\n  initialContextId,\n  contextKey,\n  onContextUpdate,\n  prepareAppendArgs,\n  prepareRequestBody,\n  streamChunkDelayMs,\n  className,\n  placeholder = \"Escribe el proximo mensaje del contexto...\",\n  defaultPrompt = \"\",\n  webSearch,\n  reasoningLevel,\n}: EventContextPanelProps) {\n  const [draft, setDraft] = useState(defaultPrompt);\n  const context = useContext(db, {\n    apiUrl,\n    initialContextId,\n    contextKey,\n    onContextUpdate,\n    prepareAppendArgs,\n    prepareRequestBody,\n    streamChunkDelayMs,\n  });\n\n  const messages = useMemo(\n    () =>\n      context.events.map((event) => ({\n        id: event.id,\n        role: getRole(event),\n        text: readEventText(event),\n        status: event.status,\n      })),\n    [context.events]\n  );\n\n  const isSending = context.sendStatus === \"submitting\";\n  const canSend = draft.trim().length > 0 && !isSending;\n\n  async function submit(event: FormEvent<HTMLFormElement>) {\n    event.preventDefault();\n    if (!canSend) return;\n\n    const text = draft.trim();\n    setDraft(\"\");\n    await context.append({\n      parts: [{ type: \"text\", text }],\n      webSearch,\n      reasoningLevel,\n    });\n  }\n\n  return (\n    <section\n      className={cx(\n        \"flex h-full min-h-[520px] flex-col overflow-hidden border border-border bg-background text-foreground\",\n        className\n      )}\n    >\n      <header className=\"border-b border-border px-4 py-3\">\n        <div className=\"flex items-center justify-between gap-3\">\n          <div>\n            <p className=\"text-xs font-medium uppercase tracking-[0.14em] text-muted-foreground\">\n              Event context\n            </p>\n            <h2 className=\"mt-1 text-lg font-semibold\">Live context panel</h2>\n          </div>\n          <span className=\"border border-border px-2.5 py-1 text-xs text-muted-foreground\">\n            {context.contextStatus}\n          </span>\n        </div>\n      </header>\n\n      <div className=\"min-h-0 flex-1 space-y-3 overflow-y-auto p-4\">\n        {messages.length === 0 ? (\n          <div className=\"flex h-full items-center justify-center text-sm text-muted-foreground\">\n            No events yet.\n          </div>\n        ) : (\n          messages.map((message) => (\n            <article\n              key={message.id}\n              className={cx(\n                \"max-w-[82%] border border-border px-3 py-2 text-sm leading-6\",\n                message.role === \"user\"\n                  ? \"ml-auto bg-primary text-primary-foreground\"\n                  : \"bg-card text-card-foreground\"\n              )}\n            >\n              <div className=\"mb-1 text-[11px] font-medium uppercase tracking-[0.12em] opacity-70\">\n                {message.role}\n                {message.status ? ` / ${message.status}` : \"\"}\n              </div>\n              <p className=\"whitespace-pre-wrap\">{message.text}</p>\n            </article>\n          ))\n        )}\n      </div>\n\n      {context.sendError ? (\n        <p className=\"border-t border-border px-4 py-2 text-sm text-destructive\">\n          {context.sendError}\n        </p>\n      ) : null}\n\n      <form className=\"border-t border-border p-3\" onSubmit={submit}>\n        <div className=\"flex gap-2\">\n          <textarea\n            className=\"min-h-20 flex-1 resize-none border border-border bg-background px-3 py-2 text-sm outline-none focus:border-foreground\"\n            placeholder={placeholder}\n            value={draft}\n            onChange={(event) => setDraft(event.target.value)}\n          />\n          <button\n            type=\"submit\"\n            disabled={!canSend}\n            className=\"self-end bg-foreground px-4 py-2 text-sm font-medium text-background disabled:cursor-not-allowed disabled:opacity-50\"\n          >\n            {isSending ? \"Sending\" : \"Send\"}\n          </button>\n        </div>\n      </form>\n    </section>\n  );\n}\n","target":"components/ekairos/events/event-context-panel.tsx"}],"dependencies":["@ekairos/events@beta"],"devDependencies":[],"registryDependencies":[]}