AG-UI 的 HTTP 端(C# Keelson.Agui.Server 的 AguiEndpoints;keel agui/http.ss + server-http.ss):CopilotKit runtime 顶替那一层
要的几条路,挂在任意前缀下。全是 Ring:routes 是 clj-net-server 的路由表(handler 直接给一个 Ring 处理器),
SSE 是流式正文(StreamableResponseBody)—— 不认识 Jetty;clj-net-server 的宿主(Jetty 12)或任何 Ring 服务端都能挂。
run / 注册表 / 编解码 / 线程存储用上游 clj-agent-agui —— C# 的 Keelson.Agui(AguiRegistry、AguiRun、RunAgentInput …)
由它顶替,不重移植。
GET {prefix}/info 名录与能力位
POST {prefix}/agent/:id/run 纯 AG-UI 的 SSE
POST {prefix}/agent/:id/connect 只订阅、不起 run:重放在飞 / 刚跑完那一轮,跟到底;没有 ⇒ 200 空流
POST {prefix}/agent/:id/suggest 「猜你想问」,无状态(条目 :suggest? + :agent-spec 才有,不然 404)
POST {prefix}/agent/:id/stop/:threadId 按停(那条 RUN_ERROR code=STOPPED 在响应体里,⛔ 不发进流)
POST {prefix} 单路由退路:{"method": …, "params": {…}, "body": …}
OPTIONS 任意 预检(永远 204;真正的闸在真请求那一次)
—— 下面七条只在给了 :thread-store 时存在 ——
GET {prefix}/threads {"threads":[…],"nextCursor":…}(查询串原样交给存储)
GET {prefix}/threads/:id/messages {"messages":[…]}
GET {prefix}/threads/:id/events {"events":[…]}
GET {prefix}/threads/:id/state {"state":…}
PATCH {prefix}/threads/:id 那条线程记录(⛔ 不套信封)
POST {prefix}/threads/:id/archive {"threadId":…,"archived":true}
DELETE {prefix}/threads/:id {"threadId":…,"deleted":true}(⚠️ 带 JSON 体)
认不出的路径:任何方法都 404 not_found(⛔ 不是 405)。CORS 缺省拒(见 im.ttalk.agent.server.agui.http)。
线程那几条:存储缺那个槽 ⇒ 501 not_implemented;没这条线程 ⇒ 404 thread_not_found;方法不对 ⇒ 405 带 Allow;
改动类的体不是对象 / 缺 agentId ⇒ 400;存储抛了 ⇒ 500 thread_store_error。…/threads/subscribe 与 …/threads/clear 照旧 404。
(def h (host/host reg {:version "1.0.0" :origin-allowed (ahttp/origin-allow "http://localhost:3000")}))
(def s (net/start (agui/routes "/api/copilotkit" h) {:port 3000})) ; im.ttalk.agent.server.jetty(Jetty)
;; 或别的 Ring 服务端:(agui/handler "/api/copilotkit" h)
routes 返回 clj-net-server 的路由表,元数据里带停机钩子(停机时按停所有在飞的 run,原因 :shutdown)。
注册表条目(clj-agent-agui registry/registry)在 :id :runtime :description :suggest? :stop 之外还认:
:agent-spec /suggest 要现建一次性 agent 的那份 create-agent 配置(无状态:临时 memory、不进注册表)
:memory 这台的 ChatMemory(线程存储的适配器读 /threads/:id/messages)
:server-tool-names 服务端工具名(前端同名声明 = 渲染 / 审批意图,见 im.ttalk.agent.server.agui.resume)
:input-transform 入站插件:(fn [body] 输入),把 RunAgentInput 解析结果改一笔再起跑(如 clj-agent-agui 的 a2ui/input-transform)
:mcp-proxy MCP Apps 的前端代理:(fn [proxied-request] result)。/run 的 forwardedProps.__proxiedMCPRequest
不是一次 run(前端 iframe 里的 MCP App 要调 server)——不起 agent,回一对 RUN_STARTED /
RUN_FINISHED{result}(上游 CopilotKit 的做法;如 clj-agent-agui 的 mcp/proxy-request)
这两格也可以放在 host 选项里当缺省值,条目里给了就以条目为准。
自带 run 驱动的 agent:注册表条目只要 {:id "x" :external? true :description …}(⛔ 不塞占位 runtime);routes 的
host 选项收 :agents {"x" {:run ring-handler :stop ring-handler :connect-source source}}。run / stop 是普通 Ring 处理器
(Origin / CORS 已在外层处理,单路由退路也认它们;体超限由库先答 413,不交驱动);source 照 (thread-id after-seq deliver) 调,deliver 吃 AG-UI 事件 map
或已编帧字节,先写帧环再送本连接,交付终端事件后流自动收口。source 可回一个清理函数。
与 C# 的差别(详见 tasks/J-03.md):被按停的 run 在流里以 RUN_FINISHED result.status=cancelled(带 reason)收口
——clj-agent-agui 的契约是「恰好一个终态」,C# 是什么都不再发;/connect 的 lastSeq 续读(IAguiThreadEventStore /
序号记录器)不做;对端断开要靠心跳的那一次写才发现(Ring 的流式正文 / Jetty 的阻塞输出不报告空闲时的断连)。
AG-UI 的 HTTP 端(C# Keelson.Agui.Server 的 AguiEndpoints;keel agui/http.ss + server-http.ss):CopilotKit runtime 顶替那一层
要的几条路,挂在任意前缀下。**全是 Ring**:`routes` 是 clj-net-server 的路由表(`handler` 直接给一个 Ring 处理器),
SSE 是流式正文(StreamableResponseBody)—— 不认识 Jetty;clj-net-server 的宿主(Jetty 12)或任何 Ring 服务端都能挂。
run / 注册表 / 编解码 / 线程存储用上游 clj-agent-agui —— C# 的 Keelson.Agui(AguiRegistry、AguiRun、RunAgentInput …)
由它顶替,不重移植。
```
GET {prefix}/info 名录与能力位
POST {prefix}/agent/:id/run 纯 AG-UI 的 SSE
POST {prefix}/agent/:id/connect 只订阅、不起 run:重放在飞 / 刚跑完那一轮,跟到底;没有 ⇒ 200 空流
POST {prefix}/agent/:id/suggest 「猜你想问」,无状态(条目 :suggest? + :agent-spec 才有,不然 404)
POST {prefix}/agent/:id/stop/:threadId 按停(那条 RUN_ERROR code=STOPPED 在响应体里,⛔ 不发进流)
POST {prefix} 单路由退路:{"method": …, "params": {…}, "body": …}
OPTIONS 任意 预检(永远 204;真正的闸在真请求那一次)
—— 下面七条只在给了 :thread-store 时存在 ——
GET {prefix}/threads {"threads":[…],"nextCursor":…}(查询串原样交给存储)
GET {prefix}/threads/:id/messages {"messages":[…]}
GET {prefix}/threads/:id/events {"events":[…]}
GET {prefix}/threads/:id/state {"state":…}
PATCH {prefix}/threads/:id 那条线程记录(⛔ 不套信封)
POST {prefix}/threads/:id/archive {"threadId":…,"archived":true}
DELETE {prefix}/threads/:id {"threadId":…,"deleted":true}(⚠️ 带 JSON 体)
```
认不出的路径:任何方法都 404 `not_found`(⛔ 不是 405)。CORS 缺省**拒**(见 im.ttalk.agent.server.agui.http)。
线程那几条:存储缺那个槽 ⇒ 501 `not_implemented`;没这条线程 ⇒ 404 `thread_not_found`;方法不对 ⇒ 405 带 `Allow`;
改动类的体不是对象 / 缺 agentId ⇒ 400;存储抛了 ⇒ 500 `thread_store_error`。…/threads/subscribe 与 …/threads/clear 照旧 404。
```clojure
(def h (host/host reg {:version "1.0.0" :origin-allowed (ahttp/origin-allow "http://localhost:3000")}))
(def s (net/start (agui/routes "/api/copilotkit" h) {:port 3000})) ; im.ttalk.agent.server.jetty(Jetty)
;; 或别的 Ring 服务端:(agui/handler "/api/copilotkit" h)
```
`routes` 返回 clj-net-server 的路由表,元数据里带停机钩子(停机时按停所有在飞的 run,原因 :shutdown)。
注册表条目(clj-agent-agui `registry/registry`)在 :id :runtime :description :suggest? :stop 之外还认:
:agent-spec `/suggest` 要现建一次性 agent 的那份 create-agent 配置(无状态:临时 memory、不进注册表)
:memory 这台的 ChatMemory(线程存储的适配器读 /threads/:id/messages)
:server-tool-names 服务端工具名(前端同名声明 = 渲染 / 审批意图,见 im.ttalk.agent.server.agui.resume)
:input-transform 入站插件:(fn [body] 输入),把 RunAgentInput 解析结果改一笔再起跑(如 clj-agent-agui 的 `a2ui/input-transform`)
:mcp-proxy MCP Apps 的前端代理:(fn [proxied-request] result)。`/run` 的 `forwardedProps.__proxiedMCPRequest`
不是一次 run(前端 iframe 里的 MCP App 要调 server)——不起 agent,回一对 RUN_STARTED /
RUN_FINISHED{result}(上游 CopilotKit 的做法;如 clj-agent-agui 的 `mcp/proxy-request`)
这两格也可以放在 host 选项里当缺省值,条目里给了就以条目为准。
自带 run 驱动的 agent:注册表条目只要 `{:id "x" :external? true :description …}`(⛔ 不塞占位 runtime);`routes` 的
host 选项收 `:agents {"x" {:run ring-handler :stop ring-handler :connect-source source}}`。run / stop 是普通 Ring 处理器
(Origin / CORS 已在外层处理,单路由退路也认它们;体超限由库先答 413,不交驱动);source 照 `(thread-id after-seq deliver)` 调,deliver 吃 AG-UI 事件 map
或已编帧字节,先写帧环再送本连接,交付终端事件后流自动收口。source 可回一个清理函数。
**与 C# 的差别**(详见 tasks/J-03.md):被按停的 run 在流里以 `RUN_FINISHED result.status=cancelled`(带 reason)收口
——clj-agent-agui 的契约是「恰好一个终态」,C# 是什么都不再发;`/connect` 的 lastSeq 续读(IAguiThreadEventStore /
序号记录器)不做;对端断开要靠心跳的那一次写才发现(Ring 的流式正文 / Jetty 的阻塞输出不报告空闲时的断连)。(handler prefix host-or-registry)(handler prefix host-or-registry opts)同 routes,直接给一个 Ring 处理器(挂到任何 Ring 服务端上用;停机时记得 host/cancel-all!)。
同 `routes`,直接给一个 Ring 处理器(挂到任何 Ring 服务端上用;停机时记得 `host/cancel-all!`)。
(info h)/info 的正文:clj-agent-agui 的 registry/info(codec/run-info)+ C# 的口径:threadEndpoints 按存储的槽逐格报
(inspect 拿 messages 当代表),agents 按注册顺序。
`/info` 的正文:clj-agent-agui 的 `registry/info`(codec/run-info)+ C# 的口径:threadEndpoints 按存储的槽逐格报 (inspect 拿 messages 当代表),agents 按注册顺序。
(routes prefix host-or-registry)(routes prefix host-or-registry opts)把 AG-UI 那几条路挂到 prefix 下(如 "/api/copilotkit","" = 根)⇒ clj-net-server 的路由表(routing/router 把它变成一个
Ring 处理器;im.ttalk.agent.server.jetty/start 直接收它)。元数据 :im.ttalk.agent.server/on-stopping 带停机钩子(按停所有在飞的
run)—— 别的 Ring 服务端上请在停机时自己调 im.ttalk.agent.server.agui.host/cancel-all!。
第二个参数是 host(im.ttalk.agent.server.agui.host/host 的返回值),或注册表 + 第三个参数的 host 选项。
把 AG-UI 那几条路挂到 `prefix` 下(如 "/api/copilotkit","" = 根)⇒ clj-net-server 的路由表(`routing/router` 把它变成一个 Ring 处理器;im.ttalk.agent.server.jetty/start 直接收它)。元数据 `:im.ttalk.agent.server/on-stopping` 带停机钩子(按停所有在飞的 run)—— 别的 Ring 服务端上请在停机时自己调 `im.ttalk.agent.server.agui.host/cancel-all!`。 第二个参数是 host(im.ttalk.agent.server.agui.host/host 的返回值),或注册表 + 第三个参数的 host 选项。
cljdoc builds & hosts documentation for Clojure/Script libraries
| Ctrl+k | Jump to recent docs |
| ← | Move to previous article |
| → | Move to next article |
| Ctrl+/ | Jump to the search field |