Giting.
낮의 Giting

홈 · AI 에이전트 · AG-UI · 거버넌스 · 셀프호스트 · 브라우저 자동화 · TypeScript · MIT

openbot 대표 이미지 7bcb8c7 (2026-09-12) · shallow clone 기준, commitCount 는 하한값
분석 리포트실측 정보사이트적용점원문 README

정체·구조

OpenBot은 CopilotKit이 낸 셀프호스트 에이전트 플랫폼 템플릿이다. README가 스스로 "제품이 아니라 템플릿"이라고 못박는다. 가입할 호스팅판이 없고, 어떤 워크스페이스도 npm 패키지로 배포되지 않는다. 리포를 클론해 examples/의 예시 테넌트를 자기 동료·채널·스킬로 갈아끼운 뒤 자기 인프라에서 돌리는 방식이다. 상태 배지는 alpha, 첫 커밋이 2026-08-14로 실측 커밋 305건 전부가 90일 창 안에 들어온다. 즉 약 한 달 된 리포에 27명이 붙어 ★4,802를 모은, 회사가 미는 신생 플래그십이다.

코드는 Bun 워크스페이스 모노레포다. 루트 workspaces는 app·server·worker 셋뿐이지만, 실제 트리는 프레임워크별 에이전트 어댑터(agent-langgraph, agent-mastra, agent-crewai, agent-pydantic-ai, agent-adk, agent-claude-sdk 등 15개), 격리 실행 환경 agent-computer, 컨테이너 오케스트레이터 supervisor, 그리고 Rust/Tauri 데스크톱(desktop, 최대 파일 main.rs 8,466줄)까지 포함한다. 언어 분포는 TS 130,970줄·TSX 43,409줄·Rust 30,944줄·Py 3,571줄로, 웹 프론트/서버는 TS, 데스크톱 껍데기는 Rust, 파이썬 에이전트 어댑터는 얇게 얹은 구성이다.

핵심 기능·아키텍처 (파이프라인 단계로 분해)

전체 런은 앱(3010) → 서버/Hono API(3001) → AG-UI Bot 엔드포인트 → 게이트웨이 → 격리 컴퓨터(4100) → PostgreSQL+pgvector(5432) 흐름을 탄다. 스레드·메모리는 외부 CopilotKit Intelligence에 둔다.

1. 턴 진입. 앱이 채널 또는 Bot 세션을 연다. 서버가 로그인 주체와 선택된 동료를 확정하고, CopilotKit 런타임이 설정된 AG-UI 엔드포인트로 턴을 넘긴다. Bot은 "AG-UI를 말하는 아무 엔드포인트"면 되므로 프레임워크에 묶이지 않는다. 2. 게이트웨이 판정 (제품의 축). Bot이 브라우저·파일·MCP·컴포넌트에 하려는 모든 호출은 서버 게이트웨이 한 곳으로 되돌아온다. 게이트웨이는 세 단계를 이 순서로 한다. ① 호출자가 보낸 ref를 서버가 직접 떠온 스냅샷에서 실제 요소로 재해석한다(호출자가 말한 라벨을 절대 믿지 않는다). ② CEL 정책을 평가한다. ③ 판정 결과가 어느 쪽이든 감사 행을 먼저 쓴 뒤에만 컴퓨터를 호출한다. 3. 정책 엔진 (fail-closed). 규칙은 tool.name·intent·bot.id·actor.id·page.url/host·element.*·key·file.*·mcp.*를 볼 수 있고, CEL 식에 contains()·matches()를 더해 쓴다. deny가 allow보다 먼저 평가되고, 빈 정책은 아무것도 허용하지 않으며, 깨진 deny 규칙은 막고 깨진 allow 규칙은 열지 않는다. 잘못된 정책은 서버 기동 자체를 멈춘다. 4. 격리 실행. supervisor가 Bot마다 전용 컨테이너·/workspace 볼륨·브라우저 프로필을 만든다. agent-computer는 COMPUTER_TOKEN 없이는 /health만 답하고 127.0.0.1:4100에 바인딩된다. DB는 별도 data 네트워크에 두어 Bot 셸이 닿지 못하게 하고, COMPUTER_RUNTIME=runsc로 gVisor 샌드박스도 옵션이다. 5. 사람 개입·감사. 로그인 벽/2FA를 만나면 Bot이 도움을 청하고, 같은 패널에서 사람이 조종간을 넘겨받는다. 사람이 모는 동안 Bot 액션은 큐잉이 아니라 거부된다. 모든 감사 행은 "누구 권한으로" 했는지와 "무엇이 촉발했는지"(initiator_kind/initiator_id)를 함께 남긴다. 시크릿은 트랜스크립트에 값이 들어가지 않고 길이만 기록된다.

