• AG-UI TypeScript SDK ํŒจํ‚ค์ง€ ๊ตฌ์กฐ๋Š” ์„ ํ˜• ์˜์กด์„ฑ์„ ๊ฐ€์ง„ 4๊ฐœ ํ”„๋กœํ† ์ฝœ ํŒจํ‚ค์ง€ + 1๊ฐœ CLI ๋„๊ตฌ
  • core โ†’ proto โ†’ encoder โ†’ client ๋‹จ๋ฐฉํ–ฅ ์˜์กด ์ฒด์ธ
  • ๊ฐ layer๊ฐ€ ๋‹จ์ผ ์ฑ…์ž„ ์›์น™์„ ๋”ฐ๋ฅด๋Š” ๋ถ„๋ฆฌ ์„ค๊ณ„
  • Transport-Agnostic ์›์น™์„ ํŒจํ‚ค์ง€ ๊ฒฝ๊ณ„๋กœ ๊ฐ•์ œํ•˜๋Š” ๊ตฌ์กฐ

์ด ๊ตฌ์กฐ๊ฐ€ ํ•„์š”ํ•œ ์ด์œ 

  • ์–ธ์–ด ์ค‘๋ฆฝ ์Šคํ‚ค๋งˆ ๊ฒฉ๋ฆฌ: .proto ํŒŒ์ผ์„ ๋ณ„๋„ ํŒจํ‚ค์ง€์— ๋‘์–ด, ๋‹ค๋ฅธ ์–ธ์–ด SDK๊ฐ€ ๋™์ผ ์Šคํ‚ค๋งˆ๋ฅผ ๊ฐ€์ ธ๋‹ค ์“ธ ์ˆ˜ ์žˆ๋Š” ํ˜•ํƒœ๋กœ ์ •์˜
  • Transport-Agnostic ๋ณด์กด: core๊ฐ€ HTTPยทObservable์„ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ transport(WebSocket ๋“ฑ) ์ถ”๊ฐ€๊ฐ€ ์‰ฌ์›€
  • ๋ฒˆ๋“ค ํฌ๊ธฐ ์ตœ์ ํ™”: ๋ธŒ๋ผ์šฐ์ € ์•ฑ์ด binary ํ˜•์‹์„ ์•ˆ ์“ฐ๋ฉด protoยทprotobuf ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ํŠธ๋ฆฌ์‰์ดํ‚น์œผ๋กœ ์ œ๊ฑฐ ๊ฐ€๋Šฅ
  • ํ…Œ์ŠคํŠธ ์šฉ์ด์„ฑ: core๋Š” ์ˆœ์ˆ˜ ํ•จ์ˆ˜์ฒ˜๋Ÿผ ๊ฒ€์ฆ ๊ฐ€๋Šฅ, encoder๋Š” HTTP ์—†์ด ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ๊ฐ€๋Šฅ
  • ํ™•์žฅ ์ง€์  ๋…ธ์ถœ: ๋ˆ„๊ตฌ๋‚˜ core ์œ„์— ์ƒˆ client(e.g. WebSocketAgent)๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ

AS-IS โ€” ๋งŒ์•ฝ ํ•œ ํŒจํ‚ค์ง€์˜€๋‹ค๋ฉด

flowchart TB
    subgraph "ag-ui (๋‹จ์ผ ํŒจํ‚ค์ง€)"
        Types["ํƒ€์ž… ์ •์˜"]
        Events["์ด๋ฒคํŠธ ์Šคํ‚ค๋งˆ"]
        Proto["Protobuf ์ง๋ ฌํ™”"]
        SSE["SSE ์ง๋ ฌํ™”"]
        HTTP["HttpAgent (RxJS)"]
        StatePatch["JSON Patch ์ ์šฉ"]
    end

    Types --> Events
    Events --> Proto
    Events --> SSE
    Proto --> HTTP
    SSE --> HTTP
    HTTP --> StatePatch

๋ฌธ์ œ:

  • ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋‹จ์ˆœํžˆ ํƒ€์ž…๋งŒ import ํ•˜๋ ค ํ•ด๋„ RxJSยทprotobufยทuuid ๊ฐ€ ๋Œ๋ ค์˜ด
  • ๋‹ค๋ฅธ ์–ธ์–ด SDK์™€ ์Šคํ‚ค๋งˆ ๊ณต์œ  ๋ถˆ๊ฐ€ โ€” ๋ณ„๋„ ์ •์˜ ํ•„์š”
  • HTTP ์™ธ transport ์ถ”๊ฐ€ ์‹œ ํŒจํ‚ค์ง€ ์ „์ฒด ์˜์กด์„ฑ์— ์˜ํ–ฅ

