플랫폼이 부르는 도구
spec 은 도구 하나하나의 계약을 정하지 않는다 — 카탈로그는 에이전트가 describe_tools 로 알려 주는 대로 받는다.
예외가 플랫폼이 스스로 부르는 도구다. 아래 도구는 relay-service·command-service 가 이름을 알고 부르며, 출력의 필드를 읽는다.
이 표가 그 도구들의 계약이다. 에이전트는 여기 적힌 입력을 받아들이고, 적힌 출력 필드를 그 이름 그대로 준다.
에이전트는 필드를 더 줄 수 있고, 플랫폼은 모르는 필드를 무시한다. 표에 없는 kind 는 그 도구를 구현하지 않아도 된다.
| 도구 | kind | 누가 부르나 | 입력 | 출력에서 읽는 필드 |
|---|---|---|---|---|
describe_tools |
전부 | relay (핸드셰이크) | {} |
tools[] — name, description, input_schema, requires_confirmation |
workspace_info |
전부 | relay (핸드셰이크) | {} |
객체 전체 (64 KiB 까지 저장, 넘으면 {truncated: true}) |
screenshot |
chrome, android | command-service (GET /resources/{id}/screen) |
{deliver_image: true} |
mime_type + image_base64 또는 image_blob(v1.1). 있으면 width·height |
app_list |
android | command-service (GET /resources/{id}/device-apps) |
{} |
apps[] — package, label, icon_png_base64(선택) |
app_launch |
android | app-service (POST /shortcuts/{id}/launch) |
{package} |
상태만 본다 (ok 면 열렸다) |
app_stop |
android | 사용자 명령 (기기 앱 창 닫기) | {package} |
상태만 본다 |
세부 규칙
섹션 제목: “세부 규칙”screenshot
섹션 제목: “screenshot”- 화면 동기화(prototype-web 의 App 창·기기 앱 창)는 이 도구를 주기적으로 부르는 것이다. command-service 는 리소스당 초당 2장을 넘겨 부르지 않고,
max_age_ms안의 화면은 다시 찍지 않는다. deliver_image: true를 주지 않으면 chrome·android 는image_id만 준다 — 플랫폼은 늘true를 준다.- 이미지가
relay_config.max_inline_bytes(256 KiB)보다 크면 v1.1 에이전트는 블롭으로 올리고image_blob을 준다. v1 에이전트는 base64 로 싣되, 프레임 상한(8 MiB)을 넘지 않게 줄여야 한다 (android 는 원본 PNG 를 8 MiB 까지 허용해 base64 로 바꾸면 상한을 넘을 수 있다 — 에이전트 감사의 항목). mime_type은image/png·image/jpeg·image/webp중 하나.
app_list
섹션 제목: “app_list”- 실행할 수 있는 앱만 준다 (런처 activity 가 있는 것). 정책(
--packages)에 막힌 앱은 빼고 준다 — 오류로 만들지 않는다. icon_png_base64는 선택이다. 주면 48~96px 정사각형 PNG, 앱 하나에 8 KiB 까지. 플랫폼은data:image/png;base64,…로 바꿔DeviceApp.icon_data_url에 싣는다. 넘으면 버린다 (null).- 앱이 많으면(수백 개) 출력이 커진다. 아이콘을 빼고 줘도 된다 — 화면이 기본 아이콘을 그린다.
app_launch
섹션 제목: “app_launch”- 이미 떠 있으면 앞으로 가져온다 (오류가 아니다).
- 실행할 수 없는 패키지면
status: "error",error_code: "app_not_launchable". 정책에 막혔으면error_code: "capability_denied".
OS interface 1.0
섹션 제목: “OS interface 1.0”os_capabilities({})는 현재 지원 기능·설치 정책·한도를 반환한다. os_execute({type,input})는 공통 OS 계약의 동작을 실행하고 {interface_version,type,result,extensions?}를 반환한다. schema는 rest/os-interface.tsp에서 생성한 os-interface.json이 기준이다. 기존 도구와 연결 프레임은 유지한다.
Storage 경로 도구 workspace_storage_path (ENDUE-1162)
섹션 제목: “Storage 경로 도구 workspace_storage_path (ENDUE-1162)”연결된 Storage 의 파일·폴더를 경로 단위로 넣고 빼고, 다른 Storage 를 가리키는 링크를 기기에 펼친다. 에이전트는 ready.capabilities 에 workspace_storage_path_v1 을 알린다. 이 능력이 없는 에이전트가 연결한 Storage 는 분리 상태에서만 이동·복사의 대상·원본이 되고, 링크를 걸거나 링크로 쓰는 일은 STORAGE_CAPABILITY_REQUIRED 로 거절된다.
플랫폼(workspace-service)만 이 도구를 부른다. 경로는 모두 Storage 루트 기준 상대 경로이고 에이전트가 아는 그 Storage 의 루트 안에서만 푼다. 권한(token)은 그 작업·링크·Storage·generation 에 묶인 단기 bearer 다.
| 모드 | 입력 | 하는 일 | 출력에서 읽는 필드 |
|---|---|---|---|
save_path |
storage_id, path, token, seal?, seal_until? |
그 경로만 스캔·업로드하고 경로 단위로 커밋한다. seal 이면 그 경로를 기기에서 읽기 전용으로 두고 seal_until 까지 기억한다 |
revision, sealed |
unseal_path |
storage_id, path |
봉인을 푼다. 명령이 닿지 않아도 seal_until 이 지나면 스스로 푼다 |
상태만 본다 |
place_path |
storage_id, path, token, revision |
그 revision 에 스테이징된 경로 아래를 받아 임시 폴더에서 해시를 확인하고 이름을 바꿔 공개한 뒤 경로 단위로 커밋한다. 경로가 이미 있으면 error_code: "storage_path_exists" |
revision |
remove_path |
storage_id, path, token, expected_hash |
저장한 뒤 바뀌지 않았는지 확인하고 기기에서 지운 뒤 제거를 커밋한다. 바뀌었으면 error_code: "storage_state_conflict" |
revision |
link_pull |
link_id, path, token, revision |
링크 대상 경로 아래를 받아 링크 경로에 공개한다. 이미 있으면 차이만. 기기에서 아직 저장하지 않은 링크 변경이 있는 파일은 덮지 않는다 | revision |
link_push |
link_id, token |
링크 경로 아래의 바뀐 경로만 대상 Storage 로 커밋한다. 저장할 때마다 함께 부른다 | revision, overwritten[] |
link_remove |
link_id, path |
링크 내용을 지운다. 저장하지 않은 변경은 복구 폴더(.endue-storage-recovery-*)로 옮긴다. 끊긴 링크면 빈 읽기 전용 폴더로 둔다 |
recovered[] |
path_sync |
storage_id, token, revision, paths[] |
원격에서 바뀐 경로를 받아 기기에 합친다. 기기에서 저장하지 않은 같은 파일은 덮지 않는다(다음 저장 때 나중 저장이 이긴다) | revision |
- 같은 파일을 여러 writer 가 저장하면 나중 저장이 이긴다. 덮인 내용은 이전 revision 에 남는다.
link_push의overwritten[]은 그렇게 덮어쓴 경로다. - 저장(
push)은 링크 경로를 스캔에서 빼고, 기준 revision 뒤의 원격 변경을 먼저 합친 뒤 바뀐 경로만 커밋한다. - 링크 루트 폴더를 기기에서 지우면 대상을 지우지 않고 다시 만든다. 링크 안의 파일을 지우면 대상에서도 지운다.