← Docs hub

DeviceAgent Device Context v2 Contract

device_context.v2는 DeviceAgent가 가진 기능과 상태를 Cloud A2A Planner가 안전하게 조합하기 위한 관찰 계약이다. 사용자 발화별 분기 규칙을 늘리는 대신, Planner가 Capability Card와 현재 상태 증거를 함께 보고 계획하도록 한다.

Device Context v2 Flow

1. 왜 v2가 필요한가

현재 MR6 DevicePlanningContextProviderdevice_context.v1은 다음 정보를 제공한다.

이 정보만으로는 이동과 청정 workflow는 만들 수 있지만, 아래 판단은 불완전하다.

v2는 더 많은 raw 값을 Cloud에 보내는 계약이 아니다. 각 domain이 raw 상태를 의미 상태, 신선도, 출처, 완료 증거로 바꿔 제공하는 계약이다.

2. 두 개의 context surface

Surface 소비자 내용 원칙
device_context.v2 DeviceAgent, on-device bridge, TaskManager, debug UI 전체 semantic domain 상태와 evidence 내부 계약. raw media와 credential은 금지
planner_context_summary.v2 Cloud A2A Planner 후보 Capability Card가 요구한 allowlist만 포함 token-safe, privacy-safe, TTS와 분리

전체 v2 snapshot을 LLM prompt에 그대로 넣지 않는다. Router가 후보 capability를 선정하면 context_reads의 합집합과 기본 admission 상태만 축약한다.

사용자 목표
  -> catalog/shadow owner 후보
  -> Capability Card 후보
  -> context_reads 합집합
  -> freshness/privacy 검사
  -> planner_context_summary.v2
  -> LLM plan
  -> DeviceAgent grounding/admission

이 구조에서 LLM은 “무슨 목표를 어떤 capability 순서로 달성할지”를 판단하고, DeviceAgent는 “현재 기기에서 실제로 허용되고 실행 가능한지”를 판정한다.

3. 공통 domain envelope

모든 domain은 같은 envelope를 사용한다.

{
  "available": true,
  "freshness": {
    "observed_at_ms": 1785326399950,
    "received_at_ms": 1785326399980,
    "age_ms": 50,
    "ttl_ms": 2000,
    "state": "fresh"
  },
  "provenance": {
    "source_component": "DeviceAgent",
    "source_symbol": "MovingController.getCurrentPosition",
    "source_event": "movement_state_snapshot",
    "source_kind": "domain_state",
    "sequence": 41
  },
  "planner_exposure": "summary",
  "sensitivity": "sensitive",
  "data": {}
}
필드 의미
available producer가 유효한 의미 상태를 만들 수 있는지
unavailable_reason unavailable을 빈 값과 구분하는 reason
observed_at_ms 실제 상태를 관찰한 시각
received_at_ms context aggregator가 수신한 시각
age_ms, ttl_ms, state stale 판단
source_component, source_symbol 값의 실제 코드 소유자
source_event, sequence callback/event 순서와 중복 제거 근거
planner_exposure summary, condition-only, internal-only, blocked
sensitivity 일반, 민감, 제한 정보
field_evidence domain보다 빠르게 변하는 핵심 필드의 별도 evidence

available=false, state=stale, 값 누락은 서로 다른 상태다. Planner가 이 세 상태를 모두 “false”로 해석하면 조건부 task가 잘못 실행될 수 있다.

현재 Cloud condition evaluator는 원본 JSON path를 직접 읽는다. 값이 없을 때 not_equals가 참으로 평가되거나 지원하지 않는 operator가 fail-open되는 경로가 있어, v2 전환 시에는 KNOWN / UNKNOWN / STALE 3상태 평가와 fail-closed를 적용해야 한다.

4. 실제 기능과 관찰 데이터

아래 표는 “무엇을 할 수 있는가”뿐 아니라 시나리오 조합에 필요한 입력, 관찰, 완료 증거를 함께 정리한다.

4.1 이동·Map