TO-BE โ€” 4-layer ๋ถ„๋ฆฌ

flowchart TB
    Core["@ag-ui/core<br/>ํƒ€์ž…ยท์ด๋ฒคํŠธยทZod ์Šคํ‚ค๋งˆ"]
    Proto["@ag-ui/proto<br/>Protobuf ๋ฐ”์ด๋„ˆ๋ฆฌ ์ธ์ฝ”๋”ฉ"]
    Encoder["@ag-ui/encoder<br/>SSE/Binary ์„ ํƒ"]
    Client["@ag-ui/client<br/>HttpAgent + ๋Ÿฐํƒ€์ž„"]

    Core --> Proto
    Core --> Encoder
    Core --> Client
    Proto --> Encoder
    Proto --> Client
    Encoder --> Client

    style Core fill:#E3F2FD
    style Proto fill:#FFF3E0
    style Encoder fill:#F3E5F5
    style Client fill:#E0F7E9

๊ฐ layer๊ฐ€ ์•„๋ž˜ layer๋งŒ ์˜์กด โ†’ ์˜์กด์ด ์œ„๋กœ ํ๋ฅด์ง€ ์•Š์Œ.

4๊ฐœ ํ”„๋กœํ† ์ฝœ ํŒจํ‚ค์ง€์˜ ์—ญํ•  ๋ถ„๋‹ด

1. core โ€” ํƒ€์ž…๊ณผ ์Šคํ‚ค๋งˆ์˜ ๊ธฐ์ค€์ 

src/
โ”œโ”€โ”€ types.ts          # ๋ฉ”์‹œ์ง€ยท๋„๊ตฌยท๋Ÿฐํƒ€์ž„ ์ž…๋ ฅ ํƒ€์ž…
โ”œโ”€โ”€ events.ts         # 16์ข… BaseEvent ์ •์˜
โ”œโ”€โ”€ capabilities.ts   # Agent capability negotiation
โ””โ”€โ”€ event-factories.ts

์™ธ๋ถ€ ์˜์กด: zod ํ•˜๋‚˜. transportยทIO ์—†์Œ. ๋‹ค๋ฅธ ๋ชจ๋“  ํŒจํ‚ค์ง€์˜ ์ง„๋ฆฌ ์›์ฒœ.

2. proto โ€” ๋ฐ”์ด๋„ˆ๋ฆฌ ์ง๋ ฌํ™” ์ฑ„๋„

