← Docs hub

TaskManager Live Monitor

Cloudflare Pages의 TaskManager 화면은 임의 명령 작성 도구가 아니라 실기기 TaskManager 플로우 검증 콘솔이다.

Dashboard:

Worker endpoint:

https://frosty-bird-d72c.silogood.workers.dev
wss://frosty-bird-d72c.silogood.workers.dev/ws?role=ui&deviceId=A1-board-001
wss://frosty-bird-d72c.silogood.workers.dev/ws?role=device&deviceId=A1-board-001

명령 등록:

POST https://frosty-bird-d72c.silogood.workers.dev/api/commands?deviceId=A1-board-001

DeviceAgent polling:

GET https://frosty-bird-d72c.silogood.workers.dev/api/device/commands?deviceId=A1-board-001

Telemetry:

POST https://frosty-bird-d72c.silogood.workers.dev/api/events

UI 범위

Dashboard의 사용 흐름은 세 단계로 고정한다.

  1. 테스트 프로그램 선택
  2. 테스트 실행
  3. 결과 관측

사용자는 method, queue, payload를 직접 조립하지 않는다. 화면은 미리 정의한 테스트 프로그램만 Worker 명령 큐에 등록한다. DeviceAgent는 polling으로 명령을 가져가고, TaskMonitorCommandBridge가 TaskManager submitTask 또는 workflow submit 경로로 넘긴다.

복합 workflow의 화면 흐름은 UI 하드코딩 목록이 아니라 command payload의 subTasks에서 만든다. Worker는 command_request audit에 payload를 보존하고, DeviceAgent ack가 payload를 생략해도 기존 subTasks를 유지한다. Dashboard는 이 subTasks 정의와 TaskManager의 WORKFLOW_STEP_STARTED/WORKFLOW_STEP_COMPLETED 이벤트를 currentStepIndex로 매칭해서 단계별 처리 상태를 보여준다.

현재 테스트 프로그램:

표시명 목적 대표 경로
안방 청정 → 거실 청정 → 복귀 순차 workflow가 단계별로 관리되는지 확인 submitWorkflow → TaskManager workflow
진행 중 인터럽트 workflow 실행 중 취소/복귀 제어 명령이 중간에 인입되는지 확인 submitWorkflowcancelQueuereturnToStation
정상 흐름 단일 명령이 등록, 실행, 완료되는지 확인 setEyeLedColor → routine queue
동시 인입 여러 명령을 연속 등록했을 때 큐와 상태가 깨지지 않는지 확인 routine/movement queue
큐 압박 같은 queue에 명령을 몰아 넣었을 때 상태 관리가 되는지 확인 movement queue
인터랙션 스케줄 등록 예약 데이터가 schedule queue를 통해 DeviceAgent 스케줄 저장 경로로 들어가는지 확인 scheduleiot(command=add) → schedule queue
인터랙션 스케줄 실행 등록된 인터랙션 스케줄 수행이 TaskManager interaction queue와 완료 이벤트를 타는지 확인 interSchedule(action=1)InterScheduleManager

용어 설명

Dashboard와 테스트 문서에서는 영문 테스트 용어 대신 아래 한글 표현을 기본으로 쓴다. 내부 API 값은 호환성을 위해 happy, burst, pressure, failure 같은 원본 키를 유지한다.

표시명 내부 값 의미
정상 흐름 happy 명령 1개가 TaskManager에 등록되고 실행, 완료까지 가는 기본 성공 케이스다.
동시 인입 burst 여러 출처나 성격의 명령이 짧은 시간에 들어와도 큐와 상태 관리가 깨지지 않는지 보는 케이스다.
큐 압박 pressure 같은 큐에 여러 태스크를 몰아 넣어 대기/실행 상태와 이상 감지 기준을 확인하는 케이스다.
실패 흐름 failure 차단되거나 실패한 명령이 요약, 타임라인, 명령 요청 기록에 남는지 확인하는 케이스다.
진행 중 인터럽트 interrupt_return_to_station 실행 중인 workflow에 cancelQueuereturnToStation을 중간 명령으로 넣어 TaskManager 제어 흐름과 모니터 표시를 확인하는 케이스다.
실기기 검증 deviceFlow Worker 명령 큐, DeviceAgent polling, TaskManager submit, telemetry 보고가 실제 보드에서 이어지는지 확인한다.
상시 반복 명령 routine setEyeLedColor처럼 계속 들어오는 LED/PUI 상태 표시성 명령이다. 핵심 이동/청정 테스트와 섞이지 않도록 별도 집계한다.
스케줄 명령 schedule scheduleiot, addSchedule, setActiveSchedule처럼 스케줄 DB/정책을 바꾸는 명령이다.
인터랙션 스케줄 실행 interaction 시스템 예약 수행 시점에 interSchedule(action=1, scheduleId=...)로 등록되는 장시간 실행 task다.
명령 요청 기록 command_request UI/Cloud에서 기기로 보내려는 명령을 감사 로그처럼 남긴 기록이다. DISPATCHED는 Worker가 등록했다는 뜻이고, HANDLED는 DeviceAgent가 받아 TaskManager에 넘겼다는 뜻이다.
워크플로우 단계 WORKFLOW_STEP_* 복합 작업 내부의 각 단계 시작/완료 이벤트다. currentStepMethod, currentStepIndex, workflowName으로 화면에서 구분한다.