기능 실제 소유자 입력 진행 관찰 완료·실패 증거 조합 예
공간 이동 MovementTaskExecutor.setMoveTo room/area/position, timeout current/target room, moving/paused/blocked movement.arrived, COMPLETED/FAILED/CANCELLED 이동 후 청정·VitalSign
스테이션 복귀 MovementTaskExecutor.returnToStation timeout 이동 상태, station 접근 movement.stationCharging workflow 최종 보상
이동 중지 stopMovement active task correlation controller idle physical idle + terminal event 사용자 취소
Follow-me AMR/Movement domain enable follow status 현재 M2, terminal 보강 필요 따라오며 콘텐츠
Map/공간 조회 MapManager 없음 revision, edit 상태, room catalog snapshot 자연어 공간 grounding

Planner에는 방 이름과 runtime ID만 제공하고 x/y/theta는 runtime grounding에 남긴다. 임의 좌표 생성, 부분 이름 첫 일치, 숫자 변환 실패의 0 fallback은 admission에서 거부해야 한다.

4.2 청정·공기질

기능 실제 소유자 입력 진행 관찰 완료·실패 증거 조합 예
고정 청정 CleaningAmpTaskExecutor action/mode/speed/AI running, paused, target area cleaning.started/stopped 현재 방 즉시 청정
전체 청정 cleaning domain mode/time/speed area progress cleaning.reportDone 전 공간 관리
선택 공간 청정 startSelectiveAirClear Area 목록 current area/step step complete/report done 여러 방 순차 청정
공기질 기반 청정 startAirSensorAirClear sensor/time policy grade/trend report done 상태 적응형 청정
청정 중지 stopCleaning, ampStop active task stopped state cleaning.stopped 이동 전 선행 정지
공기질 해석 AirQualityManager sensor snapshot grade, dominant factor, trend fresh snapshot ODL 관찰 후 DEF 설명

PM·CO2 등의 raw 값은 내부 evidence로 보존할 수 있지만 Planner에는 등급·추세· 주요 원인처럼 의사결정에 필요한 semantic summary를 우선 제공한다.

4.3 Vision·사람·조도

기능 실제 소유자 raw 입력 Planner용 의미 상태 정책
사람 감지 VisionAIManager class/confidence/bbox present/absent/uncertain raw frame/bbox 금지
지속 감지 WssVisionObserver 시간 누적 detection sustained presence 보안 domain만 직접 소유
저조도 Vision report light level low_light true/false evidence 품질 판단
카메라 상태 Vision service health 연결/오류 normal/degraded/unavailable capability 차단
화면 틸팅·매너 Vision local scenario person state domain-owned trigger Planner raw 제어 금지

Vision은 단독 사용자 capability보다 관찰 producer다. 새로운 시나리오는 person.present를 조건으로 쓸 수 있지만 confidence threshold와 debounce는 Vision domain이 소유해야 한다.

4.4 WSS 보안

기능 실제 소유자 입력 상태 모델 완료 증거 현재 범위
가용성 확인 checkSecurityBasicAvailability 사용자/정책 상태 reason bitmask immediate result TaskManager
보안 시작 startSecurityMode mode/areas/repeat running/stage/current area security.started TaskManager
순찰 WSS domain state machine Area list moving/person/verify/upload security.patrolCompleted domain-owned
pause/resume/stop MainApiTaskExecutor + WssManager current session paused/running/stopped security.paused/resumed/stopped TaskManager 코드 연결, 실기기 검증 필요
PIN/얼굴 검증 WSS verify verification request verify stage/result typed result 필요 M2
증거 업로드 WSS + Streaming/AWS event asset/correlation queued/uploading/retry upload result 민감

WSS는 카메라·Vision·AMR motion·security session을 독점한다. 음성 세션, VitalSign, LiveView와의 충돌은 공통 resource lease로 승격해야 한다.

4.5 LiveView·Streaming

기능 실제 소유자 입력 관찰 조합 제한
시작·종료 StreamingManager user/room/signed URL/correlation starting/running/stopping/stopped explicit consent
원격 수동 이동 IStreamingControl movement/rotation obstacle/keep-out/error AMR manual lease
영상 업로드 Streaming callback key/URL/expiry upload lifecycle raw URL prompt 금지
Vision 전환 StreamingManager stream lifecycle Vision enabled/disabled camera lease

