-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Background
studio.giselles.ai に agent-api ルートを追加するにあたり、@giselles-ai/sandbox-agent-core (agent-core) を直接利用して独自の認証・rate limit を組み込みたい。
現状、Bridge 操作(SSE events / dispatch / respond)のロジックは sandbox-agent-self にインラインで実装されており、外部から再利用できない。
Current Architecture
sandbox-agent-self
├── createAgentApiHandler() ← 1つのエンドポイントに全操作を集約
│ ├── GET → SSE bridge events (インライン実装)
│ └── POST → discriminatedUnion
│ ├── agent.run (createGeminiChatHandler + bridge session)
│ ├── bridge.dispatch (インライン実装)
│ └── bridge.respond (インライン実装)
│
└── depends on
└── agent-core
├── createGeminiChatHandler() ✅ 再利用可能
├── createBridgeSession() ✅ 再利用可能
├── dispatchBridgeRequest() ✅ 再利用可能
├── resolveBridgeResponse() ✅ 再利用可能
└── (Bridge HTTP handlers) ❌ 存在しない
Problem
| 層 | 再利用性 | 備考 |
|---|---|---|
| Bridge 低レベル関数 (createBridgeSession, dispatch, resolve...) | ✅ 再利用可能 | agent-core で export 済み |
| Gemini Chat Handler | ✅ 再利用可能 | agent-core で export 済み |
| Bridge HTTP ハンドラ (SSE / dispatch / respond) | ❌ 再利用不可 | sandbox-agent-self にインラインで埋め込み |
外部プロジェクト(studio.giselles.ai 等)が agent-core を使う場合、Bridge の HTTP ハンドラ部分を自前で再実装する必要がある。
Desired Architecture
agent-core (after)
├── createGeminiChatHandler() (既存)
├── createBridgeSession() (既存)
├── dispatchBridgeRequest() (既存)
├── resolveBridgeResponse() (既存)
├── ...other low-level functions (既存)
│
└── createBridgeHandler() ← 🆕 追加
├── GET → SSE bridge events
└── POST → discriminatedUnion
├── bridge.dispatch
└── bridge.respond
Data Flow
sequenceDiagram
participant Client as Client (Browser)
participant Run as /agent-api/run
participant Bridge as /agent-api/bridge/[...bridge]
participant Sandbox as Vercel Sandbox (Gemini)
participant Redis as Redis
Note over Run: API key auth + rate limit (studio独自)
Client->>Run: POST { message }
Run->>Redis: createBridgeSession()
Run->>Sandbox: createGeminiChatHandler()
Run-->>Client: ndjson stream (bridge session + Gemini output)
Note over Bridge: bridge session token auth (agent-core提供)
Client->>Bridge: GET /events?sessionId=...&token=...
Bridge-->>Client: SSE stream (bridge requests)
Sandbox->>Bridge: POST { type: "bridge.dispatch", ... }
Bridge->>Redis: dispatchBridgeRequest()
Redis-->>Client: SSE push (request)
Client->>Bridge: POST { type: "bridge.respond", ... }
Bridge->>Redis: resolveBridgeResponse()
Redis-->>Sandbox: response
Consumer Usage (studio.giselles.ai)
// /agent-api/bridge/[...bridge]/route.ts
import { createBridgeHandler } from "@giselles-ai/sandbox-agent-core";
export const { GET, POST } = createBridgeHandler();// /agent-api/run/route.ts
import { createBridgeSession, createGeminiChatHandler } from "@giselles-ai/sandbox-agent-core";
// ... studio独自の認証・rate limit ロジックAfter refactoring, sandbox-agent-self becomes:
// sandbox-agent-self/src/index.ts
import { createBridgeHandler, createGeminiChatHandler, createBridgeSession } from "@giselles-ai/sandbox-agent-core";
export function createAgentApiHandler(options) {
const bridge = createBridgeHandler();
const chat = createGeminiChatHandler();
return {
GET: bridge.GET,
POST: async (request) => {
const body = await request.json();
if (body.type === "bridge.dispatch" || body.type === "bridge.respond") {
return bridge.POST(request); // delegate to bridge handler
}
// agent.run logic (create session + chat)
...
},
};
}Scope
- Extract SSE bridge events handler from
sandbox-agent-selfintoagent-coreas part ofcreateBridgeHandler - Extract bridge.dispatch / bridge.respond POST handling into
createBridgeHandler - Export
createBridgeHandlerfromagent-core - Refactor
sandbox-agent-selfto usecreateBridgeHandlerinternally - Verify existing tests pass after refactoring
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels