콘텐츠로 이동

Studio Playground

Studio Playground는 별도 앱이나 실행 서비스가 아닙니다. 기존 프로젝트에서 다음 명령을 실행한 뒤 헤더의 설계 | Playground를 전환합니다.

Terminal window
uv run llamon studio .

Playground는 Agent·Flow·Orchestrator를 모두 프로젝트의 실제 A2A endpoint로 호출합니다. Python의 Agent 객체, graph 또는 run_turn()을 UI 프로세스가 직접 invoke하지 않습니다.

Playground의 Host 실행은 현재 사용자의 권한으로 프로젝트 코드를 실행합니다. 신뢰하지 않는 프로젝트를 열어 실행하지 마세요. Docker·Kubernetes 격리 실행과 관리자 웹은 이 기능의 범위가 아닙니다.

첫 진입 안내처럼 실제 입출력과 trace는 프로젝트 안의 다음 로컬 경로에 저장됩니다.

.llamon/playground/playground.sqlite3
.llamon/playground/files/<sha256>
  • Playground API를 열지 않으면 이 디렉터리와 background run을 만들지 않습니다.
  • .env, 내부 capture token, Playground 상관 metadata는 history와 bundle에 저장하지 않습니다.
  • 사용자 metadata는 알려진 secret key를 redaction한 뒤 저장합니다. 그래도 자유 형식 text·data·file에는 개인정보가 있을 수 있으므로 export 전에 확인하세요.
  • 왼쪽 아래의 전체 이력 삭제는 모든 session·run·trace를 삭제하고, 다른 record가 참조하지 않는 file blob도 정리합니다.

설계 모드에 미저장 변경이 있으면 Playground의 실행 버튼이 저장 후 실행으로 동작합니다.

  1. 현재 설계와 프로젝트를 검증합니다.
  2. 기존 checksum 충돌 방지를 거쳐 저장합니다.
  3. 실제로 바뀐 파일만 계산합니다.
  4. Host가 실행 중이면 그 revision을 위해 한 번 명시적으로 재시작합니다.
  5. 새 runtime generation이 Ready가 될 때까지 기다립니다.
  6. 요청과 분리된 background run을 만들고 A2A로 전송합니다.

inspector의 검증 → 저장 → 재시작/시작 → Ready → 전송 → 완료 stepper에서 진행 상태를 확인할 수 있습니다. 응답은 도착한 output.delta 순서대로 진행 중인 run 카드에 이어 붙고, run이 끝나면 저장된 최종 part로 대체되므로 같은 텍스트가 두 번 남지 않습니다. token 단위 변화는 화면에만 반영하고 screen reader에는 phase 전환만 알립니다. 외부 편집기가 파일을 바꾸면 기존 Studio watcher의 auto-reload가 계속 동작합니다. 감시 대상은 *.py, .env([tool.llamon].env_file로 지정한 파일명 포함), pyproject.toml, orchestrator.toml, 그리고 okf/·okf-contracts/ 아래의 *.md입니다 — capability catalog와 routing rule은 import 시점에 확정되므로 재시작이 필요합니다. 그때 활성 run은 failedreason="runtime_restarted"로 끝나며 자동 재시도하지 않습니다.

프로젝트 전체에서 동시에 활성화할 수 있는 run은 하나입니다. 충돌하면 서버는 409와 현재 active_run_id를 반환하고 UI가 그 run으로 이동합니다. SSE 탭을 닫아도 실행은 취소되지 않습니다. inspector의 취소를 눌러야 HTTP stream과 가능한 A2A task 취소를 요청하며, Host 프로세스 자체는 계속 실행됩니다.

Studio가 종료되면 background task를 정리합니다. 다음 시작에서 남아 있던 queued·preparing·running record는 interrupted로 복구됩니다.

run이 failedinterrupted로 끝나면 inspector의 run 탭이 reason, 서버가 남긴 error 메시지, 그리고 runtime_unavailable처럼 해결 명령이 있는 경우 그 명령을 복사 버튼과 함께 보여줍니다.

host logs 보기를 누르면 Playground 모드를 떠나지 않고 아래 로그 패널이 열립니다. 로그 패널은 설계·Playground 두 모드가 같은 상태를 공유하며, Playground로 들어와 시작할 때만 접힌 상태입니다.