현재 exported Binder 인증과 TaskManager terminal 계약이 완성되지 않아 Capability Card는 NO_GO다. 문서에 있다고 Planner에 노출해서는 안 된다.

4.6 LLM·STT·TTS·콘텐츠

기능 실제 소유자 관찰 상태 조합 의미
STT on-device Agent + LlmManager listening/processing 사용자의 개입 구간
Cloud/on-device LLM on-device Agent processing/ready/error local/cloud fallback
TTS LlmTtsTaskExecutor, LlmManager requested/processing/playing/stopped 음성 출력 자원
콘텐츠 DEF/FRG/STM/ETR agent session owner, response result 이동·청정과 병행 가능
stop/pause/resume voice runtime session state 다른 장기 workflow 개입

setLlmTts 성공은 playback 완료가 아니다. “설명이 끝나면 이동”을 보장하려면 tts.playbackCompleted 또는 동등한 terminal evidence가 필요하다.

4.7 AWS·네트워크

기능 실제 소유자 관찰 상태 Agent 활용
MQTT 연결 AWSIoTMQTTClient connected/reconnecting/disconnected Cloud 의존 단계 admission
command ingress CmdTopic, IotTaskManagerBridge accepted/correlation legacy/managed 경계
response publish IotAgent last result/error/time callback 재전송
Wi-Fi platform/network callback connected/quality local fallback
OTA·signed URL update/AWS domain available/expiry/result 유지보수·업로드

getAwsConnect는 live probe가 아니라 callback cache이므로 connected_cached + observed_at + last_success + last_error를 함께 제공한다. MQTT accepted는 물리 task 완료가 아니다.

4.8 Schedule·Interaction

시간 모델 소유자 terminal
반복 제품 예약 Product ScheduleManager 매일 8시 웰컴 product schedule lifecycle
일회성 절대 시각 TaskManager scheduler 20분 뒤 청정 scheduled admission event
단계 상대 지연 workflow after_step + delayMs 도착 30초 후 앱 실행 dependency + delay elapsed
event continuation TaskManager workflow 청정 끝나면 복귀 completion target

Interaction은 started -> arrived -> actionStarted -> actionEnded -> returning -> completed를 자체 소유한다. Planner는 내부 단계를 다시 분해하지 않고 product_interaction 하나로 다루는 것이 안전하다.

4.9 VitalSign·앱 세션

기능 실제 소유자 관찰 완료 판단
앱 실행 setLauncherScreen app session started 시작만 확인
앱 상태 MainApi.setAppStatus started/ended 세션 종료
측정 결과 VitalSign app 현재 typed result 없음 성공·취소 구분 불가

현재 app.sessionEnded를 측정 성공으로 간주하면 안 된다. VitalSign은 복합 workflow의 마지막 단계 또는 사용자 확인 checkpoint로 제한한다.

4.10 건강·정비·리소스

관찰 실제 source 의미 상태 활용
배터리 BatteryManager, ErrorHandler normal/low/charging/work budget 장기 task 축소·복귀
CPU/RAM/thermal TaskResourceMonitor normal/high/critical admission 지연
필터·부품 filter/part managers normal/replacement due 예방 정비
firmware UpdateManager idle/downloading/installing/failed 실행 차단
오류 ErrorHandler active/resolved, domain 원인 기반 replan
자원 lease 현재 domain별 분산 camera/motion/mic/display owner 충돌 방지

현재 TaskResourcePolicy는 opt-in CPU/RAM/thermal threshold만 공통 처리한다. 카메라·Vision·VitalSign·WSS·Streaming·마이크·디스플레이 lease는 아직 domain별 정책에 흩어져 있다.

5. v2 domain과 source

