콘텐츠로 이동

v0.2.3

릴리스최신

Breaking 없음 — SDK 버전만 >=0.2.3 으로 교체하면 됩니다. 공개 API, A2A 포맷, 외부 전송 형식의 기본값은 v0.2.2 와 byte-identical 입니다.

  • 묻히던 실패 가시화 — A2A 에이전트 호출 실패가 더 이상 조용히 묻히지 않습니다.
  • Composer 노드 boilerplate 5줄 → 1줄 — 입력 데이터·파일·메타데이터 전달이 옵트인 한 줄로.
  • Langfuse 트레이스 가시화errorCode / domainCode 등 핵심 필드가 최상위로 자동 노출.
  • Anthropic prompt caching 자동 적용 — 입력 토큰 50~90% 절감, 사용자 코드 변경 0.
  • CLI 확장llamon graph sync/diff/validate/inspect + llamon doctor 신규 검사.
  • 진단 메시지 형식 통일 (opt-in) — validation·parse·lint·doctor 진단이 모두 같은 JSON 모양으로.
  • in_memory OOM 가드 (opt-in) — thread LRU 자동 정리 + 저장본 트리밍 env. 기본 동작 불변.
  • 로깅 DXsetup_logging() 한 줄로 app.* 로그까지 LOG_LEVEL 적용(stderr). uvicorn 레벨은 UVICORN_LOG_LEVEL로 분리.

A2A 호출 안정성 — 묻히던 실패 가시화

섹션 제목: “A2A 호출 안정성 — 묻히던 실패 가시화”

A2A 워크플로에서 의존하는 에이전트가 일시적으로 응답하지 않으면, 이전에는 INFO 로그만 남기고 SDK 가 조용히 fallback 을 시도했습니다 — 운영 중 추적이 어려운 silent-fail.

이번 릴리스부터:

  • 같은 상황이 WARNING 로그 + a2a.pending_agent_fallback 트레이스 이벤트로 명시 기록됩니다.
  • call_agent_auto(raise_on_pending=True) 옵션 신규 — fallback 대신 UPSTREAM_UNAVAILABLE 예외를 즉시 발생시킵니다 (호출자가 선택).

의도된 noise 입니다. 운영 로그가 살짝 시끄러워지지만, 그것이 문제를 일찍 보게 하는 신호입니다.

여러 A2A 에이전트를 차례로 호출하는 composer 노드에서, 들어온 데이터·파일·메타데이터를 다음 호출로 전달하는 코드를 5줄씩 반복 작성해야 했습니다. 이제 옵트인 한 줄:

result = await call_agent_auto(
agent_id,
forward_inbound_data=True,
forward_inbound_files=True,
forward_inbound_metadata=True,
)

a2a.outbound 트레이스 이벤트로 데이터를 안 보내고 있는 호출 (예: data_count=0) 을 즉시 식별할 수 있습니다.

Langfuse 트레이스 — 에러 필드 자동 노출

섹션 제목: “Langfuse 트레이스 — 에러 필드 자동 노출”

LlamonApplicationErrorerrorCode · errorReason · domainCode 같은 핵심 필드가 트레이스 이벤트의 최상위 필드로 자동 노출됩니다. Langfuse 대시보드에서 grouping / filtering 이 곧바로 가능합니다.

추가로 신규 make_domain_error_raiser 팩토리 — 프로젝트별 에러 카탈로그 (예: "DOC_005" → ErrorCode.NOT_FOUND) 로부터 raise 헬퍼를 자동 생성합니다. 카탈로그 invariant 는 factory 호출 시점에 fail-fast. 패턴 가이드는 도메인 에러 매핑.

CLI — 그래프 동기화 + doctor 확장