부가로 컴포넌트 응답(산문 대신 컴파일된 React 컴포넌트), 거버넌스된 MCP(미상 도구는 write로 취급), 예약 루틴(15분 하한·활성 20개 상한·10연속 실패 시 자동 정지), 기업 SSO를 갖췄다.

실제로 되는 것 / 안 되는 것

되는 것으로 보이는 근거: CI 워크플로 5종에 zizmor 시큐리티 스캔이 붙어 있고, 테스트 파일 307개 중 정책 관련만 computer-policy·policy-fanout·policy-durability·policy-dry-run 등 다수가 실재한다. 게이트웨이·정책·감사가 코드로 구현되어 있고 문서와 코드 주석이 서로 일치한다. 배포도 실제 두 경로(compose 개발용, 단일 이미지+임베디드 Postgres 운영용)를 제공한다. 이슈 응답은 25건 표본 중 13건 응답(중앙값 0시간).

주의할 것. ① alpha 자백. 릴리스 태그는 9개로 아직 0.0.x 대다. ② 외부 의존. durable 스레드·메모리는 CopilotKit Intelligence에 의존한다. ③ 모델 미포함. 관리자가 키를 넣어야 한다. ④ 실제 브라우저 자동화·격리·거버넌스의 완전한 왕복을 이 분석에서 구동 검증하지는 않았다(코드·문서·테스트 존재만 확인).

우리 적용점

  • Tefo (페르소나 사원 데스크톱). 게이트웨이-단일-경로 + 감사-우선(행을 먼저 쓰지 않으면 실행 없음) 설계가 Tefo의 제안카드 수락·핸드오프 릴레이 해시체인과 정확히 같은 문제를 다룬다. "호출자가 보낸 ref/라벨을 믿지 말고 서버가 쥔 매핑으로 재해석한다"는 원칙은, 에이전트가 스스로 안전 라벨을 붙여 게이트를 우회하는 사고를 막는 참고가 된다.
  • coxpit-oss (에이전트 플릿 콘솔). "Bot마다 격리 컨테이너·workspace 볼륨 + supervisor가 ensure/stop/reset/list만 노출"은 coxpit-oss의 격리 worktree+브랜치+tmux 런 모델과 같은 계열이다. 127.0.0.1 루프백 바인딩 + per-container 토큰은 coxpit-oss 노출 정책 강화에 참고할 실측 패턴이다.
  • Triforge 챗봇 / persona-lab. AG-UI를 공통 인터페이스로 삼아 프레임워크를 갈아끼우는 어댑터 층은, persona-lab RAG 엔드포인트나 Triforge 챗봇을 여러 프런트에 프로토콜 하나로 붙일 때의 청사진이 된다.
  • 거버넌스 언어. CEL 기반 정책 + deny-before-allow + fail-closed는, 우리 규칙 표현을 선언형으로 승격하고 싶을 때 참고 문법이 된다.

가져오지 말 것

  • CopilotKit Intelligence 의존. 스레드·메모리를 외부 관리형 서비스에 매는 구조는 우리 "의존성 0·로컬 우선·계정/서버 없음" 원칙과 정면으로 어긋난다. 참고할 것은 거버넌스 설계이지 이 백엔드가 아니다.
  • 규모·스코프. 332,188 LOC·27명·15개 프레임워크 어댑터·Kubernetes 차트까지 붙은 스택은 우리 owner-단독 미니멀 도구와 정반대 무게다. 통째 이식이 아니라 원칙만 뽑는다.
  • alpha·0.0.x 코드를 그대로 신뢰. 특정 파일을 베껴오면 상류 변화에 금방 어긋난다.
  • 라이선스. MIT라 재사용 자유지만, 우리 정책상 코드는 짧은 발췌+경로로만 인용하고 통째 전재하지 않는다.

실측 정보