v2 domain 현재 producer Planner 노출 권장 기본 TTL
core StateManager ready/main interaction owner 2초
battery BatteryManager, ErrorHandler 잔량·저전력·작업 budget 10초
spatial MapManager, MovingController, AMR 방·위치·이동 의미 상태 2초, Map은 revision
environment AirQualityManager, CleaningTransaction 공기질 등급·추세·청정 상태 30초
voice_llm LlmManager, on-device Agent voice/TTS/LLM owner 2초
policy state/policy managers blocker와 확인 필요 5초 또는 event
network IotAgent callback, Wi-Fi AWS cache·최근 성공·오류 30초
perception Vision semantic adapter 사람·저조도·camera health 5초
security WssManager, WssTransaction stage·area·pause reason 5초
streaming StreamingManager lifecycle·owner 5초
application setAppStatus, app bridge app/VitalSign session 5초
maintenance filter/update/error managers 건강 요약 1시간
resource TaskResourceMonitor, lease registry 목표 pressure·owner 10초
task_manager TaskManager, completion store workflow/step/queue/reason 2초
capabilities executor/capability registry adapter enabled/blocked/reason 5분 또는 revision

TTL은 목표 기본값이다. 현재 MR6가 domain별 TTL을 모두 구현했다는 뜻이 아니다. sensor 주기, callback 특성, 제품 정책에 따라 설정으로 조정한다.

특히 TaskResourceMonitor.updateSnapshot은 현재 production producer 연결이 확인되지 않고 test에서만 호출된다. 따라서 실제 producer를 연결하기 전 resource.available=false로 내보내야 하며, unavailable을 정상 자원 상태로 간주해서는 안 된다. map.editable도 v1에서는 “편집 가능”이 아니라 실질적으로 “편집 중” 값이므로 v2에서는 policy.map_edit.active로 바로잡는다.

6. Planner 축약 규칙

  1. catalog/shadow가 route/flow 후보를 만든다.
  2. 후보 flow를 Capability Card ID로 변환한다.
  3. Card의 context_reads 합집합만 선택한다.
  4. 각 값의 freshness와 policy exposure를 검사한다.
  5. stale 값은 현재값처럼 쓰지 않고 refresh, ask, block 중 하나를 선택한다.
  6. Planner에는 room 이름, 의미 상태, 허용 조건 path를 전달한다.
  7. 좌표, raw frame, bbox, signed URL, PIN·얼굴 정보, unrestricted log는 제외한다.
  8. 최종 실행 직전 DeviceAgent가 fresh context로 admission을 다시 검사한다.

현재 Cloud의 _compact_device_context_for_planner는 v1의 위치·공기질·배터리· TaskManager 일부를 고정 추출한다. v2 목표는 이 목록을 발화 keyword로 늘리는 것이 아니라 Capability Card context_reads 기반 projector로 교체하는 것이다.

7. TTS와 debug plane 분리

Planner context와 사용자 응답은 같은 데이터 구조가 아니다.

Debug/Planner에는 가능 TTS에서는 금지
condition path air_quality.aq_level 같은 raw key
room runtime ID 위치 ID 숫자
freshness/provenance “context 기준으로”
reason payload capabilities.room_cleaning=true
raw measurement evidence 값 전체 나열

TTS presenter는 semantic state를 자연어로 바꾼다.

8. 기능 조합 방법

새 시나리오는 아래 순서로 조립한다.

Goal
  -> Context-only capability로 현재 상태 확인
  -> Direct capability 후보 선택
  -> Resource graph와 policy gate 계산
  -> Dependency/condition/time graph 생성
  -> 각 step의 completion target 지정
  -> local retry와 Cloud replan 경계 지정
  -> compensation과 사용자 개입 정의

예시 A: 상태 적응형 청정

air_quality_assessment
  -> [bad && battery work budget sufficient]
  -> move_to_room
  -> start_room_cleaning
  -> [improvement trend or timeout]
  -> return_to_station
  -> voice_content summary

예시 B: 도착 후 VitalSign

move_to_room
  -> movement.arrived
  -> after_step_delay
  -> vital_sign_session
  -> user checkpoint
  -> return_to_station

VitalSign result가 typed terminal이 아니므로 현재는 자동으로 다음 step을 성공 처리하지 않는다.

예시 C: 보안 순찰 중 음성 개입

security_patrol
  -> voice session observed
  -> local pause
  -> voice_content
  -> fresh security/battery/network context
  -> local resume or bounded Cloud replan
  -> security terminal
  -> return_to_station

예시 D: 예방 정비 Agent