섹션 제목: “CLI — 그래프 동기화 + doctor 확장”
명령용도
llamon graph syncgraph.py 정적 파싱 → .llamon/graph.json 동기화 (Studio UI 정합성).
llamon graph diff노드 / 엣지 추가·제거 + metadata 내용 변경 모두 감지.
llamon graph validateCI 통합용 — 부정합 시 비-0 exit.
llamon graph inspect [--output json]그래프 fact + validation 진단을 단일 JSON contract 로 노출.
llamon doctor 신규 검사graph_sync, registry:host_configured (.env.example 선언 / .env 누락), lint:composer_calls (AST 정적 검출).
  • require_state_str / require_state_list — state 값 추출 시 타입 보장. snake_case 자동 reason + field / expectedType / receivedType 보조 필드 자동 노출. pyright / mypy strict 호환.
  • select_input_data_as — TypedDict 또는 임의 payload 타입 명시 narrowing (cast 만, runtime 검증 X). 자세한 사용법은 입력 선별.

테스트 인프라 (llamon_agent.testing)

섹션 제목: “테스트 인프라 (llamon_agent.testing)”

Composer 노드 테스트용 mock 모듈 신규:

  • mock_a2a_server — async context manager.
  • make_a2a_response — factory.
  • facade 원복 격리 자동 보장.

3 개 composer 템플릿 (graph_sequential / graph_conditional / graph_http_pipeline) 의 nodes.py 상단에 passthrough 옵션 + AppState(AgentState) 사용 안내 추가.

폐쇄망 배포 — Nexus relock self-healing

섹션 제목: “폐쇄망 배포 — Nexus relock self-healing”

prepare-offline 의 patched Dockerfile (mode 1, PYPI_INDEX_URL) 의 Nexus install 경로에 self-healing 블록이 자동 부착됩니다. Nexus 에서 uv pip install 이 실패하면 자동으로 uv lock 을 Nexus 기준으로 재실행 후 export/install 재시도. # LLAMON: nexus-relock-fallback v1 marker 로 idempotent (재실행 / restore-online 안전).

추가로 prepare-offline 이 프로젝트의 deploy/ 디렉터리에 relock-for-nexus.sh 스크립트를 자동 생성하고, 배포 아카이브(dist/<agent>-*.tar.gz)에도 함께 담습니다. 폐쇄망에서 docker build 직전 수동 실행하면 lock 이 Nexus 기준으로 정규화 → fallback 미발동 + deterministic 빌드.

단계별 사용법은 같은 명령이 프로젝트에 생성하는 deploy/offline-build-checklist.md“3-1. Nexus 기준 uv.lock 재정렬” 절에 정리돼 있습니다. 이 체크리스트와 스크립트가 만들어지는 전체 흐름은 폐쇄망 준비 (llamon prepare-offline) 를 참고하세요.

메모리 — in_memory 장기 운영 OOM 가드 (opt-in)

섹션 제목: “메모리 — in_memory 장기 운영 OOM 가드 (opt-in)”

in_memory backend 를 장기 운영하면 ① 사용자/세션마다 늘어나는 thread 와 ② 한 thread 의 누적 messages 가 프로세스 RAM 에 무한 적재돼 OOM 으로 이어질 수 있습니다. 두 안전장치가 추가됐습니다 — 둘 다 기본 동작은 그대로이고, env / MemoryConfig 로만 조정합니다.

  • MEMORY_INMEMORY_MAX_THREADS (기본 10000) — in_memory 가 이 수를 넘으면 가장 오래 쓰이지 않은 thread 의 체크포인트를 LRU 로 자동 정리. 새 요청은 거부되지 않고, 방치된 thread 만 비웁니다. 0 이면 무제한(이전 동작). thread 1개당 메모리 × 이 값이 컨테이너 RAM 보다 작도록 잡으세요. (postgres / sqlite 는 디스크 저장이라 no-op.)
  • MEMORY_PERSIST_TRIM_KEEP_GROUPS (기본 0 = OFF) — >0 이면 저장본에서 오래된 turn 그룹을 RemoveMessage 로 정리해 최근 N개 turn 만 유지(가장 최근 human turn 은 추가 보존 → 실제 최대 N+1). SystemMessage·tool-call pair 는 항상 보존돼 멀티턴은 정상. 영구 기록을 외부(Langfuse 등)에 둔다면 켜는 것을 권장. 삭제는 비가역입니다.