HEAD 커밋
7bcb8c7 (2026-09-12) · shallow clone 기준, commitCount 는 하한값
무엇
CopilotKit이 낸 셀프호스트 에이전트 플랫폼 템플릿(제품 아님·호스팅판 없음). AG-UI 프로토콜로 어떤 프레임워크 에이전트든 격리된 '컴퓨터'(브라우저·파일·셸)를 가진 사내 동료로 붙인다. 클론해 예시 테넌트를 갈아끼우고 자기 인프라에서 돌린다
규모 / 실측
332,188줄 · TS 130,970 + TSX 43,409 + Rust 30,944(Tauri 데스크톱) + Py 3,571 · 1,027파일 · 테스트 307 · CI 5(zizmor 시큐리티 스캔 포함)
활발 / 유지
첫 커밋 2026-08-14 · 커밋 305 전부 90일 내(약 한 달 된 신생) · 기여자 27 · 이슈 응답 표본 25건 중 13건 · 중앙값 0시간(즉답)
거버넌스 (제품의 축)
모든 도구 호출이 게이트웨이 한 곳 통과 → ① 서버가 직접 뜬 스냅샷으로 ref 재해석(호출자 라벨 불신) ② CEL 정책 평가(deny-before-allow · fail-closed · 빈 정책=전부 거부) ③ 감사 행을 먼저 쓴 뒤에만 실행. Bot별 격리 컨테이너 · gVisor(runsc) 옵션
성숙도 / 의존
스스로 alpha 자백 · 릴리스 9태그(0.0.x) · durable 스레드·메모리는 외부 CopilotKit Intelligence 의존 · 모델 키는 관리자가 주입 · MIT

사이트 실측

주소
www.copilotkit.ai/openbot
응답 · 첫 화면
200 · 0.9초 (데스크톱)
요청 · 전송량
53개 · 1.1MB
깨진 요청 · 콘솔 오류
1개 · 0개
폰(390px)
가로 넘침 없음
디자인
밝은 화면 · figtree

홈페이지를 실제 크롬으로 띄워 첫 화면까지만 쟀습니다(2026-10-16 · 데스크톱 1440px · 폰 390px). 로그인 · 입력 같은 동작은 하지 않았고, 사이트 상태는 리포 품질과 따로 봅니다. 색 칸은 바탕 · 면 · 글자 · 흐린 글자 · 강조 · 선, 점선은 「못 잼」.

적용점

  • 이럴 때 유용에이전트에게 실제 브라우저·파일·셸을 주되 '무엇을 언제 하게 할지'를 정책으로 통제해야 하는 팀. 게이트웨이-단일-경로 + 감사-우선(행 먼저, 실행 나중) + fail-closed 정책이 코드로 구현돼 있고 정책 테스트도 실재한다(computer-policy·policy-fanout 등). AG-UI라 LangGraph·Mastra·CrewAI·Claude SDK 등 프레임워크를 갈아끼운다.
  • 이럴 땐 부적합당장 쓸 완성 제품을 찾는다면 이르다. 스스로 alpha·템플릿이라 밝히고 릴리스가 0.0.x다. durable 스레드·메모리를 외부 CopilotKit Intelligence 에 매므로 완전 자체호스트·오프라인을 원하면 그 의존이 걸린다. 332K줄·15개 어댑터·K8s 차트라 가벼운 도구가 필요하면 과하다.
  • 먼저 볼 것값은 '에이전트 플랫폼'보다 거버넌스 설계다. 게이트웨이가 호출자의 ref/라벨을 믿지 않고 서버 스냅샷으로 재해석하는 부분, CEL 정책의 deny-before-allow·fail-closed, 감사 행을 실행보다 먼저 쓰는 순서, 에이전트에 안전 경계를 씌우려는 사람은 여기부터 본다.
◈ 참고용

판정은 참고용이다. OpenBot 은 '제품'이 아니라 CopilotKit 이 미는 셀프호스트 템플릿이고, 스스로 alpha 라 밝힌다(릴리스 0.0.x). 그러니 지금 당장 도입해 의존할 물건은 아니다. 그런데 값은 다른 데 있다. 거버넌스 설계다. 에이전트에게 실제 브라우저·파일·셸을 쥐여 주면서도 모든 도구 호출을 게이트웨이 한 곳으로 되돌리고, 거기서 ① 호출자가 보낸 ref 를 서버가 직접 뜬 스냅샷으로 재해석하고(라벨을 안 믿는다) ② CEL 정책을 deny-before-allow·fail-closed 로 평가하고 ③ 감사 행을 실행보다 먼저 쓴다. 이 세 가지가 코드와 테스트로 실재하고, 약 한 달 된 신생 리포에 27명이 붙어 별 4,802를 모은 회사 플래그십이다. 우리(Tefo·coxpit-oss)가 에이전트에 안전 경계를 씌우는 문제를 정확히 같은 각도에서 푼다. 그래서 통째 이식이 아니라 이 원칙을 참고하는 표본으로 값이 있다. 단, durable 스레드·메모리를 외부 CopilotKit Intelligence 에 매는 구조는 우리 로컬-우선 원칙과 어긋나니 참고할 건 게이트웨이·정책·감사이지 그 백엔드가 아니다.