같은 session의 일반 turn은 같은 A2A contextId를 사용하지만 각 turn은 별도 run입니다.

  • 응답이 input_required이면 서버가 배정한 taskId를 저장합니다. 재개는 같은 contextIdtaskId를 쓰는 child run입니다.
  • 새 context 재실행은 원래 입력 part를 복제하되 새 contextId를 발급합니다.
  • Compare 탭은 status, duration, text unified diff, JSON 구조 변경, file metadata/hash, evaluator score delta를 보여줍니다. 원본 응답 JSON을 그대로 붙이지 않고 diff와 변경 목록, score 표로 나눠 표시하며 자동 pass/fail 판정은 하지 않습니다.
  • run 탭에는 그 run의 evaluator score와 passStatus, 평가 근거, 그리고 runtime이 보고한 경우 evaluator별 소요 시간이 함께 남습니다. passStatus는 evaluator가 기록한 값을 그대로 보여주는 표시이며 Playground가 판정을 만들지는 않습니다.
  • 대화의 각 run 카드에는 evaluator 3 · fail 1 형태의 요약 배지가 붙습니다. fail 개수는 evaluator가 스스로 기록한 passStatus를 세었을 뿐입니다.
  • Copy Python과 Copy curl은 현재 run의 TextPart·DataPart·FilePart, redaction된 business metadata, contextId, 필요한 taskId를 포함합니다. 내부 capture 정보는 포함하지 않습니다.

Flow는 저장된 graph.json을 추측하지 않고 현재 source mtime의 graph를 다시 parse합니다. START에 바로 연결된 node의 input_contracts를 탭으로 만들며 필드 skeleton은 다음과 같습니다.

계약 타입초기값
string""
number·integer0
booleanfalse
object{}
array[]

서로 다른 시작 node에 같은 contract 이름이 있어도 별도 탭으로 유지됩니다. required 표시는 누락 가능성을 알려줄 뿐 기존 runtime validation 규칙을 바꾸지 않습니다.

계약 name은 탭을 구분하는 표시이므로 따로 입력하지 않습니다. 편집기에 보이는 JSON object 전체가 A2A DataPart의 data가 되며, 선언된 DataContract.schemadata.schema에 자동으로 포함됩니다.

Agent와 Orchestrator의 AgentCard capability가 input_schemas 이름만 선언하면 {"schema":"<name>"}까지만 제안하고 필드 형태가 미선언임을 표시합니다. schema가 없으면 AgentCard input mode와 skill example을 이용하는 text composer로 돌아갑니다.

Playground capture는 Host가 child process에만 주입하는 일회성 token으로 격리됩니다. 검증된 Playground 요청에서만 NodeTracer event와 evaluator 결과를 현재 run에 연결합니다. 내부 envelope는 AgentState.metadata, node, guardrail, memory와 child forwarding 전에 제거됩니다.

Trace 탭에서 node event를 누르면 설계 모드로 전환하고 live graph의 node를 중앙에 선택한 뒤 해당 app/nodes.py 함수의 CodeEditor를 엽니다. 연결은 trace 문자열이나 graph.json이 아니라 live graph의 function_name과 Python AST 위치를 사용합니다.

evaluator score에 node가 기록되어 있으면 run 탭의 그 항목에서 평가 설정으로 이동할 수 있습니다. 설계 모드로 전환해 해당 node를 선택하고, node 패널의 Runtime 평가 섹션으로 스크롤해 포커스를 옮깁니다.

평가 대상 선언은 계속 설계 탭이 소유합니다. Playground는 어떤 evaluator가 어떤 점수를 남겼는지만 보여주고, 실행마다 evaluator를 바꿔 끼우는 경로는 제공하지 않습니다. 선언을 바꾸면 저장과 runtime 재시작을 거치므로 같은 조건의 A/B가 아니기 때문입니다.

history·trace 기록 오류는 history_degraded 진단으로 남지만 Agent 출력이나 A2A status를 바꾸지 않습니다.

프로젝트가 PostgreSQL memory/state backend를 선언하면 처음부터 경고를 표시합니다. Playground는 SQLite나 in-memory backend로 자동 대체하거나 DB를 초기화하지 않습니다. Host가 외부 PostgreSQL에 연결하지 못하면 run은 runtime_unavailable로 끝나고 Host 로그와 다음 명령을 함께 안내합니다.

Terminal window
uv run llamon run .

Playground 저장소는 Python 표준 sqlite3만 사용해 별도 runtime dependency나 인터넷 연결을 추가하지 않습니다. 폐쇄망에서도 Studio와 프로젝트 wheel이 준비되어 있으면 history·비교·bundle 기능은 동작합니다. 다만 프로젝트가 Registry, model, MCP, PostgreSQL 같은 외부 서비스를 요구하면 그 서비스는 별도로 접근 가능해야 합니다.

내보내기 형식은 llamon.playground.bundle/1 JSON입니다. 선택한 session·run·event와 content hash별 base64 blob을 중복 없이 담습니다. 가져올 때 모든 관계, SHA-256과 byte size를 먼저 검증하고 session·run ID를 새로 발급합니다.

외부 URI FilePart는 자동 다운로드하지 않으며 external·unavailable_for_replay로 표시됩니다. bundle에는 사용자 입력이 포함되므로 공유 전 privacy warning과 실제 내용을 확인하세요.

HTTP 계약이 필요한 도구 제작자는 Playground API를 참고하세요.