기본값(MAX_THREADS=10000, KEEP_GROUPS=0) 에서는 트리밍 미들웨어가 설치되지 않고 LRU 도 일반 사용량에선 발동하지 않아 v0.2.2 와 동일하게 동작합니다.

로깅 DX — setup_logging + UVICORN_LOG_LEVEL

섹션 제목: “로깅 DX — setup_logging + UVICORN_LOG_LEVEL”

스캐폴드 main.pysetup_logging(settings) 한 줄을 호출합니다. 이제 .envLOG_LEVEL이 SDK(llamon_agent.*)뿐 아니라 사용자 코드(app.*) 로그까지 제어합니다(출력 stderr). 노드에서는 표준 logging.getLogger(__name__)만 쓰면 됩니다 — logging.basicConfig 보일러플레이트가 사라집니다.

uvicorn 서버 로그는 신규 UVICORN_LOG_LEVEL(기본 info)로 LOG_LEVEL독립적으로 제어합니다. 기존 프로젝트는 wheel만 교체해도 그대로 동작하고(드롭인), 새 동작은 main.pysetup_logging을 넣을 때만 적용되는 opt-in입니다. 설정법은 문제 해결 → SDK 로그 레벨.


내부 인프라 변경 (사용자 코드 영향 없음)

섹션 제목: “내부 인프라 변경 (사용자 코드 영향 없음)”
  • Anthropic prompt caching 자동 적용langchain-anthropic 모델의 SystemMessage 첫 블록에 cache_control: ephemeral 자동 부착. agent loop 입력 토큰 50~90% 절감, 사용자 코드 무변경. OpenAI pass-through, Ollama no-op.
  • 공유 httpx connection pool (core/http/) — 8 곳의 자체 httpx.AsyncClient 생성을 폐기, get_default_client() / get_streaming_client() (단발 / SSE) 로 통일. Limits(max=500, keepalive=100) 기본값.
  • executor 모듈 분리inbound/a2a/executor.py (1936 줄) → 4 모듈 split (_output_synthesis.py · _part_builders.py · _streaming_state.py, ~572 줄 감소). 기존 import 경로 re-export 로 호환.
  • Langfuse Observation level / statusMessageInvokeTraceContext.set_output() 에 추가. executor 가 swallow 한 application error 도 trace UI 에서 색상 / 필터로 구분.
  • Langfuse cache 토큰 metricusage_detailscache_read_input_tokens / cache_creation_input_tokens 추가 (Anthropic · OpenAI · LangChain unified 세 포맷 추출).
  • GuardrailJudgeLLMConfig + skip_llm 통합 — 가드레일 prompt 판정 LLM 을 GuardrailConfig(judge_llm=...) 로 명시 지정. Registry model_id / ExtensionConfig.llm 보다 우선. skip_llm=True 상태에서도 ref tracking / hot-reload / agent-card 노출 / build-time fetch 우회 일관 적용.
  • core/errors/mapping.py 회귀 잠금httpx.TimeoutException 4 subclass · 5xx · 401/403 · reason 문자열 명시 잠금으로 errorCode / errorReason 카테고리 안정성 확보.
  • LangChain 메이저 상한langchain<2, langgraph<2, langchain-mcp-adapters<0.3. 컨슈머가 호환되지 않는 상위 메이저를 의도치 않게 resolve 하는 사고를 사전에 차단 (기존 lock 된 버전들은 모두 새 범위 안이라 dev/CI 영향 없음).

Validation · parse · lint · doctor 검사가 emit 하는 진단 메시지를 모두 같은 JSON 모양으로 통일했습니다 — 안정 code + 중첩 location + expected / actual + repair_id + fix_safety.

기존 호출자 영향 없음 — 신규 모양은 opt-in 으로만 노출되고, 기본 응답 형태는 v0.2.2 와 byte-identical 입니다.

활성화 방법:

  • Studio HTTPX-LLaMON-Diagnostics: structured 요청 헤더 첨부 → detail 필드가 { error, message, diagnostics: [unified...] } dict 로 응답.
  • CLIllamon graph inspect --diagnostic-format=v2diagnostics 항목이 통합 모양 (중첩 location / repair) 으로 직렬화.