원문 README

아래는 CopilotKit/openbot 저장소의 README 원문입니다(GitHub 렌더, 수집 시점 기준). 저작권은 원 프로젝트에 있으며 원 저장소의 라이선스를 따릅니다. GitHub에서 보기

README 전문 펼치기

OpenBot

The AI assistant your company can actually own. Same shape as ChatGPT, Claude or Grok, with one difference that matters: it runs on your infrastructure and you can change anything about it. Any agent stack, through AG-UI.

Each coworker gets a computer of its own: a real browser with its own logins, its own files, and only the tools you grant. Every action decided before it happens and recorded after.

Talk to an engineer · Have us build it with you · copilotkit.ai/openbot · Quick start · Docs

CI security License: MIT Alpha

Trendshift: #3 Repository Of The Day

demo-openbot.mp4

Bring any AG-UI agent, written on a framework or by hand, and it arrives as a coworker with a channel of its own. Watch it work on its own screen, take the wheel when it reaches something it should not do alone, then hand it back. It answers with components rather than only prose, and the whole thing runs on your own machine.

A template, not a product. OpenBot is meant to be cloned and made your own. There is no hosted version to sign up for, and nothing here is published as a package to depend on: every workspace in this repository is private. You take the repository, replace the example tenant package under examples/ with your own coworkers, channels and skills, and run it. Everything below describes a starting point, not a finished thing somebody operates for you.

Alpha, and under active development. OpenBot is early. Expect rough edges and bugs, and expect things to move. Issues and pull requests are welcome.

Runs on your machine. Everything below is written for a laptop. .env.example carries OPENBOT_SINGLE_USER=true, which admits every request as one administrator, so a fresh clone reaches the product without registering an OAuth client first. Sign-in turns that off, and is required before anybody else can reach the deployment.

Do not want to build it yourself? We will. Our engineers will stand OpenBot up inside your infrastructure, customize it into something that looks like your own product, and hand it back to you to keep changing. Start the conversation.

What it is

An agent platform that runs inside your own infrastructure. Docker Compose brings up every part of it, the data sits in your PostgreSQL, and the model is yours to choose: no model ships in the box, and an administrator supplies the credential, which is encrypted at rest and never logged.

Thirteen coworkers ship in the example package, and they are configuration rather than code: General Assistant for everyday work and Knowledge for company questions, a Risk Analyst reached as an endpoint, and ten in examples/fintech/agents/ that each do one job — reading an expense claim against the policy as written, turning a meeting note into the follow-ups actually in it, drafting release notes from what shipped, triaging a ticket, answering a new starter from the handbook, writing a brief that names what it could not find, writing up an interview, handing an on-call shift over, assembling what is known before a renewal, and grouping customer feedback into themes it can cite. Add your own by dropping a file in that directory, by editing agents.yaml, or from /agents in the UI.

Anything a Bot does to a computer, a file, an MCP server or a component goes through one gateway that decides and records it. That is the difference between an agent that can use your tools and an agent you can let near them.

More at copilotkit.ai/openbot.

Built on AG-UI

A Bot is any endpoint speaking AG-UI, the open protocol for agent-to-user interaction, so OpenBot is not tied to a framework and neither are you. Agents built with LangGraph, Mastra, CrewAI, Pydantic AI, Google ADK or written by hand all arrive the same way, and the governance rides the protocol rather than the framework.

You talk to the server, which sends the turn to a Bot over AG-UI. Every tool call the Bot makes comes back through the gateway, which resolves the target, decides it against your policy, records an audit row, and only then acts, or refuses and names the rule. Allowed browser and file actions reach that Bot's own computer, one container each with its own Chromium, logins and workspace, built by the supervisor. Decisions land in PostgreSQL and threads in CopilotKit Intelligence.

Requirements

  • Docker, for PostgreSQL and the shipped Bots.
  • Bun 1.3+, for the app and API server.
  • A CopilotKit Intelligence project and license. A free plan is available, and Intelligence can be self-hosted.
  • A model key. The proof-of-concept Bot uses OpenAI; the LangGraph Bot can use OpenAI, Anthropic, or Google.

