@alexkroman1/aai-ui (英语)
用于 Assembly SDK 代理的浏览器客户端: 反应 19 个钩和 框架不可知会话核心的组件(WebSocket + 麦克风+) (原始内容存档于2017-03-25). play back).
npm i @alexkroman1/aai-ui react react-dom
每个特工都免费拿到UI.. aai dev 和部署的特工
默认客户端从此软件包中构建 。 代理时直接安装
其本身 client.tsx。 。 。 .
UI 整合
这里的钩子是一页 读到一个代理: 活电话,状态
代理项目,工具在运行时调用,以及它开始的持久运行.
没有路可写. 代理服务器已经为会话服务
套接字和工作流程 HTTP API, 所以组件对一个没有
介于两者之间的粘结文件 — 客户端是一个 client.tsx 呼叫一个山.
两道正门 二道山. 一个语音代理的页面呼叫 mountClient() 财务报告和审定财务报表
和现场谈话 一个工作流程应用程序的页面( A)workflowApp(),或
agent({ mode: "workflow-app" })(电话) mountPage() 与工作流程交谈
HTTP API — 没有会话, 没有插座, 没有麦克风 。 都还在 client.tsx, (中文(简体) ),
仍为回放,仍为同名主题符号.
探员 agent.ts
会话状态处于一个档位,一个档位宣布 sync: true 这是什么
浏览器所看见的 —— 在每个工具调用后按下, 所以客户端永远不会重建它
来自事件 :
import { agent, sessionSlot } from "@alexkroman1/aai";
const desk = sessionSlot("desk", () => ({ symbols: [] as string[] }), {
view: (state) => ({ symbols: state.symbols }),
sync: true,
});
// The `sync: true` slot is collected; the prompt is the system-prompt.md beside this file.
export default agent({ name: "Market Desk" });
工具 tools/get_quote.ts
一个工具是 文件,用它自己的文件名命名。 没有登记
agent() 采取不 tools 字段 :
import { tool } from "@alexkroman1/aai";
import { z } from "zod";
export default tool({
description: "Look up the latest price for one ticker symbol",
inputSchema: z.object({ symbol: z.string() }),
execute: async ({ symbol }, ctx) => {
const res = await fetch(`https://api.example.com/quote/${symbol}`, {
headers: { authorization: `Bearer ${ctx.env.QUOTES_API_KEY}` },
signal: ctx.signal,
});
return (await res.json()) as { symbol: string; price: number };
},
});
工具的 UI 组件 quote-card.tsx
useToolResult 每个定点调用一个命名工具时一次起火,结果
已解析 。 迟到的部分仍然收到通话结果
——结果是一种UI驱动的值,而不是a
秒数 :
import { useState } from "react";
import { useToolResult } from "@alexkroman1/aai-ui";
type Quote = { symbol: string; price: number };
export default function QuoteCard() {
const [quote, setQuote] = useState<Quote>();
useToolResult<Quote>("get_quote", (result) => setQuote(result));
if (!quote) return null;
return (
<p>
{quote.symbol} — {quote.price.toFixed(2)}
</p>
);
}
useToolCallStart 对电话的另一端是同一个钩子——待发
引用及其论点,为一个旋转者而不是一个价值。 一个
以工具本身的形状作为类型参数,由工具模块导出
只类型 导入被擦除后将服务器代码拖入捆绑中 :
useToolResult<InferToolOutput<typeof getQuote>>(…) 因此,
useToolCallStart<InferToolInput<typeof getQuote>>(…) 用来辩论.
客户端 client.tsx
mountClient() 挂载默认聊天 shell — 启动屏幕、 记录,
控制器 里面有你的组件. sidebar 拿走组件,不是
元素 :
import "@alexkroman1/aai-ui/styles.css";
import { mountClient, useAgentState } from "@alexkroman1/aai-ui";
import QuoteCard from "./quote-card.tsx";
function Watchlist() {
// The `desk` slot `syncState` projected, live. Null until the first push,
// which is a moment the UI has to render.
const desk = useAgentState<{ symbols: string[] }>("desk");
return (
<div>
<QuoteCard />
{desk?.symbols.map((symbol) => <div key={symbol}>{symbol}</div>)}
</div>
);
}
mountClient({
name: "Market Desk",
sidebar: Watchlist,
// Icon and label per tool, for the transcript's tool rows.
tools: { get_quote: { icon: "📈", label: "Fetching quote" } },
theme: { primary: "#2f9e44" },
});
上面的类型参数重现了代理已知道的形状 。 移动槽
并投射为a shared.ts 两端导入, 通过投影
本身 - useAgentState(deskProjection) - 州从
投影和它产生的前先推框架,所以没有什么
重复,没有分支 对于第一个渲染.
过 component 改为 sidebar 替换整个外壳。 它让
在同一个供应商内部, 所以这里的每一个钩 工作不变.
一个工作流程应用程序
mountPage() 将窗体挂载在代理工作流程上,并安装无会话.
<WorkflowFields> 使工作流程的每个平面属性有一个控制
输入 schema, 因此在 schema 中添加一个字段, 在页面中添加 :
import "@alexkroman1/aai-ui/styles.css";
import {
Form,
mountPage,
SubmitButton,
UploadProgressBar,
useWorkflowSubmit,
WorkflowFields,
WorkflowProgress,
} from "@alexkroman1/aai-ui";
function App() {
const { submitForm, run, pending, upload, error } =
useWorkflowSubmit("digest");
return (
<main className="mx-auto flex max-w-2xl flex-col gap-6 p-8">
<Form onSubmit={submitForm} error={error}>
<WorkflowFields workflow="digest" />
<SubmitButton pending={pending}>Summarize</SubmitButton>
</Form>
{/* The upload is its own wait: the run does not exist until the bytes
are in, so nothing else on the page can describe it. */}
<UploadProgressBar upload={upload} />
{/* What the run has SAID, from `stepReport()` in its steps. */}
<WorkflowProgress runId={run?.runId} />
{run?.status === "completed" && <pre>{JSON.stringify(run.output)}</pre>}
</main>
);
}
mountPage({ name: "Digest", component: App });
将工作流程命名为 def —— useWorkflowSubmit<typeof digest>("digest")关闭 a
只类型 进口 agent.ts - 这才是 submit() 带所申报的
输入和 run.status === "completed" 缩小为已键入 run.output编辑
导入已被删除, 因此它不会将服务器代码拖入捆绑中 .
包裹里有什么
这个 API 参考 按类型编组 有点 这是同样的表面 组合它是什么.
挂载 —— 说 mountClient(), (中文(简体) ), mountPage(),每个配置和
处理每个返回( e)ClientConfig, (中文(简体) ), ClientHandle, (中文(简体) ), PageConfig, (中文(简体) ),
PageHandle) (中文(简体) ). fetchClientConfig() {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}看经纪人的申报
name编号 :greeting 在页面上 mountClient() 是为了自己.
现场通话 —— 说 useSession() 整个快照加上控件
(单位:千美元)start, (中文(简体) ), toggle, (中文(简体) ), cancel, (中文(简体) ), reset, (中文(简体) ), resetState, (中文(简体) ), restart, (中文(简体) ), disconnect, (中文(简体) ),
end(三); useSessionSelector() 一个切片,用 useSessionStatus(), (中文(简体) ),
useSessionError() 财务报告和审定财务报表 useSessionActions() 因为狭义读取了一个习惯
铬重复; useUserTranscript() {\fn黑体\fs22\bord1\shad0\3ahbe\4ah00\fscx67\fscy66\2chffffff\3ch808080}因为呼叫者正在转弯
保留 null (沉闷)和 "" (口出相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相去相相相相去相相去相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相相; useConversation()
连结的笔录都没有. createBrowserSession()
与普通商店相同,每起变化都有不可改变的快照
非反应客户端. SessionSnapshot, (中文(简体) ), AgentState, (中文(简体) ), ChatMessage, (中文(简体) ),
ToolCallInfo, (中文(简体) ), SessionError 财务报告和审定财务报表 SessionErrorCode 带着它.
经纪人推着什么 —— 说 useAgentState(slot.projected) (该插槽的条目)
在经纪人的 syncState· ; selectAgentState(slot) 页:1 useSessionSelector, (中文(简体) ),
useToolResult() 编号 : useToolCallStart() (工具唤作跑道)
useEvent() (来自 ctx.send,在新代码中更喜欢的
在阅读工具结果之后).
聊天铬 —— 说 ChatView 整个地表; ConsoleShell, (中文(简体) ),
MessageList, (中文(简体) ), Controls, (中文(简体) ), Markdown, (中文(简体) ), ToolCallRow, (中文(简体) ), SessionErrorBanner, (中文(简体) ),
StartScreen, (中文(简体) ), SidebarLayout, (中文(简体) ), AutoScroll, (中文(简体) ), BulletList, (中文(简体) ), Facts 财务报告和审定财务报表 Button
是它的部件,出口到一个定制的铬再利用它们而不是近似
他们. AutoScroll 这是直接接触的:这是唯一的
在这里滚动连接执行,它需要一个 边界高度。 。 。 .
AGENT_STATE_LABELS 财务报告和审定财务报表 WORKFLOW_STATUS_LABELS 是默认状态的单词,
所以一个铬 超过一个词 它有一个更好的词.
表单 —— 说 Form 提交时从 DOM 中收集输入的值. Field, (中文(简体) ),
TextField, (中文(简体) ), NumberField, (中文(简体) ), TextAreaField, (中文(简体) ), SelectField, (中文(简体) ), CheckboxField, (中文(简体) ),
FileField 财务报告和审定财务报表 SubmitButton 是控件; WorkflowFields 生成它们
从一个计划。 一个平地 <input name="x"> 一样的工作.
工作流量 —— 说 createWorkflowApi() 是客户端; useWorkflowSubmit() 编号 :
useWorkflowStream() 开始看它, useWorkflowRun() (观看一个
页:1, useWorkflowRuns() (历史), useWorkflowProgress() (跑步有什麽事)
写作, useWorkflows() (清单), useDownloadUrl() (上传运行)
作为DOM元素接受的URL生产, useRunKey() (存储后键)
(a) 提交材料由收回). <WorkflowProgress> 财务报告和审定财务报表 <UploadProgressBar>
即所化为二分之一. WorkflowRun, (中文(简体) ), WorkflowSummary, (中文(简体) ), WorkflowInputOf, (中文(简体) ),
WorkflowOutputOf 财务报告和审定财务报表 isTerminal() 是词汇.
主题 —— 说 useTheme() 财务报告和审定财务报表 ClientTheme。 。 。 .
其他子路径
根导出是整个客户端 API. 两条子道都坐在旁边,两个都没有
他们的东西 client.tsx 达到:
| 子路径 | 找到它的时候 |
|---|---|
/client-dir | 从节点服务预建的默认客户端 - defaultClientDir(),文件系统路径 createServerForRuntime({ clientDir }) 想要吗 |
/internal | 从来没有,从应用程序代码:管道 mountClient() 为自己安装(会话和主题提供者,默认 shell 的 URL 芯片,工具配置上下文,预连接查询). 不是公共的API,不是Semver覆盖 |
文档
完整 API 参考 : https://alexkroman.github.io/ agent/ 页面存档备份,存于互联网档案馆