이벤트 계약

Task event:

{
  "type": "task_event",
  "deviceId": "A1-board-001",
  "taskId": "bedroom_livingroom_clean_return-12",
  "taskMethod": "submitWorkflow",
  "source": "IOT",
  "state": "RUNNING",
  "queue": "workflow",
  "eventName": "WORKFLOW_STEP_COMPLETED",
  "currentStepMethod": "setAirCleanerOperation",
  "currentStepIndex": 3,
  "workflowName": "bedroom_livingroom_clean_return",
  "traceId": "dispatch-bedroom_livingroom_return-1783699716006"
}

Command request:

{
  "type": "command_request",
  "deviceId": "A1-board-001",
  "requestId": "dispatch-bedroom_livingroom_return-1783699716006",
  "source": "IOT",
  "method": "submitWorkflow",
  "queue": "workflow",
  "status": "HANDLED",
  "taskCount": 5,
  "safety": {
    "requiresToken": false,
    "allowlisted": true
  }
}

Interrupt command request:

{
  "type": "command_request",
  "deviceId": "A1-board-001",
  "requestId": "interrupt-returnToStation-1783784529278",
  "source": "IOT",
  "method": "returnToStation",
  "queue": "movement",
  "status": "HANDLED",
  "taskId": "returnToStation-3",
  "interrupt": {
    "scenarioKind": "interrupt_return_to_station",
    "triggerAfterStep": 1,
    "action": "returnToStation",
    "targetQueue": "movement",
    "reason": "취소 이후 스테이션 복귀를 새 movement task로 등록"
  }
}

Interaction schedule command request:

{
  "type": "command_request",
  "deviceId": "A1-board-001",
  "requestId": "interaction-run-901001-1783784529278",
  "source": "SCHEDULE",
  "method": "interSchedule",
  "queue": "interaction",
  "status": "HANDLED",
  "payload": {
    "action": "1",
    "scheduleId": "901001",
    "completionTarget": "interaction.completed",
    "timeoutMs": 1200000
  }
}

DeviceAgent 설정

Runtime properties:

persist.sys.deviceagent.taskmonitor.enable=true
persist.sys.deviceagent.taskmonitor.endpoint=https://frosty-bird-d72c.silogood.workers.dev/api/events
persist.sys.deviceagent.taskmonitor.device_id=A1-board-001
persist.sys.deviceagent.taskmonitor.command.enable=true
persist.sys.deviceagent.taskmonitor.command_endpoint=https://frosty-bird-d72c.silogood.workers.dev/api/device/commands
persist.sys.deviceagent.taskmonitor.command_interval_ms=1000

DeviceAgent는 TaskMonitorReporter로 heartbeat/task event를 전송한다. TaskMonitorCommandPoller는 Worker pending queue를 polling하고, 반환된 command를 TaskMonitorCommandBridge로 넘긴 뒤 처리 결과를 command_request ack로 보고한다.

웹에서 “실제 전송”한 명령은 Worker가 dryRun=false로 pending queue에 넣고, DeviceAgent bridge가 dryRun=false, executorDryRun=false를 함께 TaskManager submit bundle로 전달한다. 따라서 실제 executor가 연결된 기기에서는 TaskManager가 기존 DeviceAgent manager 함수까지 호출한다. 하드웨어가 빠진 보드에서는 명령 등록과 대기/실패/타임아웃/모니터 표시까지만 검증한다.