Quick start

Setting up with an AI assistant? Paste prompt.txt into it first. It carries the same steps as below plus the things that are easy to get wrong: which of the ten blank keys in .env.example are actually yours to fill (three), which the start script generates for you, and what each start-up refusal means. Every claim in it is checked against this repository.

  1. Create .env:

    cp .env.example .env
    bun install
  2. Connect a fresh managed Intelligence project:

    npx --yes copilotkit@latest login
    npx --yes copilotkit@latest project select
    bun scripts/setup-learning.ts

    The helper provisions the selected project's runtime key, creates or reuses its openbot Learning container, then writes both settings to .env. It preserves custom container assignments and refuses to replace an existing OpenBot key. For fresh self-hosted setup, set INTELLIGENCE_API_URL to that deployment's HTTPS API origin and run the helper without the two npx commands. It opens an isolated Chrome or Edge window for your usual sign-in and project choice; install either browser first. Existing key-only setups can assign a container through Admin → Automatic Learning. Managed Intelligence needs no separate licence token.

  3. Fill the remaining required values:

    • OPENAI_API_KEY

    Keep the managed Intelligence URLs from .env.example unless you run Intelligence yourself. The example KEY_ENCRYPTION_KEY is public and fine locally; generate your own with:

    openssl rand -base64 32
  4. Run:

    bash scripts/start.sh
  5. Open http://localhost:3010.

scripts/start.sh starts Docker services, applies migrations, starts the API server on port 3001, starts the app on port 3010, and checks that the services answer their own health routes before printing next steps.

scripts/stop.sh takes the same things down, including each Bot's computer, which compose does not own. Nothing is deleted: the database, the Bots' files and their browser profiles are volumes.

Deploy it

One image carries the app, the API, the browser the Bots drive, and optionally PostgreSQL. Same .env, no Kubernetes.

# The published image. Nothing to clone and nothing to build.
docker run -p 3001:3001 --env-file .env \
  -e EMBEDDED_POSTGRES=on -v openbot-data:/var/lib/postgresql \
  ghcr.io/copilotkit/openbot:latest

# Or the tree you have in front of you.
docker build -t openbot .
docker run -p 3001:3001 --env-file .env \
  -e EMBEDDED_POSTGRES=on -v openbot-data:/var/lib/postgresql openbot

Everything is on 3001 here, the app included, rather than the 3010 the clone uses. latest is the most recent release and a version tag such as :v0.0.9 pins one.

Leave EMBEDDED_POSTGRES off and set DATABASE_URL to point at a database you already run. docs/deployment.md has the minimum sizes, the platform notes, and how it behaves behind more than one replica.

Try it

  • Open /bot and ask: Open news.ycombinator.com and tell me the top story.
  • Ask the Bot to fill out https://httpbin.org/forms/post, then inspect /admin/audit.
  • Open /admin/boundaries, add a deny rule or preset, and retry the same browser action.
  • Create a coworker from /agents, give it a standing role, and start a channel with it.

Main surfaces

Route Purpose
/ Start and browse channels.
/agents Create, edit, duplicate, hide, delete, and launch coworkers.
/channel/:id Converse with one coworker, watch its screen, and see what it ran.
/bot Direct chat with a Bot; ?agent=<id> selects one.
/skills Create and enable personal skills.
/routines See the routines that are standing, and stop one.
/settings User preferences.
/admin/credentials Store write-only encrypted credentials.
/admin/computers View, stop, and reset Bot computers.
/admin/boundaries Configure browser/file/MCP action policy.
/admin/components Publish components and govern which Bots may use them.
/admin/playground Draft and publish sandboxed components in the browser.
/admin/plugins Configure MCP servers and grant their tools to Bots.
/admin/skills Write deployment skills and grant them to Bots.
/admin/people List, promote, demote, and remove people who have signed in.
/admin/identity-providers Register a company SAML or OIDC provider, routed by email domain.
/admin/audit Review permitted, refused, and failed actions.