진단 카테고리 7종 — 코드 prefix 매핑 (펼치기)
FamilyCode prefix적용 위치
Flow graph validationFLW001FLW037validate_flow_graph_diagnostics()
Project parsePRJ010PRJ012parse_local_config_with_diagnostics / parse_local_skills_with_diagnostics / parse_node_ext_configs_with_diagnostics (종전 silent except SyntaxError 6 곳 제거)
Edge rulesEDG001EDG002can_connect_diagnostic() (기존 can_connect 는 TS mirror 호환 위해 보존)
Unused local resourcesRES001RES002detect_unused_local_resources_diagnostics()
Save conflictSAV001SAV002FileFingerprint.check_conflict_diagnostics()expected_sha / actual_sha 노출. Studio /api/save 409 응답
DoctorDOC020DOC120doctor_add_check() + doctor_diagnostics()

JSON Schema 는 /diagnostic-schema.json 으로 게시됩니다 (canonical $id: https://llamon.ai/schemas/diagnostic/v1.json) — 외부 컨슈머가 그대로 내려받아 검증에 사용할 수 있습니다. CI gate 가 게시본과 SDK source 정의의 정합성을 매 commit 마다 자동 검증합니다.

다음 릴리스 예고: 위 통일 형식은 별도 Rust 패키지 (llamon-core) 가 같은 모양을 emit 하도록 만들기 위한 사전 정비입니다. 사용자는 Rust 의 존재를 인지하지 못한 채 pip install llamon-agent 한 번으로 가속을 자동으로 받게 됩니다. 상세 로드맵(Rust core 도입 계획)은 현재 내부 설계 문서로 관리 중이며, 공개 가능한 단계가 되면 후속 릴리스 노트에서 안내합니다.


pytest-xdist --dist=loadfile 도입으로 파일별 워커 격리 — macOS Mach semaphore lock 으로 인한 hang 차단. 부수 효과로 module / loop / registry singleton 오염도 동시 해결.

결과: just test1747 pass / 1 skipped / 0 fail / ~47 초 (이전: 단일 프로세스 hang 으로 2 분).

이 섹션은 SDK 자체 CI 에 대한 내부 변경이라 사용자 코드에는 영향이 없습니다. (hang 회피 안티패턴 / 권장 패턴은 SDK 컨트리뷰터용 tests/TESTING.md 에 기록돼 있습니다.)


시나리오작업
기존 호출자수정 불필요 — 진단·A2A 변경은 public API 무변경, 신규 옵션은 모두 keyword-only + 기본값 off.
agent.yaml 선언형 설정 (제거)선언형 agent.yaml 경로를 제거했습니다. 설정은 app/config.pybuild_extension() 단일 경로만 지원. 제거 대상: python -m llamon_agent.server --yaml 진입점, load_extension · build_agent_card export, agent.yaml 로더(LDR001-005). 코드 기반 설정(config.py)을 쓰는 프로젝트는 영향 없음. 빌드타임 캐시는 resolve (인자 생략 시 app.config:build_extension) 로 그대로 동작.
SDK 버전 핀pyproject.tomlllamon-agent>=0.2.2>=0.2.3.
Langfuse 대시보드신규 errorCode / errorReason / domainCode root field 로 grouping / filtering 가능.
운영 로그A2A pending fallback 이 INFOWARNING 으로 가시화 (의도된 noise).
CI 통합 (옵트인)llamon graph validate . 추가로 graph.pygraph.json 정합성 강제. just schema-check 로 diagnostic schema drift 차단.
통합 Diagnostic 형식 (옵트인)Studio: X-LLaMON-Diagnostics: structured 헤더 / CLI: --diagnostic-format=v2.

다음 단계 로드맵(Rust core 도입 계획)은 내부 설계 문서로 관리 중입니다. 테스트 인프라(tests/TESTING.md, test-debug recipe)는 SDK 컨트리뷰터용 자료로, SDK 컨슈머에게는 영향이 없습니다.