음성 Agent 연동 위치

Task Monitor가 내리는 command와 음성 Agent가 내리는 command는 최종적으로 같은 TaskManager ingress를 사용한다. 차이는 입력 주체와 plan 생성 위치다.

입력 주체 생성 위치 DeviceAgent 진입 상태 회수
Task Monitor UI Worker predefined scenario polling command -> submitTask/submitWorkflow Worker telemetry dashboard
Cloud A2A/음성 Agent Cloud planner device_task_requests[] 온디바이스 bridge -> submitTask/submitWorkflow onTaskEvent -> MaumAi -> Cloud task_event

2026-07-23 A1-board-005 실기기에서는 TaskManager dry-run 기준으로 아래 계약이 확인됐다.

submitTask
  taskMethod=setAirCleanerOperation
  forceTaskManager=true
  source=CLOUD
  contract_version=a2a-task-orchestration-v1
  cloud_workflow_id=wf_device_e2e_001
  cloud_step_id=step_clean_living_room
  cloud_plan_id=plan_device_e2e_cleaning
  cloud_output_key=living_room_cleaning
  executorDryRun=true

DeviceAgent는 이 task를 COMPLETED로 종료했고, 같은 trace 값을 Worker telemetry에 유지했다. 따라서 Worker pending queue, DeviceAgent polling, TaskManager workflow 실행, monitor event 보고, trace 보존은 통과다.

최신 확인 run:

deviceId: A1-board-005
requestId: dispatch-a2a-callback-probe-1784741807996
source: CLOUD
method: submitWorkflow
workflowName: cloud_a2a_callback_probe
taskId: cloud_a2a_callback_probe-1
event count: 8
terminal event: COMPLETED

2026-07-23 추가 확인 run:

deviceId: A1-board-005
requestId: dispatch-a2a-step-metadata-probe-1784743420469
source: CLOUD
method: submitWorkflow
workflowName: cloud_a2a_step_metadata_probe
taskId: cloud_a2a_step_metadata_probe-1
cloud_workflow_id: wf_codex_step_metadata_probe
cloud_plan_id: plan_codex_step_metadata_probe
step 0: setEyeLedColor, cloud_step_id=step_led_001, cloud_output_key=led_result
step 1: setLlmTts, cloud_step_id=step_tts_001, cloud_output_key=tts_result
terminal event: COMPLETED

이 run의 의미는 단순히 workflow가 끝났다는 것이 아니다. Cloud가 만든 plan step id와 output key가 DeviceAgent TaskManager 내부 step 실행 중에도 보존되고, TaskMonitorReporter가 같은 값을 Worker telemetry로 올렸다는 점이 핵심이다. 따라서 Monitor 화면은 currentStepIndex/currentStepMethod만 보지 말고, Cloud 연계 검증에서는 아래 trace 필드를 함께 확인해야 한다.

필드 확인 이유
cloud_workflow_id / cloudWorkflowId Cloud workflow와 SoC native task를 같은 실행 단위로 묶는다.
cloud_plan_id / cloudPlanId 어떤 Cloud plan에서 내려온 작업인지 추적한다.
cloud_step_id / cloudStepId 재플래닝이나 다음 step resume 시 완료된 step을 식별한다.
cloud_output_key / cloudOutputKey 이전 step 결과를 다음 step 입력으로 연결할 때 사용한다.

현재 Worker telemetry는 이 필드들을 정상 수집한다. 별도 이슈는 MaumAi가 배포 Cloud Lambda로 같은 event를 forward할 때 발생하는 500이며, Monitor 수집 경로와는 분리해서 봐야 한다.

주의할 점은 /api/device/commands가 pending command를 소비하는 polling endpoint라는 점이다. 사람이 상태를 볼 때는 이 endpoint를 직접 호출하지 말고 /api/snapshot?deviceId=A1-board-005를 사용한다.

DeviceAgent callback fan-out도 확인됐다. logcat 기준 MainApi.onModuleCallbackLoopmethod:onTaskEvent, callerclassname:com.skmagic.ondeviceai.agent.service.DeviceCommunicator로 callback을 보냈고, MaumAi는 DeviceCommunicator - Device Device Callback method : onTaskEventSTARTED, WORKFLOW_STEP_STARTED, WORKFLOW_STEP_COMPLETED, COMPLETED event를 수신했다.