Features

  • A computer per Bot: the supervisor gives each Bot its own container, its own /workspace volume and its own browser profile. Set COMPUTER_RUNTIME=runsc to run them under gVisor where the host supports it.
  • A shell, not just a browser: a Bot can run a command in its workspace, install what it needs, and process a file it saved. Through the same gate as everything else, so a rule can refuse a shell outright or refuse particular commands, and the command is on the record either way. The command inherits PATH, locale, terminal and proxy variables, not the rest of the deployment's environment.
  • The gateway is the only way in: it resolves the target from a server-held snapshot, evaluates the policy, writes the audit row, and only then calls the computer. There is no path that acts without the record existing first.
  • CEL policy, fail closed: rules can inspect tool.name, intent, bot.id, actor.id, page.url, page.host, element.*, key, command, file.*, mcp.* and initiator.* (what started the run, so a rule can refuse a scheduled routine what it would allow a person). Deny is evaluated before allow, a missing policy permits nothing, and a broken rule refuses rather than opens.
  • Watch what it is doing: the screen shows what a Bot is looking at, and the Activity tab beside it shows what it ran, read and saved, with the output. A command line in the transcript opens to the same thing. A saved file shows its path and size, never its contents.
  • Take the wheel: a Bot that hits a login wall or a 2FA prompt asks for help. Control is handed over in the same panel and recorded as computer.help_requested, computer.control_taken and computer.control_released. While a person is driving, Bot actions are refused rather than queued.
  • Secrets never enter the transcript: the trail records that a secret was requested and how long it was, not what it said.
  • Bring your own agent: any AG-UI endpoint is a Bot, on a framework or hand-written. Endpoints are validated with the same target checks used for browser navigation, and an auth header is stored write-only.
  • Components instead of prose: compiled React components live in app/src/components/gallery/, sandboxed ones are authored in /admin/playground and published with no deployment. Every call asks the server whether the component exists, is published, and is not withheld from that Bot. Data functions are granted per component.
  • Governed MCP: Google Drive and Notion ship in the catalogue, and Composio brokers a few hundred more apps behind one account, each reached as the person asking. The catalogue carries only vendors this deployment stands behind, so adding one is a review of that vendor. Custom servers must pass URL checks; unknown tools and custom-server tools are treated as writes, and a catalogue tool the server advertises but does not name as a write classifies as a read. A Bot is told which connectors exist here and which it holds, so it says it has not been granted one rather than browsing to the vendor's website.
  • Skills are instructions, not capabilities: personal skills attach only to Bots their author owns, deployment skills are admin-owned, and both are invoked with / in the composer. A Bot granted the shipped skill-creator skill can write one with you in the conversation, and saves it only when you press the button on the card.
  • Sign in with what your company already has: Google, Microsoft or Okta from the environment, or a company's own SAML or OpenID Connect provider registered while the deployment runs and routed by email domain. Any one turns sign-in on; several may be configured at once.
  • Decide who gets in: /admin/people lists everybody who has signed in, promotes and demotes them, and removes access, which ends the session they are using and stops the next sign-in. Every change is on the audit trail.
  • An audit trail you can read: /admin/audit lists what was permitted, what was refused and what failed, and every refusal carries the rule that caused it.
  • Credentials encrypted at rest: stored through /admin/credentials, never returned by an API, and redacted from audit events.
  • Loopback by default: computers bind to 127.0.0.1 and require a per-container token, so nothing reaches a logged-in browser by knowing its port. The supervisor binds there too, because it holds the Docker socket and its token is a shared secret rather than a network boundary.
  • Durable threads and memory: conversations survive restarts through CopilotKit Intelligence, and each deployment stamps the threads it owns.
  • Routines: ask a Bot to do something on a schedule and it does, running as you, in the channel you asked in. A 15-minute floor and a cap of 20 enabled routines keep a sentence from scheduling more than a person meant, and ten failures in a row switch a routine off rather than burn model spend forever. Needs a worker process; see docs/routines.md.

Bring your own agent

Any AG-UI endpoint can be a Bot.

From /agents, create a coworker with:

  • name, title, and role description;
  • private or public visibility;
  • optional AG-UI endpoint;
  • optional write-only authorization header.

The server validates agent endpoints with the same target checks used for browser navigation, at registration and again on every redirect the endpoint answers with. If no custom endpoint is set, product-created coworkers use MANAGED_AGENT_AG_UI_URL when it is configured, and are refused when it is not.

A private address is refused unless it is listed in AGENT_ENDPOINT_ALLOWED_HOSTS:

AGENT_ENDPOINT_ALLOWED_HOSTS=agents.internal,10.0.0.42:9000

A host on its own covers any port on that host; a host with a port pins that port. Matching is exact: no wildcards, no suffixes. An entry written as a URL, or containing *, stops startup and names that entry.