device_health_assessment
  -> filter trend + cleaning effectiveness + recent failures
  -> no side effect: explain
  -> user confirms maintenance action
  -> schedule_workflow or supported maintenance capability

9. 재계획 경계

Cloud LLM은 모든 progress event에 호출하지 않는다.

Event/상태 기본 처리
정상 progress, step completed TaskManager가 다음 step 수행
짧은 장애물, 일시 network 흔들림 bounded local retry
stale context local refresh
정책 차단, 자원 충돌 DeviceAgent가 block reason 반환
목표 변경, 대체 capability 필요 Cloud replan
사용자 확인 필요 workflow checkpoint
반복 실패, budget 초과 중단·보상·사용자 통지

일반 task timeout은 FAILED + reason_code, 예약 admission의 busy/missed-run은 BLOCKED + reason_code로 구분한다. completion target은 task event 이름이 아니라 executor가 기다리는 물리 상태다.

10. 구현 순서

  1. MR6에 v1과 병행하는 v2 semantic aggregator를 추가한다.
  2. domain별 producer adapter와 freshness/provenance를 붙인다.
  3. on-device bridge에 v2 snapshot과 ordered task-event relay를 연결한다.
  4. Cloud projector를 Capability Card context_reads 기반으로 교체한다.
  5. DeviceAgent admission에서 fresh context와 resource lease를 재검사한다.
  6. TTS presenter와 debug UI를 분리한다.
  7. v1 consumer를 유지한 채 dual-read 후 v2로 전환한다.

device_context.v1 key를 즉시 제거하지 않는다. v2 전환 기간에는 v1 snapshot -> v2 adapterv2 -> legacy compact view를 함께 둔다.

11. 검증 기준

12. 구현 근거 경로

Domain MR6 source
v1 context apps/DeviceAgent/app/src/main/java/com/sk/airbot/deviceagent/task/DevicePlanningContextProvider.java
Task context API .../task/TaskManager.javawriteDevicePlanningContext, refreshPlanningContextIfRequired
이동 완료 .../task/MovementTaskExecutor.java, TaskCompletionStateStore.java
청정 완료 .../task/CleaningAmpTaskExecutor.java, CleaningTransaction
Vision .../recognition/VisionAIManager.java, WSS WssVisionObserver
WSS .../wss/WssManager.java, .../wss/data/WssTransaction.java
Streaming .../streaming/StreamingManager.java, StreamingControlStub.java
LLM/음성 .../llm/LlmManager.java, LlmTtsTaskExecutor.java
정책 .../settings/Settings.java, WssPolicyChecker.java, StateManager.java
Wi-Fi/AWS DeviceAgent Utils, IotAgent AWSIoTMQTTClient, IotTaskManagerBridge
VitalSign MainApi.setAppStatus, AppSessionCompletionBridge.java, SKLauncher2 app status
정비 UsageTimeManager.java, FilterBodyManager.java, UpdateManager.java, error managers
리소스 TaskResourceMonitor.java, TaskResourcePolicy.java

Cloud 소비 근거:

현재 on-device feature_a2a_task_orchestration_bridge@b857a620에는 VoiceContext, getDevicePlanningContext, orchestration workflow/task 제출, /task_event relay 경로가 있다. 다만 ordered dispatcher·deferred schedule helper 일부는 untracked WIP이고 runtime 연결이 끝나지 않았다. v2 문서와 sample은 현재 배포 완료를 뜻하지 않으며, additive parser, size/token budget, durable event relay 반영이 별도 필요하다.

13. 계약 자산

Keyboard shortcuts

⌘K / Ctrl+KOpen command palette
/Focus search
g hGo to home
g pGo to projects
g sGo to sessions
j / kNext / prev row (tables)
?Show this help
EscClose dialogs

Structured queries

Mix key:value filters with free text in the palette:

type:sessionOnly session pages
project:llm-wikiFilter by project name (substring)
model:claudeFilter by model name (substring)
date:>2026-03-01Sessions after a date
date:<2026-04-01Sessions before a date
tags:rustPages mentioning a tag/topic
sort:dateSort results by date (newest first)

Example: type:session project:llm-wiki date:>2026-04 sort:date