fx 하네스
fx 하네스 (fx Harness)
fx 하네스 어댑터는 Agent Client Protocol(ACP)을 통해 HarnessAgent를 fx에 연결해요. 어댑터는 설치, 세션, 스트리밍, 도구, 수명주기 관리를 @ai-sdk/harness-acp에 위임해요.
참고: 하네스 패키지는 실험적이에요. 이 초기 API가 더 다듬어지면서 릴리스 사이에 파괴적인 변경이 예상돼요.
출처: 문서
본문
셋업 (Setup)
npm install @ai-sdk/harness @ai-sdk/harness-fx @ai-sdk/sandbox-vercel
ACP 하네스는 첫 세션이 시작될 때 샌드박스 안에서 정식 fx 설치 프로그램을 실행해요. 설치 프로그램은 최신 fx 릴리스를 추적하고 실행 파일을 ACP 구현의 프라이빗 홈 디렉터리에 설치해요.
Import
import { createFx, fx } from '@ai-sdk/harness-fx';
fx는 기본 구성으로 createFx()를 호출한 것과 같아요.
기본 사용법 (Basic Usage)
import { HarnessAgent } from '@ai-sdk/harness/agent';
import { fx } from '@ai-sdk/harness-fx';
import { createVercelNetworkSandboxSession } from '@ai-sdk/sandbox-vercel';
const agent = new HarnessAgent({
harness: fx,
model: 'openai/gpt-5.6-luna',
});
const sandboxSession = await createVercelNetworkSandboxSession({
runtime: 'node24',
ports: [4000],
template: await agent.getSandboxTemplate(),
});
const session = await agent.createSession({ sandboxSession });
let exitCode = 0;
try {
const result = await agent.stream({
session,
prompt: 'Check the test failures and fix the production code.',
});
for await (const part of result.stream) {
if (part.type === 'text-delta') {
process.stdout.write(part.text);
}
}
} catch (err) {
exitCode = 1;
console.error(err);
} finally {
await session.destroy();
await sandboxSession.destroy();
process.exit(exitCode);
}
어댑터 설정 (Adapter Settings)
createFx()로 런타임을 구성하세요:
const harness = createFx({
auth: 'ai-gateway',
port: 4001,
startupTimeoutMs: 180_000,
});
설정:
auth:auto,direct,ai-gateway인증을 선택하거나 프로그램적으로 해결된 자격 증명용 인증 환경을 받아요. fx는 항상 Vercel AI Gateway를 통해 모델 요청을 보내므로,direct와ai-gateway는 하네스가 Gateway 자격 증명을 샌드박스로 전달하는 방식만 다를 뿐이에요.credentialForwarding: 하네스 어댑터가 각 자격 증명을 샌드박스 프로세스로 전달하기 직전에 커스터마이즈하는 선택 동기/비동기 콜백. 그렇지 않으면 전달될 자격 증명 값(실제 자격 증명 또는 마스킹된 값)과 이를 노출하는 데 쓰는 환경 변수 이름을 받아요. 이 콜백은 샌드박스 프로세스로 전달되는 값만 제어해요. 하네스 어댑터가 호스트 프로세스에서 어떤 자격 증명을 발견·읽거나 접근할 수 있는지는 제한하지 않아요.mcpServers: 서버 이름별 MCP 서버 정의. fx ACP 세션은 ACP 클라이언트가 제공한 서버만 사용해요.port: ACP 브리지 포트 재정의.portEndpoint: 샌드박스 세션이 포트를 직접 노출할 수 없을 때 ACP 브리지의 호스트 엔드포인트.startupTimeoutMs: ACP 브리지가 시작될 때까지 기다릴 최대 시간.reconnect: 브리지 WebSocket 연결이 끊긴 후 재연결 타이밍.maxElapsedMs는 연결 설정과 백오프 지연을 포함한 전체 재시도 창을 제어하며 기본 30초.initialDelayMs기본 50밀리초,maxDelayMs기본 2초. 이 재시도는 지수 백오프를 사용하며startupTimeoutMs와 별개예요. 샌드박스, 브리지 프로세스, 브리지 엔드포인트가 영구적으로 사용 불가하면 복구할 수 없어요.mintBridgeToken: 샌드박스 id를 받고 ACP 브리지 인증 토큰을 반환하는 동기 함수. 기본적으로 어댑터는 무작위 32바이트 토큰을 생성해요.
어댑터는 설치 소스, 실행 파일, 런치 명령, ACP 버전을 고정해요. 이 구현 세부사항은 createFx()로 재정의할 수 없어요.
인증 (Authentication)
fx는 Vercel AI Gateway 인증을 사용해요. 다음 환경 변수 중 하나를 설정하세요:
VERCEL_OIDC_TOKENAI_GATEWAY_API_KEY
적용 가능한 자격 증명 환경 변수가 없으면, AI Gateway 인증이 선택되지 않는 한 어댑터는 호스트 시스템에서 네이티브 구독을 해결하려 시도해요.
둘 다 있으면 fx는 VERCEL_OIDC_TOKEN을 선호해요. 샌드박스가 요청 변환을 지원하면 어댑터는 선택된 자격 증명을 구성된 Gateway origin에만 브로커링해요. 다른 샌드박스는 직접 자격 증명 전달을 유지해요.
process.env로 노출하는 대신 호스트가 런타임에 자격 증명을 해결할 때 인증 환경을 전달하세요:
const gatewayHarness = createFx({
auth: {
AI_GATEWAY_API_KEY: await resolveGatewayToken(),
AI_GATEWAY_BASE_URL: 'https://ai-gateway.vercel.sh',
},
});
제공된 record는 인증 발견을 위해 호스트 환경을 대체해요. 어댑터는 자격 증명을 process.env에 추가하거나 유지되는 ACP 수명주기 식별자에 그 값을 포함하지 않아요.
두 인증 구성 모두 AI Gateway에 도달해요:
const directHarness = createFx({ auth: 'direct' });
const gatewayHarness = createFx({ auth: 'ai-gateway' });
샌드박스 (Sandbox)
fx는 @ai-sdk/harness-acp를 통해 샌드박스 안에서 실행돼요. 노출된 포트가 하나 이상 있는 네트워크 샌드박스가 필요해요:
const sandboxSession = await createVercelNetworkSandboxSession({
runtime: 'node24',
ports: [4000],
template: await agent.getSandboxTemplate(),
});
첫 세션은 fx를 다운로드하려면 네트워크 이그레스가 필요해요. 이후 모델·웹 요청도 네트워크 접근이 필요해요.
내장 도구 (Built-in Tools)
어댑터는 glob_files, grep_files, web_search를 공통 하네스 도구 이름 glob, grep, webSearch로 매핑해요.
다른 도구는 네이티브 fx 이름으로 계속 사용할 수 있어요. list_files, read_file, write_file, edit_file, 파일 수정·메타데이터 도구, terminal, semantic_search, web_fetch, 스킬 도구, 하위 에이전트, MCP 발견 도구, ask_user_question, vision, read_tool_result가 포함돼요.
어댑터는 allow-reads와 allow-edits를 fx의 ask ACP 모드로 매핑해요. allow-all은 fx의 code ACP 모드로 매핑돼요. allow-edits 매핑은 보수적인데, fx는 터미널 명령에 여전히 승인을 요구하면서 파일 편집을 허용하는 모드를 제공하지 않기 때문이에요. fx는 안전한 작업을 해결하거나 ACP 권한 요청을 보내지 않고 자체 권한 정책을 적용할 수 있어요.
알려진 제한 (Known Limitations)
- fx의 ACP v1 도구 업데이트는 권한을 요청할 때를 제외하고 프로그램적 도구 이름과 원시 입력을 생략해요. 네이티브 도구는 여전히 실행되지만, 일반 네이티브 도구 이벤트는 항상 타입 있는 내장 도구 이름과 연관될 수는 없어요.
- ACP v1은 모델 스텝 경계나 스텝별 사용량을 노출하지 않아요. 어댑터는 경계를 추론하고 fx가 합계를 제공하지 않을 때 알 수 없는 스텝별 사용량을 보고해요.
- ACP v1에는 휴대 가능한 수동 압축 또는 미드 턴 스티어링 API가 없어요.
- ACP v1에는 휴대 가능한 내장 도구 필터링 API가 없어요. 호스트 도구 필터링은 지원되지만 fx 내장 도구를 필터링하면 지원되지 않는 역량 오류가 throw돼요.
- fx ACP는 구조화 출력 메타데이터 매핑을 노출하지 않으므로 스키마 기반 구조화 출력은 지원되지 않아요.
- 커스텀
headers는 네이티브로 지원되지 않고 샌드박스 외부 요청 변환을 통해서만 적용돼요. 그 역량이 없는 샌드박스가 제공되면 커스텀headers를 전달할 수 없어 무시돼요.