The list covers agent endpoints only. Browsing is unaffected, the addresses holding a deployment's own cloud credentials are refused whatever is listed, and listing an address permits registering an agent there rather than granting that agent anything.

Tenant package agents are declared in agents.yaml as either:

  • built-in, with a system prompt; or
  • remote-ag-ui, with an endpoint.

See docs/configuration.md and docs/coworkers.md.

Configuration

.env.example is the source template. The API server refuses to start without:

  • DATABASE_URL
  • KEY_ENCRYPTION_KEY
  • INTELLIGENCE_API_URL
  • INTELLIGENCE_GATEWAY_WS_URL
  • INTELLIGENCE_API_KEY

COPILOTKIT_LICENSE_TOKEN is optional. A self-hosted Intelligence with its own licence can still set it and it is forwarded to the runtime; managed Intelligence does not issue one and startup no longer asks for it.

Settings worth knowing:

Variable Use
OPENBOT_SINGLE_USER Admits every request as one administrator. Required when no identity provider is configured; .env.example ships it on.
OPENAI_BASE_URL Answers the OpenAI-shaped calls from somewhere else: a gateway, a proxy.
ANTHROPIC_BASE_URL, GOOGLE_GENERATIVE_AI_BASE_URL The same, for those two APIs.
COMPUTER_TOKEN Secret every Bot computer request must present. start.sh sets one.
SUPERVISOR_TOKEN Secret the supervisor requires. start.sh sets one.
AGENT_TOOL_TOKEN Secret a Bot presents to call a granted tool back. start.sh sets one. Without it no Bot may call tools.
COMPUTER_SUPERVISOR_URL Gives each Bot a computer of its own instead of one shared computer.
COMPUTER_RUNTIME Set to runsc to run computers under gVisor, where the host has it.
COMPUTER_SANDBOX Set to on for Chromium's own sandbox, where the host permits it.
EMBEDDED_POSTGRES Set to on for a database inside the deployment container.
AGENT_COMPUTER_POLICY JSON action policy. Malformed JSON stops server startup.
AGENT_COMPUTER_ALLOW_PRIVATE_HOSTS Lets a Bot reach this machine's own services. Local only, and refused under NODE_ENV=production.
AGENT_ENDPOINT_ALLOWED_HOSTS Private addresses an agent may be registered at, comma separated. A host, optionally with a port.
TENANT_PACKAGE_DIR Directory containing tenant YAML. Defaults to ../examples/fintech.
DEPLOYMENT_ID Names this deployment when two share one Intelligence project.

Full reference: docs/configuration.md.

Architecture

Service Port Purpose
app 3010 React/Vite UI.
server 3001 Hono API, CopilotKit runtime, auth, policy, audit, plugins, components, coworkers, and channels.
agent-computer 4100 Chromium plus /workspace and browser profile.
agent-bot 4200 Proof-of-concept AG-UI Bot.
agent-langgraph 4201 LangGraph AG-UI Bot.
supervisor 4500 host / 4300 container Creates and manages one computer per Bot.
PostgreSQL with pgvector 5432 Product data, policy, audit, credentials, grants, channels, and component metadata.
CopilotKit Intelligence external Durable threads and memory.

The server gateway is the product/API path for Bot browser and file tool calls. It resolves the target, evaluates policy, writes an audit row, and then calls agent-computer. The computer also exposes lower-level token-protected service endpoints; keep them private and do not use them to bypass the gateway.

More detail: docs/architecture.md.

Sign in

.env.example ships OPENBOT_SINGLE_USER=true, which is one administrator and no sign-in: how a fresh clone reaches the product without registering an OAuth client first. Delete that line and configure any one of Google, Microsoft or Okta before anybody else can reach the deployment. With neither, it refuses to start rather than admitting everybody as an administrator. Configure more than one provider and the sign-in screen offers each of them.

These four are needed whichever you pick:

BETTER_AUTH_URL=http://localhost:3001        # where OAuth callbacks come back to
BETTER_AUTH_SECRET=                          # openssl rand -base64 32
TRUSTED_ORIGINS=http://localhost:3010        # where the app is served from
INITIAL_ADMIN_EMAILS=you@example.com         # comma separated

Then the provider. Register the redirect URI shown beside it.

# Google — http://localhost:3001/api/auth/callback/google
GOOGLE_OAUTH_CLIENT_ID=
GOOGLE_OAUTH_CLIENT_SECRET=

