-
Notifications
You must be signed in to change notification settings - Fork 0
Providers and Agents ko
English | 中文 | 日本語 | 한국어 | Español | Português | Русский
lib/llm-client.js가 프로토콜 층이다. 네 스트림 모두 하나의 openSseStream() 골격(fetch / 에러 분류 / 예산 협상 / 중단 / SSE 프레이밍 / 마무리)을 공유한다; 각 프로토콜은 buildRequest + 순수 이벤트 파서만 유지한다. SSE data: 페이로드 추출은 단일 출처다(sseDataPayload, 스펙대로 멀티-데이터-라인 조인):
| apiStyle | 엔드포인트 | 비고 |
|---|---|---|
chat |
/v1/chat/completions |
DeepSeek 스타일 reasoning_content도 파스한다 |
responses |
/v1/responses |
네이티브 input_* 멀티모달 표기 |
anthropic |
/v1/messages |
두 브레이크포인트(시스템 + 마지막 메시지)에 명시적 cache_control — Anthropic에는 암시적 프리픽스 캐싱이 없다 |
runs |
Hermes /v1/runs
|
에이전트 프로토콜: 승인 / 확인 / 도구 / thinking 이벤트 |
thinking: 'inline' | 'omit'(기본 omit)은 reasoning 텍스트가 델타 스트림에 하나의 <thinking> 블록으로 인라인으로 실리는지를 제어한다; 메인 채팅과 디테일 스레드만 inline을 쓴다. runs의 reasoning.available 필드는 thinking이 아니라 답변 리플레이다 — 에코 가드가 이를 드롭해야 한다(ADR-0004).
프로바이더별 요청 형태는 메인 채팅에서 네 번 재건된다(초기 / 오버플로 재건 / 계속 / 타임스탬프 재작성), createTurnRequest(prepare / rebuildFrom / continueWith / rewriteWith)로 통합되었다 — chat-handler는 WHEN을, 사다리는 HOW를 소유한다. 디테일 스레드는 의도적으로 이것을 쓰지 않는다(격리 세션 의미론, ADR-0007).
- 기본
max_tokens32768; 상한 초과 예산을 400으로 거절하는 서버에는 에러 텍스트에서 파스한 상한으로renegotiateOutputCap재시도를 한 번 한다. -
finish_reason === 'length'→ 조용한 계속 패스 한 번(반복 방지 지시, 델타 삼킴); 그래도 절단되면 DONE이outputTruncated를 싣고, 패널이 토스트 + 원클릭 "계속" 버튼을 보여준다. 수동 max_tokens 필드는 의도적으로 존재하지 않는다 — "모델별 지식을 요구하는 노브는 설계 버그다".
| 에이전트 | 채널 | 세션 |
|---|---|---|
| Hermes | /v1/runs |
서버 측(storage의 sessionId); 현재 턴 파트는 정규 text/image_url을 쓰고, conversation_history는 문자열 전용이다(strict 레이어 422, 2026-09-24 검증) |
| OpenCode |
opencode serve HTTP |
서버 측; 기본은 랜덤 포트 → 고정 --port 권장 |
| OpenSquilla | 로컬 게이트웨이 ws://…/ws
|
대화당 하나의 게이트웨이 세션; 60K자를 넘는 첨부는 page-context.md 문서로 업로드; 오리진 허용목록 — 보안 모델 참조 |
| Agent Bridge |
@xiaohuzai/agent-bridge 로컬 데몬 |
하나의 HTTP 프로토콜 뒤에서 codex/claude/pi/gemini을 적응시킨다; 구독 로그인이 모델 소스로 동작 |
공유 층 lib/agent-turn.js: 에이전트 턴은 사용자의 현재 턴 + 후행 페이지-컨텍스트 실행만 보낸다(트랜스크립트는 서버 측에 산다; 히스토리는 재전송되지 않는다). 이미지는 pickTurnImages를 거친다(≤8 이미지 / ≤3MiB URL 예산; 첨부 시점 게이트와 전송 시점 게이트가 서로를 거울처럼 반영한다). 대화 중 에이전트 프로바이더로 전환하면 「带上当前对话继续」(현재 대화를 가져가 이어하기)를 제안한다 = 1회성 backfill(평문 트랜스크립트, 200K자 꼬리 상한).
에이전트 프로바이더의 트랜스크립트는 이미 서버 측에 산다(에이전트 턴은 현재 턴만 보낸다) — "에이전트 자체 UI에 넘겨주기"에는 데이터 이동이 아니라 발견 가능성이 필요하다. 두 조각:
-
자동 이름짓기: 성공한 Hermes 턴 후 1회성
PATCH /api/sessions/{id}(업스트림 원본 API; 서버가 제목을 살균하고 정확한 충돌은 거절한다)가 제목을browsa:+ 현재 턴 사용자 텍스트의 첫 줄(48자 상한)로 설정한다. 한 번만 스탬프 의미론(hermesSessionTitled_<provider>, 세션 id와 같은 수명 주기): 성공과 4xx 모두 스탬프 (제목 충돌이 턴마다 재시도 루프가 되어서는 안 된다); 전송 실패(status 0)만 다음 성공 턴을 위해 스탬프 없이 머문다. PATCH는 10s 타임아웃이고 그 await는 2.5s 상한과 레이스해 DONE이 절대 매달리지 않는다. 오늘의 채널: Hermes(PATCH /api/sessions/{id})와 bridge/codex(데몬의POST /threads/{id}/title→ app-serverthread/name/set, codex 0.149.1에서 라이브 검증 — 이름은 codex의 상태 DB에 영속되고codex resume이 이름이나 id로 해석한다; 네 브리지 에이전트의 Picker 가시성 판정(2026-10-01 소스 검증): codex ✓ (픽커 술어has_user_event = 1 AND title <> ''— 실제 턴은 충족; 전역 상태 DB, cwd 스코핑 없음; 데몬의POST /threads/{id}/title→ app-serverthread/name/set으로 이름짓기). claude ✓ 브리지의transcriptFix: 'claude'가 매 정착 턴 후 디스크의 자기-스탬프entrypoint: sdk-*를cli로 재작성하기 때문(에이전트 브리지 #56, Mac 확인) — 클라이언트 이름바꾸기 채널 없음(claude-agent-acp가 자동 제목), 픽커에서나 ID로 resume 가능. pi ✓ (ACP 세션은 픽커가 읽는 pi 자체의 cwd-스콥 저장소에 들어간다; 스코프 토글 + 이름 필터; pi의 네이티브set_session_nameRPC가session_info이름 엔트리를 쓴다 — pi-acp는 그것을 턴 중/name명령으로만 노출, 아직 브리지에 배선되지 않음). gemini ✓ (목록은kind:"subagent"만 제외; 브리지 세션은kind:"main"; 저장소~/.gemini/tmp/<cwd>/chats/, cwd-스콥; 이름 채널 없음 — 제목은 첫 사용자 메시지에서 온다). opencode/squilla 미검증. 디테일 스레드의 전용 세션은 의도적으로 이름 붙지 않는다.) -
세션-ID 표시:
storage.getAgentSessionInfo가 종류별 세션-키 형태를 단독 소유한다(bridge는activeModel || baseUrl로 엔드포인트별 키); 세션 드로어는 목록 위에 "에이전트 세션" 줄(짧은 id + 복사)을 렌더하고, LLM 프로바이더 / 세션이 없을 때는 숨긴다.
에이전트 도구 승인과 확인 프롬프트는 lib/handlers/approval-relay.js로 중계된다(메인 채팅은 tabId 키, 디테일 스레드는 subId 키). 대기-엔트리 형태가 곧 디스패치 인터페이스다. UI 측에서는 turn-chrome.js가 두 표면이 공유하는 턴 크롬이다(대기 표시기, 도구 진행, 승인/확인 카드, 사용량 칩).
- 드롭다운은 구성된(CONFIGURED) 프로바이더만 나열하고, 도달 가능한 것 우선(안정 정렬); 구성된 것이 0이면 비활성 플레이스홀더 하나.
- 저장된 activeProvider가 구성되지 않았으면 첫 구성 프로바이더가 자동 선택되고 영속화된다(상태 수리지 선호가 아님); 첫 도달 가능 ping도 (한 번) 자동 전환한다.
- 멀티 모델 프로바이더: 쉼표 구분 모델 ID; 모델당 드롭다운 엔트리 하나;
resolveChatModel은 activeModel이 그 프로바이더에 여전히 속하는 동안만 이를 존중한다. - 두 그룹(LLM / 에이전트)은 탭 카드로 렌더된다(에이전트 그룹 기본 접힘; 탭 순서 [bridge, opencode, hermes]는 테스트 핀).
모든 CHAT 턴의 시스템 프롬프트 = 사용자 systemPrompt + 답장 언어 줄 + CAPABILITY_HINTS + CHOICE_REQUEST_HINT; 바이트 안정 프리픽스를 유지해야 한다(턴별 키워드 게이팅은 위치 0부터 KV 프롬프트 캐시를 깬다). 남아 있는 모든 엔트리는 실제 렌더링 버그로 자기 값을 증명했다 — why-절을 "다듬으려면" AGENTS.md 역사를 먼저 읽어라. 놓친 포맷의 해법은 더 나은 힌트지 런타임 탐지가 아니다.
원본 출처: AGENTS.md "Provider API styles", chat/subchat-handler, provider-resolver, 에이전트별 절; ADR-0004 / 0007 / 0010. 권위판: Providers-and-Agents(영어) / Providers-and-Agents-zh(중국어) — AI 초벌 번역 스냅숏, 동기화 2026-10-01.
English
- Home
- Architecture
- Rendering Pipeline
- Storage Model
- Providers and Agents
- ASR and Video Analysis
- Security Model
- Design Decisions
- Contributing
中文
相关 / Related
日本語
한국어
Español
- Inicio
- Arquitectura
- Pipeline de renderizado
- Modelo de almacenamiento
- Proveedores y agentes
- ASR y análisis de vídeo
- Modelo de seguridad
- Decisiones de diseño
- Contribuir
Português
- Início
- Arquitetura
- Pipeline de renderização
- Modelo de armazenamento
- Provedores e agentes
- ASR e análise de vídeo
- Modelo de segurança
- Decisões de design
- Contribuindo
Русский