src/
โ”œโ”€โ”€ proto/*.proto     # ์–ธ์–ด ์ค‘๋ฆฝ ์Šคํ‚ค๋งˆ
โ””โ”€โ”€ proto.ts          # encode/decode ํ•จ์ˆ˜

ํ•ต์‹ฌ export: encode, decode, AGUI_MEDIA_TYPE = "application/vnd.ag-ui.event+proto" ์˜์กด: core, @bufbuild/protobuf.

์™œ ๋ถ„๋ฆฌ๋˜์—ˆ๋‚˜ โ€” .proto ํŒŒ์ผ์€ Protocol Buffers์˜ ํ‘œ์ค€ ํฌ๋งท์œผ๋กœ, protoc ์ปดํŒŒ์ผ๋Ÿฌ๋Š” ๊ณต์‹์ ์œผ๋กœ C++, Java, Kotlin, Python ๋“ฑ 8๊ฐœ ์–ธ์–ด์— ๋Œ€ํ•ด ์ฝ”๋“œ๋ฅผ ์ž๋™ ์ƒ์„ฑํ•˜๊ณ  GoยทDart๋„ ํ”Œ๋Ÿฌ๊ทธ์ธ์œผ๋กœ ์ง€์›ํ•œ๋‹ค. ์ฆ‰ ์ด ํŒจํ‚ค์ง€์˜ .proto๋Š” ๋‹จ์ง€ TS ๋ฐ”์ด๋„ˆ๋ฆฌ ์ธ์ฝ”๋”ฉ์šฉ์ด ์•„๋‹ˆ๋ผ, ๋ˆ„๊ตฌ๋“  ๋‹ค๋ฅธ ์–ธ์–ด SDK๋ฅผ ๋งŒ๋“ค ๋•Œ ๊ฐ€์ ธ๋‹ค ์“ธ ์ˆ˜ ์žˆ๋Š” ์–ธ์–ด ์ค‘๋ฆฝ ์Šคํ‚ค๋งˆ ์›์ฒœ์ด๋‹ค. ๋ณ„๋„ ํŒจํ‚ค์ง€๋กœ ๋‘” ๋•๋ถ„์— ์ฝ”๋“œ ์ƒ์„ฑ ์›Œํฌํ”Œ๋กœ(pnpm generate)๋„ ๊น”๋”ํ•˜๊ฒŒ ๋ถ„๋ฆฌ๋œ๋‹ค.

(์ฐธ๊ณ : ํ˜„์žฌ AG-UI Python SDK๋Š” protobuf ์ฝ”๋“œ ์ƒ์„ฑ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ณ„๋„ ํƒ€์ž… ์ •์˜๋กœ ์šด์˜ ์ค‘. ํ•˜์ง€๋งŒ .proto๊ฐ€ ์ด๋ฏธ ๋ถ„๋ฆฌ๋˜์–ด ์žˆ์œผ๋ฏ€๋กœ ์–ธ์ œ๋“  ๋‹ค์–ธ์–ด ๊ณต์œ ๋กœ ์ „ํ™˜ ๊ฐ€๋Šฅํ•œ ๊ตฌ์กฐ.)

3. encoder โ€” ์ง๋ ฌํ™” ์˜ค์ผ€์ŠคํŠธ๋ ˆ์ดํ„ฐ

src/
โ”œโ”€โ”€ encoder.ts
โ””โ”€โ”€ media-type.ts

์˜์กด: core, proto. ์–‡์€ wrapping layer. SSE(ํ…์ŠคํŠธ) vs proto(๋ฐ”์ด๋„ˆ๋ฆฌ)๋ฅผ media type์œผ๋กœ ์„ ํƒํ•ด์ฃผ๋Š” ๋ผ์šฐํ„ฐ ์—ญํ• . HTTP๋ฅผ ๋ชจ๋ฆ„ โ€” ๋‹จ์ง€ ๋ฐ”์ดํŠธ/ํ…์ŠคํŠธ๋กœ์˜ ๋ณ€ํ™˜๋งŒ ๋‹ด๋‹น.

4. client โ€” ๋Ÿฐํƒ€์ž„ ํ†ตํ•ฉ

src/
โ”œโ”€โ”€ agent/        # HttpAgent
โ”œโ”€โ”€ run/          # run loop
โ”œโ”€โ”€ apply/        # JSON Patch ์ƒํƒœ ์ ์šฉ
โ”œโ”€โ”€ verify/       # ์ด๋ฒคํŠธ ์‹œํ€€์Šค ๊ฒ€์ฆ
โ”œโ”€โ”€ transform/    # ์ด๋ฒคํŠธ ๋ณ€ํ™˜
โ”œโ”€โ”€ chunks/       # streaming chunk ์ฒ˜๋ฆฌ
โ”œโ”€โ”€ compact/      # ๋ฉ”์‹œ์ง€ ์••์ถ•
โ”œโ”€โ”€ middleware/   # ๋ฏธ๋“ค์›จ์–ด ์ฒด์ธ
โ””โ”€โ”€ legacy/       # ๊ตฌ๋ฒ„์ „ ํ˜ธํ™˜

์˜์กด: core, encoder, proto, rxjs, fast-json-patch, uuid. ์ฒ˜์Œ์œผ๋กœ RxJS์™€ HTTP๊ฐ€ ๋“ฑ์žฅํ•˜๋Š” layer. ์ด layer๋งŒ ํ™˜๊ฒฝ ์˜์กด์ (๋ธŒ๋ผ์šฐ์ €/Node ๋‘˜ ๋‹ค ๋™์ž‘ํ•˜์ง€๋งŒ streaming ๋ชจ๋ธ์€ RxJS).

CLI ํŒจํ‚ค์ง€์˜ ์œ„์น˜

create-ag-ui-app (cli)์€ ํ”„๋กœํ† ์ฝœ ์Šคํƒ๊ณผ ๋ฌด๊ด€ํ•œ ์Šค์บํด๋”ฉ ๋„๊ตฌ. inquirer, commander, giget ๋งŒ ์˜์กด โ€” core๋ฅผ import ํ•˜์ง€ ์•Š์Œ. โ€œ์™œ 4๊ฐœ๋ƒโ€๊ณ  ๋งํ•  ๋•Œ cli๋ฅผ ๋นผ๊ณ  ์„ธ๋Š” ์ด์œ .

์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„๊ฐ€ ์•Œ๋ ค์ฃผ๋Š” ์„ค๊ณ„ ์›์น™

์˜์กด์€ ํ•œ ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ํ๋ฅธ๋‹ค

client๋ฅผ ์ˆ˜์ •ํ•ด๋„ core๋Š” ์•ˆ์ „. ๋ฐ˜๋Œ€๋กœ core ์ˆ˜์ •์€ ๋ชจ๋“  layer์— ํŒŒ๊ธ‰. โ†’ ๋ณ€ํ™”์˜ ์˜ํ–ฅ ๋ฐ˜๊ฒฝ์ด ํŒจํ‚ค์ง€ layer๋กœ ๋ช…์‹œ์ ์œผ๋กœ ํ‘œํ˜„๋จ.

proto์™€ encoder๋ฅผ ๋ถ„๋ฆฌํ•œ ์ด์œ 

  • proto: ์–ธ์–ด ์ค‘๋ฆฝ โ€” .proto ํŒŒ์ผ์€ ์–ด๋–ค ์–ธ์–ด์—์„œ๋„ protoc๋กœ ์ฝ”๋“œ ์ƒ์„ฑ ๊ฐ€๋Šฅ
  • encoder: TS ์ „์šฉ โ€” SSE ๋ถ„๊ธฐ์™€ media type ์ฒ˜๋ฆฌ

๋งŒ์•ฝ ํ•œ ํŒจํ‚ค์ง€๋กœ ๋ฌถ์—ˆ๋‹ค๋ฉด, ๋‹ค๋ฅธ ์–ธ์–ด SDK๊ฐ€ .proto๋ฅผ ์žฌ์‚ฌ์šฉํ•˜๋ ค ํ•  ๋•Œ TS ์ „์šฉ SSE ์ฝ”๋“œ๊นŒ์ง€ ํ•จ๊ป˜ ๋Œ๊ณ  ์™€์•ผ ํ•˜๋Š” ๋ถ€์กฐํ™”๊ฐ€ ์ƒ๊ธด๋‹ค.

client์—๋งŒ rxjs๊ฐ€ ์žˆ๋‹ค

โ†’ โ€œ๋‹ค๋ฅธ streaming ๋ชจ๋ธโ€์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ๋œป. ์˜ˆ: Python SDK๋Š” Observable ๋Œ€์‹  async iterator. core ํƒ€์ž…์€ ๊ทธ๋Œ€๋กœ ์žฌ์‚ฌ์šฉ.

๋ธ”๋กœ๊ทธ 1ํŽธ ํ•ต์‹ฌ ๋ฉ”์‹œ์ง€

ํŒจํ‚ค์ง€ ๊ฒฝ๊ณ„๋Š” ๋””๋ ‰ํ† ๋ฆฌ ๊ตฌ์กฐ๊ฐ€ ์•„๋‹ˆ๋ผ ์˜์กด์„ฑ ํ๋ฆ„์˜ ๋ฐฉ๋ฒฝ์ด๋‹ค. AG-UI๋Š” โ€œtransport-agnosticโ€์ด๋ผ๋Š” ์ถ”์ƒ ์›์น™์„ 4๊ฐœ์˜ ํŒจํ‚ค์ง€ ๊ฒฝ๊ณ„๋กœ ๋ฌผ๋ฆฌ์ ์œผ๋กœ ๊ฐ•์ œํ–ˆ๋‹ค. ๊ทธ๋ž˜์„œ ๋‹ค์Œ ํŽธ(AbstractAgent)๋ถ€ํ„ฐ ๋ณด๊ฒŒ ๋  ์ฝ”๋“œ๋Š” ํ•ญ์ƒ โ€œ์ด ์ฝ”๋“œ๊ฐ€ ์–ด๋А layer์— ์žˆ๋Š”๊ฐ€โ€๋ฅผ ๋จผ์ € ๋ฌป๊ฒŒ ๋œ๋‹ค.

์ฐธ๊ณ  ๋ฌธ์„œ