# Microsoft — http://localhost:3001/api/auth/callback/microsoft
MICROSOFT_OAUTH_CLIENT_ID=
MICROSOFT_OAUTH_CLIENT_SECRET=
MICROSOFT_OAUTH_TENANT_ID=common             # your directory GUID for staff only

# Okta — http://localhost:3001/api/auth/callback/okta
OKTA_OAUTH_CLIENT_ID=
OKTA_OAUTH_CLIENT_SECRET=
OKTA_OAUTH_ISSUER=https://example.okta.com/oauth2/default

Restart. Accounts, sessions and roles are stored in the same PostgreSQL database as everything else.

A company's own SAML or OpenID Connect provider is registered while the deployment runs, under Admin → Identity providers, and routed by email domain. An OIDC registration needs every host in the provider's discovery document listed in TRUSTED_ORIGINS, not only the issuer.

  • INITIAL_ADMIN_EMAILS is required, because nothing else grants the administrator role and no screen can promote somebody afterwards. It is re-read on every sign-in, so editing it takes effect the next time that person signs in.
  • MICROSOFT_OAUTH_TENANT_ID defaults to common, which admits personal Microsoft accounts as well as work ones. On a multi-tenant app registration Entra may send no email claim at all, so OpenBot falls back to upn and then preferred_username. If none of the three arrives the sign-in is refused and the reason is logged: add email as an optional claim, or use your directory GUID here.
  • A half-configured provider is refused at start-up rather than at somebody's first attempt to sign in: a client id with no secret, a secret shorter than 32 characters, or an Okta issuer with no credentials behind it.
  • SAML and OIDC are registered while the deployment runs rather than configured here. Sign in as an administrator and go to Admin → Identity providers with the metadata your identity team gave you. People then sign in by typing their email address, and the domain decides which provider they are sent to.
  • Put TLS in front of any deployment. A page served over plain http:// on anything but localhost is not a secure context, and sign-in cookies want Secure.

Organization sign-in for desktop installations

For an employee desktop, provision an OpenBot authority using the Google, Microsoft or Okta settings above (your Kubernetes OpenBot can serve this role). Set Organization OpenBot URL in the desktop connection screen, or OPENBOT_ORGANIZATION_AUTH_URL=https://openbot.company.example in its public configuration. Use an HTTPS origin; HTTP is accepted only on loopback for local tests. Provider client secrets stay on that authority. Template and white-label deployments can supply the same setting without changing their Intelligence endpoint.

This optional URL is separate from INTELLIGENCE_API_URL, INTELLIGENCE_GATEWAY_WS_URL and INTELLIGENCE_API_KEY. Local, managed and customer-hosted Intelligence all retain their project credential. A Google ID token is not an Intelligence project key. Leave the organization URL empty for a standalone desktop.

Desktop sign-in uses the system browser and Better Auth's single-use PKCE exchange. The authority verifies the employee and current role; organization mode never substitutes dev@openbot.local. Employees do not need project-key administration privileges. Installation happens once: reopening or refreshing an expired organization, Intelligence or model connection preserves the installed runtime and data and opens the relevant connection screen.

Keeping it to your machine

  • agent-computer drives a browser holding real logins. docker-compose.yml binds it to loopback; leave it there.
  • Store credentials through /admin/credentials, which encrypts them. Do not put credential values in tenant YAML or in committed files.
  • AGENT_COMPUTER_ALLOW_PRIVATE_HOSTS lets a Bot reach services on this machine. It ships commented out in .env.example, is for a laptop only, and a deployment running with NODE_ENV=production refuses to start while it is set.
  • To reach an agent on your own network from a deployment, list its address in AGENT_ENDPOINT_ALLOWED_HOSTS instead. That permits the one address, where the switch above permits the network.

Development

bun run format:check
bun run lint
bun run typecheck
bun run test
bun run build

After changing the Drizzle schema:

bun run --filter server db:generate
bun run --filter server db:migrate

Use bash scripts/start.sh for the whole stack and bash scripts/stop.sh to take it down. Use bun run dev only when you want the app and server without the Docker Bots and computers.

Documentation

Contributing

  • Open an issue or coordinate before starting substantial work.
  • Keep changes focused and update docs when setup, configuration, architecture, or user behavior changes.
  • Keep secrets, service-account JSON, customer data, and local transcripts out of the repository.
  • Run the checks in Development before opening a pull request.

License

MIT © CopilotKit

의견

판정에 대한 반론, 도입 경험, 정정 제보를 환영합니다. GitHub 계정으로 참여합니다.

이것도 재봤습니다

전체 리포트 →