현재 남은 실패 지점은 MaumAi가 배포 Cloud task_event endpoint로 forward한 뒤 받는 HTTP 500이다. logcat 기준 응답 body는 {"error": "'NoneType' object is not subscriptable"}다. 로컬 Lambda는 task_event 직접 envelope와 Task Monitor style event를 처리하도록 수정 및 테스트됐으므로, app-api-dev 배포본을 최신 package로 동기화해야 closed loop가 완성된다.

다음 검증은 Cloud 배포 후 같은 request id 패턴으로 workflow를 재등록하고, 아래 문자열을 같은 window에서 확인한다.

adb -s 192.168.123.116:5555 logcat -c
# Worker /api/commands 로 새 workflow 등록
adb -s 192.168.123.116:5555 logcat -d | rg -n \
  "requestId|workflowName|onTaskEvent|DeviceCommunicator|Task event API|failed to forward|NoneType"

명령 게이트웨이 안전 조건

현재 웹 전송 허용 범위:

범주 대표 method
workflow/control submitWorkflow, cancelTask, clearPendingTasks, cancelQueue
이동 setMoveTo, setMoving, stopMovement, returnToStation
청정 getAirCleanerOperation, setAirCleanerOperation, setStatusClean, startSimpleAirClear, startBasicAirClear, startFixedAirClear, startAllAirClear, startSelectiveAirClear, startAirSensorAirClear, stopAirClear, pauseAirClear, resumeAirClear, returnAirClearToStation, returnCleaningToStation, stopCleaning, ampStop
상태/설정 getBatteryInfo, getFirmwareVersion, getMainState, getDeviceStatus, setMainState, setDeviceStatus, setLauncherScreen, setConfig, getConfig, getConfiguration
AI/PUI setChangeLlmStatus, setLlmTts, stopLlm, stopTts, setEyeLedColor, startEyeLedScene
스케줄/인터랙션 addSchedule, editSchedule, deleteSchedule, scheduleiot, setActiveSchedule, puiEditSchedule, callschedule, getschedule, getUpComingSchedule, setScheduleExecuted, gpsLocNearBy, interSchedule
업데이트 OTAUpdateArmResult, OTAUpdateMcuResult, setFirmwareUpdateStatus

setFanLevel, setLlmStatus처럼 legacy 코드에는 흔적이 있지만 현재 TaskManager executor-backed catalog에 없는 명령은 실기기 전송에서 차단한다. 이런 명령을 테스트하려면 먼저 DeviceAgent executor/policy에 실제 완료 기준까지 연결한 뒤 allowlist에 추가한다.

검증 기준

실기기 검증은 아래 증거가 동시에 있어야 통과로 본다.

현재 의사결정

웹 화면에서 직접 task를 생성하거나 payload를 조합하는 기능은 범위에서 제외한다. 이 화면은 정해진 테스트 프로그램을 실기기 TaskManager 경로에 태우고, 큐/상태/단계/완료 여부를 관측하는 용도로 유지한다.

현재 판정은 TaskManager 관리 검증이다. 실제 이동, 청정, 복귀 actuator 함수가 물리적으로 끝까지 수행됐다는 의미로 표시하지 않는다. 향후 모든 실제 함수가 연결된 기기에서는 같은 subtask payload와 telemetry 계약을 유지한 채, executor/actuator 완료 신호를 별도 evidence로 추가한다.

진행 중 인터럽트 시나리오도 현재는 실제 이동 중단을 물리적으로 검증하지 않는다. 현재 검증 범위는 Worker pending queue, DeviceAgent polling, TaskManager control command 처리, command ack, dashboard 표시가 이어지는지다. 실제 actuator 완료/중단 callback이 붙으면 같은 interrupt 메타데이터를 기준으로 DEVICE_CONFIRMED, FAILED_BY_DEVICE, CANCELLED_BY_DEVICE 같은 물리 결과 evidence를 추가한다.

인터랙션 스케줄은 사용자가 웹에서 임의 payload를 만드는 기능이 아니라, “시스템 예약 수행 시점에 자동으로 TaskManager에 등록되는 흐름”을 검증하는 테스트 프로그램으로 둔다. 웹의 등록/실행 버튼은 업체 설명과 단말 검증을 위한 테스트 harness이며, 제품 동작에서는 SKMLauncher/스케줄 엔진이 같은 scheduleId를 DeviceAgent interSchedule로 넘기는 것이 정상 경로다.

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