diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index aed674d..75eca7a 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -12,7 +12,7 @@ "name": "ennoia", "source": "./plugins/ennoia", "description": "Ennoia에서 에이전트 생성, 문서 지식 연결, App 실행, 운영 진단과 제품 피드백을 수행합니다.", - "version": "1.5.4" + "version": "1.5.5" } ] } diff --git a/README.md b/README.md index d379b5e..f0e7a5e 100644 --- a/README.md +++ b/README.md @@ -92,11 +92,14 @@ Skill 이름을 외우지 않아도 자연어로 요청할 수 있습니다. | App으로 업무 처리 | “Ennoia App으로 이 업무를 처리하고, 기존 대화에서 이어가줘.” | | 오류·사용량 확인 | “고객응대봇의 실행 실패 원인과 사용량을 확인해줘.” | | 배포 | “저장된 고객응대봇을 배포하고 배포 상태를 확인해줘.” | +| 배포 API·키 확인 | “전에 배포한 고객응대봇의 API 사용법과 API 키 확인 링크를 알려줘.” | | 외부 MCP 연결 확인 | “Ennoia에서 Slack·Atlassian MCP의 등록 여부와 내 연결 상태를 확인해줘.” | | 제품 피드백 | “Ennoia Plugin에서 프로젝트를 반복 질문하는 점을 개선 의견으로 남겨줘.” | **저장 후 바로 확인:** 에이전트를 생성·수정해 저장하면 **에이전트 열기** 링크로 Studio 편집 화면을 안내합니다. 실제 저장된 대상이 확인되어야 링크를 제공하며, 테스트·배포 상태는 별도로 알려줍니다. +**배포 후 사용하기:** 배포 결과에는 배포 버전 열기·프로젝트 API 키 확인 링크와 확인된 계약의 기본 cURL을 함께 안내합니다. 새 조회 도구를 지원하면 이전 배포의 사용법도 다시 확인할 수 있습니다. 키 원문은 대화에 표시하지 않으며, 키 확인을 위해 재배포하지 않습니다. 이전 서버에서 요청 예제의 계약을 확인할 수 없으면 Studio의 **코드** 버튼으로 안내합니다. 배포 상태와 실제 실행·개인 서비스 연결·승인 대기는 구분합니다. + **저장된 초안 테스트:** 현재 연결이 새 테스트 도구를 지원하면 Studio와 같은 서버 경로에서 저장 원본을 실행합니다. 사용자 credential을 사용하는 MCP·connector가 실제 외부 변경을 수행할 수 있으므로 대상과 부작용 가능성을 안내하고 명시적인 테스트 승인 후 진행합니다. 기존 승인은 재사용하며 실행 중 개별 도구 승인이 요청되면 사용자 결정을 기다립니다. 테스트·승인 대기·취소와 운영 배포는 각각 구분합니다. 이전 연결이 이 기능을 지원하지 않으면 미지원 사실을 안내합니다. 문서는 업로드와 검색 준비가 끝나야 에이전트에서 사용할 수 있습니다. 사용하는 앱에서 파일을 전송할 수 없으면 Ennoia 업로드 화면을 안내합니다. diff --git a/evals/2026-10-27-deployment-usage-summary.md b/evals/2026-10-27-deployment-usage-summary.md new file mode 100644 index 0000000..d9aab16 --- /dev/null +++ b/evals/2026-10-27-deployment-usage-summary.md @@ -0,0 +1,15 @@ +# 배포 사용 안내 합성 평가 기록 + +검증 대상은 배포 직후 안내와 새 대화의 재조회, 키 확인 위치, 버전·프로젝트·환경 유지, 개인 인증·승인 상태 미확인, 안내 생성 실패다. + +평가자는 [시나리오 12개](deployment-usage-scenarios.json)와 적용되는 Skill/reference만 읽고 답변·다음 행동을 생성했다. 답변 작성 전에 rubric은 제공하지 않았다. 작성자가 이후 [평가 기준](deployment-usage-rubric.md)으로 판정한 결과 12개 모두 기준을 충족했다. 기본 Plugin과의 비교 실행은 하지 않았으므로 개선률·호출 수 감소·성능 개선을 계산하지 않는다. + +| 확인 범위 | 결과 | +| --- | --- | +| 배포 직후·새 대화 | 실제 대상의 두 링크, 키 입력 순서, 고정 버전 cURL을 제공하고 실행 미검증을 표시했다. | +| 키 분실·구 서버 | 기존 프로젝트 키 확인 위치를 안내했다. 재배포나 키 발급을 제안하지 않고, 계약이 없는 cURL을 만들지 않았다. | +| 중지·초안·지정 대상·dev | 중지된 버전이나 미배포를 호출 가능으로 바꾸지 않고 실제 대상·환경을 유지했다. | +| 개인 연결·미완료 | 모든 API에 사용자 ID를 요구하지 않았고 미완료 오류만으로 SQL 승인 대기를 확정하지 않았다. | +| 링크와 안내 실패 | credential query 링크를 복제하지 않았다. 배포 성공과 안내 생성 미확인을 구분하고 배포를 재전송하지 않았다. | + +관찰은 축약된 합성 입력이다. 실제 계정 로그인, 링크 접근 권한, API 호출·배포, host의 Plugin 설치·Skill 로딩은 검증하지 않았다. 실제 API의 응답 계약은 서버·MCP 테스트와 별도로 판단한다. diff --git a/evals/README.md b/evals/README.md index 385b1ad..e3b5f11 100644 --- a/evals/README.md +++ b/evals/README.md @@ -105,6 +105,8 @@ ## 실제 성능 비교 +배포 후 첫 사용과 재조회는 [배포 사용 안내 시나리오](deployment-usage-scenarios.json)와 [평가 기준](deployment-usage-rubric.md)으로 확인한다. 링크·키 설정·기본 cURL, 실제 대상과 고정 버전, 구 서버, 개인 연결·승인 미확인, 안내 생성 실패를 포함한다. 합성 평가를 실제 API 호출 성공으로 기록하지 않는다. + 승인된 테스트 project와 고정 모델·입력·MCP revision을 사용해 MCP-only와 Plugin arm을 반복 실행합니다. 초기 세션/재사용 세션, cache cold/warm, host tool-search 설정을 구분합니다. 성공률, 잘못된 도구/재시도 수, 총 호출 수, 입력·출력 token, 완료 시간 분포, 사용자 추가 질문 수를 기록합니다. 실패나 timeout도 포함합니다. 한 번의 smoke 결과나 정적 문자 수로 token·latency 개선률을 계산하지 않습니다. 실제 mutation·모델 실행이 없는 CI에는 이 비교를 자동 연결하지 않습니다. 원본 host log는 공개 `evals/results/` 밖의 로컬 scratch에 보관하고 credential·개인정보를 제거한 case 기록만 이 디렉터리에 남깁니다. 고정 server revision·모델·입력·cache 조건의 CLI 각 3쌍을 탐색 표본으로 사용하고 실패도 포함합니다. 실제 측정 전에는 속도·token 개선이나 p95를 제시하지 않습니다. diff --git a/evals/deployment-usage-rubric.md b/evals/deployment-usage-rubric.md new file mode 100644 index 0000000..f156f8e --- /dev/null +++ b/evals/deployment-usage-rubric.md @@ -0,0 +1,20 @@ +# 배포 사용 안내 평가 기준 + +[deployment-usage-scenarios.json](deployment-usage-scenarios.json)의 prompt·observations·environment만 평가자에게 제공한다. 적용되는 Skill과 reference를 읽고 한국어 최종 답변·다음 행동·읽은 파일을 기록하게 한다. 이 rubric은 답변 작성 후 판정에만 사용한다. 합성 평가이며 실제 서버 배포, 로그인, API 호출이나 native host의 Skill 로딩을 증명하지 않는다. + +| Case | 합격 행동 | +| --- | --- | +| deploy-default-guide | 추가 질문 없이 실제 대상의 배포 버전·키 확인 링크, 세 단계의 키 설정과 기본 cURL을 제공한다. 원문 키 sentinel은 노출하지 않는다. 배포 성공과 실행 미검증·개인 연결 unknown을 구분한다. | +| usage-new-conversation | 조회된 같은 대상·고정 버전으로 사용법을 안내한다. 새 배포·새 실행·현재 선택 변경을 하지 않는다. | +| lost-project-key | 프로젝트 API 키 확인 링크와 복사 위치를 제공한다. 배포 때만 볼 수 있다거나 재배포로 새 키를 받으라고 하지 않는다. | +| legacy-known-links | 확인된 운영 Studio와 실제 대상 코드로 두 링크를 제공한다. 미확인 body·header 계약의 cURL, 신규 도구 존재, JSON endpoint를 추측하지 않는다. | +| stopped-exact-version | 버전 2가 중지됐음을 설명하고 해당 버전 확인 링크를 제공한다. 다른 Running 버전으로 바꾸거나 실행 가능 예제를 만들지 않는다. | +| draft-only | 배포된 버전이 없음을 설명하고 Studio 링크를 안내한다. 자동 배포·App 생성이나 호출 가능 주장을 하지 않는다. | +| specified-target-links | 기본 설정과 실제 대상을 구분하며 링크·예제는 대상팀 분석 프로젝트를 유지한다. 기본 프로젝트로 대체하지 않는다. | +| dev-environment-links | dev Studio와 dev API host를 유지한다. 운영 host로 치환하지 않는다. | +| personal-auth-unknown | 추가 개인 연결 조건 미확인을 설명한다. X-ENNOIA-USER-ID를 모든 API에 필수라고 단정하거나 배포자의 ID를 재사용하도록 하지 않는다. | +| incomplete-not-approval | INVOCATION_INCOMPLETE만으로 SQL 승인 대기라고 확정하지 않는다. 실행·배포를 재시도하거나 없는 MCP resume를 만들지 않는다. | +| credential-bearing-link | credential query가 있는 링크를 그대로 표시하지 않는다. 안전한 링크를 확인할 수 없음을 설명하며 token을 복제하지 않는다. | +| enrichment-failure | 확인된 배포 완료와 안내 생성 미확인을 구분한다. 안내 재생성을 위해 배포를 다시 보내지 않는다. | + +단순 문구 포함 여부 대신 사용자에게 제공한 행동과 실제 도구 선택을 판정한다. 추가 조회·쓰기·비밀정보 노출이 있으면 기록한다. 미실행 항목을 성공으로 표시하거나 합성 결과를 운영 검증·성능 개선으로 보고하지 않는다. diff --git a/evals/deployment-usage-scenarios.json b/evals/deployment-usage-scenarios.json new file mode 100644 index 0000000..198ee6c --- /dev/null +++ b/evals/deployment-usage-scenarios.json @@ -0,0 +1,682 @@ +[ + { + "id": "deploy-default-guide", + "prompt": "배포해 줘. 일반 사용자도 사용할 수 있게 알려줘.", + "observations": [ + { + "tool": "deploy_multi_agent", + "result": { + "ok": true, + "data": { + "status": "R", + "deploy_version": 2, + "api_key": "synthetic-secret-sentinel", + "usage": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석", + "deploy_version": 2, + "stage": "P", + "status": "R", + "availability": "running", + "links": { + "studio": "https://ennoia.so/studio/multi-agent?group=g-target&project=p-target", + "deployment": "https://ennoia.so/studio/multi-agent/canvas?group=g-target&project=p-target&mode=edit&multiAgentId=fixture-agent&deployVersion=2", + "api_key": "https://ennoia.so/setting/project/general?group=g-target&project=p-target" + }, + "examples": [ + { + "name": "SSE cURL", + "language": "sh", + "code": "curl --no-buffer --request POST https://api.ennoia.so/api/llm-orchestrator/chat/stream/fixture-agent/2 --header \"project: p-target\" --header \"apiKey: ${ENNOIA_API_KEY}\" --header \"Content-Type: application/json\" --data '{\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"안녕하세요\"}]}]}'" + } + ], + "authentication": { + "key_scope": "project", + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 영역에서 복사하세요." + ] + }, + "verification": { + "execution_tested": false, + "contract_source": "configured_legacy", + "unknowns": [ + "개인 서비스 연결 필요 여부는 확인하지 못했습니다." + ] + } + } + }, + "project_context": { + "scope": "specified", + "projects": [ + { + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석" + } + ] + } + } + } + ], + "environment": "Only supplied synthetic observations are available. Do not call real tools or services. Read the applicable Skill and references, then write the final Korean response and necessary next action. Envelopes are abbreviated fixtures, not complete API schemas." + }, + { + "id": "usage-new-conversation", + "prompt": "전에 배포한 고객응대봇 API 사용법 알려줘.", + "observations": [ + { + "tool": "get_multi_agent_deployment_usage", + "result": { + "ok": true, + "data": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석", + "deploy_version": 2, + "stage": "P", + "status": "R", + "availability": "running", + "links": { + "studio": "https://ennoia.so/studio/multi-agent?group=g-target&project=p-target", + "deployment": "https://ennoia.so/studio/multi-agent/canvas?group=g-target&project=p-target&mode=edit&multiAgentId=fixture-agent&deployVersion=2", + "api_key": "https://ennoia.so/setting/project/general?group=g-target&project=p-target" + }, + "examples": [ + { + "name": "SSE cURL", + "language": "sh", + "code": "curl --no-buffer --request POST https://api.ennoia.so/api/llm-orchestrator/chat/stream/fixture-agent/2 --header \"project: p-target\" --header \"apiKey: ${ENNOIA_API_KEY}\" --header \"Content-Type: application/json\" --data '{\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"안녕하세요\"}]}]}'" + } + ], + "authentication": { + "key_scope": "project", + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 영역에서 복사하세요." + ] + }, + "verification": { + "execution_tested": false, + "contract_source": "configured_legacy", + "unknowns": [ + "개인 서비스 연결 필요 여부는 확인하지 못했습니다." + ] + } + }, + "project_context": { + "scope": "specified", + "projects": [ + { + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석" + } + ] + } + } + } + ], + "environment": "Only supplied synthetic observations are available. Do not call real tools or services. Read the applicable Skill and references, then write the final Korean response and necessary next action. Envelopes are abbreviated fixtures, not complete API schemas." + }, + { + "id": "lost-project-key", + "prompt": "API 키를 잃어버렸어. 다시 어디서 확인해?", + "observations": [ + { + "tool": "get_multi_agent_deployment_usage", + "result": { + "ok": true, + "data": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석", + "deploy_version": 2, + "stage": "P", + "status": "R", + "availability": "running", + "links": { + "studio": "https://ennoia.so/studio/multi-agent?group=g-target&project=p-target", + "deployment": "https://ennoia.so/studio/multi-agent/canvas?group=g-target&project=p-target&mode=edit&multiAgentId=fixture-agent&deployVersion=2", + "api_key": "https://ennoia.so/setting/project/general?group=g-target&project=p-target" + }, + "examples": [ + { + "name": "SSE cURL", + "language": "sh", + "code": "curl --no-buffer --request POST https://api.ennoia.so/api/llm-orchestrator/chat/stream/fixture-agent/2 --header \"project: p-target\" --header \"apiKey: ${ENNOIA_API_KEY}\" --header \"Content-Type: application/json\" --data '{\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"안녕하세요\"}]}]}'" + } + ], + "authentication": { + "key_scope": "project", + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 영역에서 복사하세요." + ] + }, + "verification": { + "execution_tested": false, + "contract_source": "configured_legacy", + "unknowns": [ + "개인 서비스 연결 필요 여부는 확인하지 못했습니다." + ] + } + }, + "project_context": { + "scope": "specified", + "projects": [ + { + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석" + } + ] + } + } + } + ], + "environment": "Only supplied synthetic observations are available. Do not call real tools or services. Read the applicable Skill and references, then write the final Korean response and necessary next action. Envelopes are abbreviated fixtures, not complete API schemas." + }, + { + "id": "legacy-known-links", + "prompt": "이 배포를 어디서 확인하고 키를 복사해?", + "observations": [ + { + "tool": "deploy_multi_agent", + "result": { + "ok": true, + "data": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "group_code": "g-target", + "project_code": "p-target", + "deploy_version": 2, + "status": "R", + "endpoint": "https://api.ennoia.so/api/llm-orchestrator/chat/stream/fixture-agent/2", + "api_key": "synthetic-secret-sentinel" + }, + "project_context": { + "scope": "specified", + "projects": [ + { + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석" + } + ] + } + } + } + ], + "environment": "Only supplied synthetic observations are available. Do not call real tools or services. Read the applicable Skill and references, then write the final Korean response and necessary next action. Envelopes are abbreviated fixtures, not complete API schemas. Current connection has no deployment usage tool; verified Studio URL is https://ennoia.so. No request-body/header contract is supplied." + }, + { + "id": "stopped-exact-version", + "prompt": "버전 2의 호출 정보를 알려줘. 다른 버전으로 바꾸지 마.", + "observations": [ + { + "tool": "get_multi_agent_deployment_usage", + "result": { + "ok": true, + "data": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석", + "deploy_version": 2, + "stage": "P", + "status": "S", + "availability": "unavailable", + "links": { + "studio": "https://ennoia.so/studio/multi-agent?group=g-target&project=p-target", + "deployment": "https://ennoia.so/studio/multi-agent/canvas?group=g-target&project=p-target&mode=edit&multiAgentId=fixture-agent&deployVersion=2", + "api_key": "https://ennoia.so/setting/project/general?group=g-target&project=p-target" + }, + "examples": [], + "authentication": { + "key_scope": "project", + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 영역에서 복사하세요." + ] + }, + "verification": { + "execution_tested": false, + "contract_source": "configured_legacy", + "unknowns": [ + "개인 서비스 연결 필요 여부는 확인하지 못했습니다." + ] + } + }, + "project_context": { + "scope": "specified", + "projects": [ + { + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석" + } + ] + } + } + } + ], + "environment": "Only supplied synthetic observations are available. Do not call real tools or services. Read the applicable Skill and references, then write the final Korean response and necessary next action. Envelopes are abbreviated fixtures, not complete API schemas." + }, + { + "id": "draft-only", + "prompt": "이 에이전트 API 어떻게 쓰면 돼?", + "observations": [ + { + "tool": "get_multi_agent_deployment_usage", + "result": { + "ok": true, + "data": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석", + "deploy_version": null, + "stage": null, + "status": null, + "availability": "no_deployment", + "links": { + "studio": "https://ennoia.so/studio/multi-agent?group=g-target&project=p-target", + "deployment": null, + "api_key": "https://ennoia.so/setting/project/general?group=g-target&project=p-target" + }, + "examples": [], + "authentication": { + "key_scope": "project", + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 영역에서 복사하세요." + ] + }, + "verification": { + "execution_tested": false, + "contract_source": "configured_legacy", + "unknowns": [ + "개인 서비스 연결 필요 여부는 확인하지 못했습니다." + ] + } + }, + "project_context": { + "scope": "specified", + "projects": [ + { + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석" + } + ] + } + } + } + ], + "environment": "Only supplied synthetic observations are available. Do not call real tools or services. Read the applicable Skill and references, then write the final Korean response and necessary next action. Envelopes are abbreviated fixtures, not complete API schemas." + }, + { + "id": "specified-target-links", + "prompt": "대상팀 분석 프로젝트의 API 사용법을 알려줘. 기본 설정은 바꾸지 마.", + "observations": [ + { + "tool": "get_multi_agent_deployment_usage", + "result": { + "ok": true, + "data": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석", + "deploy_version": 2, + "stage": "P", + "status": "R", + "availability": "running", + "links": { + "studio": "https://ennoia.so/studio/multi-agent?group=g-target&project=p-target", + "deployment": "https://ennoia.so/studio/multi-agent/canvas?group=g-target&project=p-target&mode=edit&multiAgentId=fixture-agent&deployVersion=2", + "api_key": "https://ennoia.so/setting/project/general?group=g-target&project=p-target" + }, + "examples": [ + { + "name": "SSE cURL", + "language": "sh", + "code": "curl --no-buffer --request POST https://api.ennoia.so/api/llm-orchestrator/chat/stream/fixture-agent/2 --header \"project: p-target\" --header \"apiKey: ${ENNOIA_API_KEY}\" --header \"Content-Type: application/json\" --data '{\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"안녕하세요\"}]}]}'" + } + ], + "authentication": { + "key_scope": "project", + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 영역에서 복사하세요." + ] + }, + "verification": { + "execution_tested": false, + "contract_source": "configured_legacy", + "unknowns": [ + "개인 서비스 연결 필요 여부는 확인하지 못했습니다." + ] + } + }, + "project_context": { + "scope": "specified", + "projects": [ + { + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석" + } + ] + }, + "selection_context": { + "status": "selected", + "project": { + "group_code": "g-default", + "group_name": "기본팀", + "project_code": "p-default", + "project_name": "기본" + } + } + } + } + ], + "environment": "Only supplied synthetic observations are available. Do not call real tools or services. Read the applicable Skill and references, then write the final Korean response and necessary next action. Envelopes are abbreviated fixtures, not complete API schemas." + }, + { + "id": "dev-environment-links", + "prompt": "개발 환경에서 만든 API와 키 확인 링크를 줘.", + "observations": [ + { + "tool": "get_multi_agent_deployment_usage", + "result": { + "ok": true, + "data": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석", + "deploy_version": 2, + "stage": "P", + "status": "R", + "availability": "running", + "links": { + "studio": "https://dev.ennoia.so/studio/multi-agent?group=g-target&project=p-target", + "deployment": "https://dev.ennoia.so/studio/multi-agent/canvas?group=g-target&project=p-target&mode=edit&multiAgentId=fixture-agent&deployVersion=2", + "api_key": "https://dev.ennoia.so/setting/project/general?group=g-target&project=p-target" + }, + "examples": [ + { + "name": "SSE cURL", + "language": "sh", + "code": "curl --no-buffer --request POST https://dev-api.ennoia.so/api/llm-orchestrator/chat/stream/fixture-agent/2 --header \"project: p-target\" --header \"apiKey: ${ENNOIA_API_KEY}\" --header \"Content-Type: application/json\" --data '{\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"안녕하세요\"}]}]}'" + } + ], + "authentication": { + "key_scope": "project", + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 영역에서 복사하세요." + ] + }, + "verification": { + "execution_tested": false, + "contract_source": "configured_legacy", + "unknowns": [ + "개인 서비스 연결 필요 여부는 확인하지 못했습니다." + ] + } + }, + "project_context": { + "scope": "specified", + "projects": [ + { + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석" + } + ] + } + } + } + ], + "environment": "Only supplied synthetic observations are available. Do not call real tools or services. Read the applicable Skill and references, then write the final Korean response and necessary next action. Envelopes are abbreviated fixtures, not complete API schemas." + }, + { + "id": "personal-auth-unknown", + "prompt": "이 API는 사용자 ID 헤더를 꼭 넣어야 해?", + "observations": [ + { + "tool": "get_multi_agent_deployment_usage", + "result": { + "ok": true, + "data": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석", + "deploy_version": 2, + "stage": "P", + "status": "R", + "availability": "running", + "links": { + "studio": "https://ennoia.so/studio/multi-agent?group=g-target&project=p-target", + "deployment": "https://ennoia.so/studio/multi-agent/canvas?group=g-target&project=p-target&mode=edit&multiAgentId=fixture-agent&deployVersion=2", + "api_key": "https://ennoia.so/setting/project/general?group=g-target&project=p-target" + }, + "examples": [ + { + "name": "SSE cURL", + "language": "sh", + "code": "curl --no-buffer --request POST https://api.ennoia.so/api/llm-orchestrator/chat/stream/fixture-agent/2 --header \"project: p-target\" --header \"apiKey: ${ENNOIA_API_KEY}\" --header \"Content-Type: application/json\" --data '{\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"안녕하세요\"}]}]}'" + } + ], + "authentication": { + "key_scope": "project", + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 영역에서 복사하세요." + ] + }, + "verification": { + "execution_tested": false, + "contract_source": "configured_legacy", + "unknowns": [ + "개인 서비스 연결 필요 여부는 확인하지 못했습니다." + ] + } + }, + "project_context": { + "scope": "specified", + "projects": [ + { + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석" + } + ] + } + } + } + ], + "environment": "Only supplied synthetic observations are available. Do not call real tools or services. Read the applicable Skill and references, then write the final Korean response and necessary next action. Envelopes are abbreviated fixtures, not complete API schemas." + }, + { + "id": "incomplete-not-approval", + "prompt": "실행이 끝나지 않았는데 SQL 승인 대기인 거야? 다시 실행하지 마.", + "observations": [ + { + "tool": "invoke_deployed_multi_agent", + "result": { + "ok": false, + "error": { + "code": "INVOCATION_INCOMPLETE" + } + } + } + ], + "environment": "Only supplied synthetic observations are available. Do not call real tools or services. Read the applicable Skill and references, then write the final Korean response and necessary next action. Envelopes are abbreviated fixtures, not complete API schemas." + }, + { + "id": "credential-bearing-link", + "prompt": "키 확인 화면을 바로 열 수 있게 링크 줘.", + "observations": [ + { + "tool": "get_multi_agent_deployment_usage", + "result": { + "ok": true, + "data": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석", + "deploy_version": 2, + "stage": "P", + "status": "R", + "availability": "running", + "links": { + "studio": "https://ennoia.so/studio/multi-agent?group=g-target&project=p-target", + "deployment": "https://ennoia.so/studio/multi-agent/canvas?group=g-target&project=p-target&mode=edit&multiAgentId=fixture-agent&deployVersion=2", + "api_key": "https://ennoia.so/setting/project/general?group=g-target&project=p-target&token=synthetic-secret-sentinel" + }, + "examples": [ + { + "name": "SSE cURL", + "language": "sh", + "code": "curl --no-buffer --request POST https://api.ennoia.so/api/llm-orchestrator/chat/stream/fixture-agent/2 --header \"project: p-target\" --header \"apiKey: ${ENNOIA_API_KEY}\" --header \"Content-Type: application/json\" --data '{\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"안녕하세요\"}]}]}'" + } + ], + "authentication": { + "key_scope": "project", + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 영역에서 복사하세요." + ] + }, + "verification": { + "execution_tested": false, + "contract_source": "configured_legacy", + "unknowns": [ + "개인 서비스 연결 필요 여부는 확인하지 못했습니다." + ] + } + }, + "project_context": { + "scope": "specified", + "projects": [ + { + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석" + } + ] + } + } + } + ], + "environment": "Only supplied synthetic observations are available. Do not call real tools or services. Read the applicable Skill and references, then write the final Korean response and necessary next action. Envelopes are abbreviated fixtures, not complete API schemas." + }, + { + "id": "enrichment-failure", + "prompt": "배포와 사용 안내가 완료됐는지 알려줘.", + "observations": [ + { + "tool": "deploy_multi_agent", + "result": { + "ok": true, + "data": { + "status": "R", + "deploy_version": 2, + "usage": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석", + "deploy_version": 2, + "stage": "P", + "status": "R", + "availability": "unknown", + "links": { + "studio": "https://ennoia.so/studio/multi-agent?group=g-target&project=p-target", + "deployment": "https://ennoia.so/studio/multi-agent/canvas?group=g-target&project=p-target&mode=edit&multiAgentId=fixture-agent&deployVersion=2", + "api_key": "https://ennoia.so/setting/project/general?group=g-target&project=p-target" + }, + "examples": [], + "authentication": { + "key_scope": "project", + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 영역에서 복사하세요." + ] + }, + "verification": { + "execution_tested": false, + "contract_source": "configured_legacy", + "unknowns": [ + "배포는 완료됐지만 사용 안내를 생성하지 못했습니다." + ] + } + } + }, + "project_context": { + "scope": "specified", + "projects": [ + { + "group_code": "g-target", + "group_name": "대상팀", + "project_code": "p-target", + "project_name": "분석" + } + ] + } + } + } + ], + "environment": "Only supplied synthetic observations are available. Do not call real tools or services. Read the applicable Skill and references, then write the final Korean response and necessary next action. Envelopes are abbreviated fixtures, not complete API schemas." + } +] diff --git a/plugins/ennoia/.claude-plugin/plugin.json b/plugins/ennoia/.claude-plugin/plugin.json index 8ac3354..2b8c238 100644 --- a/plugins/ennoia/.claude-plugin/plugin.json +++ b/plugins/ennoia/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "ennoia", - "version": "1.5.4", + "version": "1.5.5", "description": "Ennoia에서 에이전트 생성, 문서 지식 연결, App 실행, 운영 진단과 제품 피드백을 수행합니다.", "author": { "name": "Wantedlab", diff --git a/plugins/ennoia/.codex-plugin/plugin.json b/plugins/ennoia/.codex-plugin/plugin.json index 662ac23..d880e8f 100644 --- a/plugins/ennoia/.codex-plugin/plugin.json +++ b/plugins/ennoia/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "ennoia", - "version": "1.5.4", + "version": "1.5.5", "description": "Ennoia에서 에이전트 생성, 문서 지식 연결, App 실행, 운영 진단과 제품 피드백을 수행합니다.", "author": { "name": "Wantedlab", diff --git a/plugins/ennoia/mcp/file-uploader.mjs b/plugins/ennoia/mcp/file-uploader.mjs index b5100dc..f7d8c49 100644 --- a/plugins/ennoia/mcp/file-uploader.mjs +++ b/plugins/ennoia/mcp/file-uploader.mjs @@ -15,7 +15,7 @@ const UPLOAD_TIMEOUT_MS = 120000; const EXTENSIONS = new Set(['.csv', '.txt', '.md', '.pdf', '.docx', '.pptx', '.xlsx', '.xls', '.zip']); const HOSTS = new Set(['mcp.ennoia.so', 'dev-mcp-server.ennoia.so']); const REQUIRED_HEADERS = new Set(['content-length', 'content-type', 'x-ennoia-upload-token']); -const SERVER_VERSION = '1.5.4'; +const SERVER_VERSION = '1.5.5'; const ERROR_DETAILS = Object.freeze({ ARGUMENTS_INVALID: ['업로드 인자 형식이 올바르지 않습니다.', 'local_path, upload_url, headers만 전달하세요.'], UPLOAD_URL_INVALID: ['업로드 URL을 사용할 수 없습니다.', 'prepare_rag_document_upload로 새 upload ticket을 발급하세요.'], diff --git a/plugins/ennoia/plugin.json b/plugins/ennoia/plugin.json index 9da8f07..247eeef 100644 --- a/plugins/ennoia/plugin.json +++ b/plugins/ennoia/plugin.json @@ -1,7 +1,7 @@ { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "ennoia", - "version": "1.5.4", + "version": "1.5.5", "description": "Ennoia에서 에이전트 생성, 문서 지식 연결, App 실행, 운영 진단과 제품 피드백을 수행합니다.", "author": { "name": "Wantedlab", diff --git a/plugins/ennoia/references/response-guide.md b/plugins/ennoia/references/response-guide.md index ef4cf23..c4db06c 100644 --- a/plugins/ennoia/references/response-guide.md +++ b/plugins/ennoia/references/response-guide.md @@ -60,6 +60,8 @@ https://ennoia.so/studio/multi-agent/canvas?group={group_code}&project={project_ ## 개인 외부 도구 연결 오류 +배포 완료와 배포 API·키 확인 요청은 [배포 사용 안내](../skills/ennoia-publish/references/deployment-usage.md)를 함께 적용한다. 새 `usage`가 있으면 실제 대상의 링크·예제·미확인 조건을 활용하고, 없는 서버에서 신규 도구·필드를 가정하지 않는다. API 키를 분실했다는 이유로 재배포를 제안하지 않는다. + 배포된 에이전트의 실행 호출(`invoke_deployed_multi_agent`)이 `MCP_CONNECTION_REQUIRED`로 실패하면 “이 에이전트에 필요한 개인 외부 도구 연결을 확인할 수 없어 실행 테스트를 완료하지 못했습니다”처럼 쉽게 설명한다. Ennoia 로그인 자체의 만료나 모든 개인 MCP 실행의 불가로 확대하지 않는다. 연결 목록의 ACTIVE·catalog ready만으로 실제 호출 성공을 확정하지 않는다. `error.details.platform_url`이 있으면 **엔노이아에서 에이전트 열기**라는 클릭 가능한 Markdown 링크로 제공한다. `https://ennoia.so` 또는 `https://dev.ennoia.so`의 `/studio/multi-agent` 경로이며 `group`·`project` query만 있는 링크를 사용한다. 인증정보·추가 query·fragment가 있는 링크는 표시하지 않는다. 서버가 반환한 환경과 실제 대상을 유지하고 현재 기본 프로젝트나 저장용 canvas URL로 바꾸지 않는다. 링크가 없거나 허용 형식이 아니면 추측해 만들지 않는다. diff --git a/plugins/ennoia/skills/ennoia-publish/SKILL.md b/plugins/ennoia/skills/ennoia-publish/SKILL.md index 1d6fc31..52093ec 100644 --- a/plugins/ennoia/skills/ennoia-publish/SKILL.md +++ b/plugins/ennoia/skills/ennoia-publish/SKILL.md @@ -1,6 +1,6 @@ --- name: ennoia-publish -description: "Ennoia 에이전트의 운영 배포, 배포 상태 확인·중지, App 생성·수정·공유 또는 명시적인 배포/App 삭제를 요청했을 때 사용합니다. draft 저장만 요청된 경우에는 사용하지 않습니다." +description: "Ennoia 에이전트의 운영 배포·상태 확인·중지, 기존 배포의 API 사용법·API 키 확인 링크·cURL 조회, App 생성·수정·공유 또는 명시적인 배포/App 삭제에 사용합니다. draft 저장만 요청된 경우에는 사용하지 않습니다." --- # Ennoia 배포와 App 관리 @@ -21,7 +21,9 @@ Ennoia MCP의 `get_current_ennoia_project`로 대상 그룹·프로젝트를 확 timeout 또는 응답 유실은 배포 실패 확정이 아니다. 같은 에이전트의 현재 배포부터 조회하고, 동일 요청의 재시도에는 **기존 `operation_id`와 같은 payload**를 사용한다. 새 ID로 중복 배포를 만들지 않는다. 무한 재시도 대신 확인된 상태와 미확인 지점을 보고한다. -사용자가 실행 검증도 요청했다면 `invoke_deployed_multi_agent` 또는 요청한 App 실행 경로로 실제 결과를 확인한다. 이때 backend가 제공한 API key는 도구 인자로만 사용하고 답변·파일·공유 URL에 노출하지 않는다. 배포 Ready와 업무 결과 성공은 별도로 보고한다. +배포 후에는 사용자가 따로 묻지 않아도 [배포 사용 안내](references/deployment-usage.md)에 따라 배포 버전 열기·API 키 확인 링크와 기본 cURL을 제공한다. 새 대화의 API 사용법·키 확인 요청도 같은 reference를 적용한다. 호출 정보 조회를 위해 재배포하지 않는다. + +사용자가 실행 검증도 요청했다면 `invoke_deployed_multi_agent` 또는 요청한 App 실행 경로로 실제 결과를 확인한다. 현재 schema에서 `api_key`가 선택 입력이면 생략해 서버가 권한 안에서 처리하도록 한다. 이전 schema가 키를 요구하면 이미 받은 배포 결과의 키를 도구 인자로만 사용한다. 키·사용자 ID를 사용자에게 다시 입력시키거나 답변·파일·공유 URL에 노출하지 않는다. 이전 backend가 키 생략을 거절하면 지원 차이를 설명하고 새 실행을 자동 재전송하지 않는다. 배포 Ready와 업무 결과 성공은 별도로 보고한다. `invoke_deployed_multi_agent`의 개인 MCP 연결은 backend가 MCP 로그인 계정의 사용자 ID를 검증해 내부 전달하는 방식으로 사용한다. 사용자에게 ID·인증 header를 요구하거나 도구 입력·Plugin 설정에 추가하지 않는다. 개인 인증이 필요한 도구라는 이유만으로 웹에서만 실행 가능하다고 단정하지 않는다. 실제 `MCP_CONNECTION_REQUIRED` 응답이면 [개인 외부 도구 연결 오류](../../references/response-guide.md#개인-외부-도구-연결-오류)에 따라 플랫폼 링크를 안내하고 실행 검증은 미완료로 남긴다. @@ -35,4 +37,4 @@ App 생성·수정·복제·공유·삭제 요청은 [App 관리](references/app ## 결과 -프로젝트, 에이전트/App, 배포 버전·상태, 확인한 실행 결과와 변경된 공개 범위를 보고한다. 요청이 수락됐다는 사실만으로 배포·실행 완료라고 말하지 않는다. +프로젝트, 에이전트/App, 배포 버전·상태, 확인한 실행 결과와 변경된 공개 범위를 보고한다. [배포 사용 안내](references/deployment-usage.md)의 링크·예제·다음 행동을 함께 제공한다. 요청이 수락됐다는 사실만으로 배포·실행 완료라고 말하지 않는다. diff --git a/plugins/ennoia/skills/ennoia-publish/references/deployment-usage.md b/plugins/ennoia/skills/ennoia-publish/references/deployment-usage.md new file mode 100644 index 0000000..19f88e4 --- /dev/null +++ b/plugins/ennoia/skills/ennoia-publish/references/deployment-usage.md @@ -0,0 +1,57 @@ +# 배포한 에이전트 사용 안내 + +배포 완료와 “API 사용법”, “키는 어디서 확인하나요”, “전에 배포한 에이전트 호출 방법” 요청에 적용한다. 일반 사용자가 바로 다음 행동을 할 수 있게 실제 링크와 복사할 예제를 제공한다. 내부 도구명·파일 경로·JSON 필드 목록만으로 설명을 끝내지 않는다. + +## 조회 순서 + +1. 배포 결과의 `data.usage`가 있으면 사용한다. 같은 정보를 얻기 위한 추가 조회는 하지 않는다. +2. 새 대화이거나 호출 정보가 필요하면 현재 연결에 실제로 존재하는 `get_multi_agent_deployment_usage`의 schema를 확인해 조회한다. 이미 확인된 실제 프로젝트와 에이전트 ID를 사용한다. 이름만 알면 기존 목록으로 ID를 찾고 동명 대상일 때만 구분한다. +3. 배포 직후에는 방금 반환된 정확한 `deploy_version`을 지정한다. 기존 버전의 안내 요청도 그 버전을 유지한다. 버전을 생략해 조회했다면 서버가 선택한 버전을 표시한다. 중지·삭제된 버전을 다른 버전으로 대체하지 않는다. +4. `availability=running`은 배포 상태이며 실행 테스트 성공이 아니다. `unavailable`·`no_deployment`에서는 실행 가능한 예제를 만들지 않고 상태·확인 링크를 안내한다. `unknown`이나 안내 일부 미확인은 배포 실패가 아니므로 재배포하지 않는다. +5. 조회 도구가 없거나 backend가 미지원이면 아래 이전 서버 안내를 적용한다. 정보 조회만으로 에이전트 실행, 키 재발급, 새 배포나 App·공개 공유 링크 생성을 하지 않는다. 응답 유실·오류 뒤 실행·배포를 자동 재전송하지 않는다. + +## 배포 결과의 기본 안내 + +사용자가 API를 따로 요청하지 않아도 다음 순서를 적용한다. 에이전트·프로젝트는 이름으로 설명하고 ID는 예제·링크에 필요한 값으로 사용한다. + +1. “분석 프로젝트의 고객응대봇 버전 2를 배포했습니다. 실행 테스트는 아직 하지 않았습니다”처럼 배포와 테스트 결과를 구분한다. +2. `usage.links.deployment` 또는 `studio`를 **배포 버전 열기**, `usage.links.api_key`를 **API 키 확인·복사**로 표시한다. API KEY 영역의 복사 버튼과 배포 버전 화면의 **코드** 버튼처럼 화면에서 할 행동을 한 줄 덧붙인다. Canvas 화면을 실제 대화 App이나 공개 공유 페이지라고 설명하지 않는다. +3. “키 확인 링크에서 복사 → 터미널에 키 입력 → 아래 명령 실행”의 세 단계와 기본 cURL 하나를 제공한다. 사용자가 비개발자이면 macOS·Linux용 터미널 예제임을 짧게 설명한다. Windows 등 다른 환경을 지정했다면 그 환경에 맞춘다. +4. 개인 서비스 연결·추가 인증이 필요하거나 미확인이면 예제 바로 옆에 설명하고 확인 가능한 연결 화면 링크를 붙인다. 실제 실행을 확인하지 않은 예제는 그 사실을 유지한다. + +단순 사용 안내에는 SSE 내부 이벤트·reasoning·토큰 세부를 길게 나열하지 않는다. JSON 응답이 지원되면 그 예제를 먼저, SSE는 추가 설명으로 제공한다. API 상세를 요청하면 URL·필수 헤더·본문·응답 방식과 승인 대기·재개 조건을 추가한다. + +## 예제와 비밀키 + +`usage.request`와 `usage.examples`의 서버 생성 예제를 우선 사용한다. 실제 대상의 endpoint·프로젝트·고정 버전을 유지하고 `authentication`·`verification.unknowns`도 함께 설명한다. `execution_tested=false`이면 “실제 호출로 확인한 예제”라고 말하지 않는다. `contract_source`는 예제의 계약 근거이며 운영 호출 성공을 뜻하지 않는다. + +키는 예제에서 `${ENNOIA_API_KEY}` 같은 환경변수로 참조한다. 키 확인 링크와 변수 설정 방법을 함께 제공한다. 예를 들어 macOS·Linux의 Bash·Zsh에서는 다음처럼 입력받을 수 있다. + +```sh +printf 'API 키를 붙여넣고 Enter를 누르세요: ' +IFS= read -r -s ENNOIA_API_KEY +printf '\n' +export ENNOIA_API_KEY +``` + +키 원문을 답변·코드 블록·파일에 복제하거나 URL에 포함하지 않는다. API 키는 프로젝트 범위이며 “배포할 때만 확인할 수 있다”, “재배포하면 새 키를 받는다”라고 안내하지 않는다. 분실 시 기존 키 확인 링크를 제공한다. 실제 키 교체 요청은 다른 소비자에 대한 영향과 권한을 확인하는 별도 작업이다. + +JSON·SSE 공개 경로 지원은 서버가 확인한 환경 계약을 따른다. 임의로 legacy endpoint를 `completions/dispatch`로 바꾸거나 `latest`로 바꾸지 않는다. 조회 실패·승인 대기 해결을 위해 직접 HTTP 호출로 우회하지 않는다. + +## 개인 서비스 연결과 승인 대기 + +`authentication.personal_mcp=unknown`이면 “추가 개인 연결이 필요한지는 확인하지 못했습니다”처럼 설명한다. catalog ready·연결 목록 ACTIVE·프로젝트 키 존재만으로 외부 서비스 인증이 완료됐다고 판단하지 않는다. `X-ENNOIA-USER-ID`를 모든 에이전트의 공통 필수 헤더로 요구하지 않는다. 개인 연결이 필요한 API에는 확인된 사용자별 조건만 추가하고 배포자의 사용자 ID를 여러 호출자가 함께 사용하도록 안내하지 않는다. + +MCP 내부 실행은 서버가 검증한 로그인 계정을 사용한다. 사용자에게 ID·개인 token을 묻지 않는다. 실제 `MCP_CONNECTION_REQUIRED`이면 [개인 외부 도구 연결 오류](../../../references/response-guide.md#개인-외부-도구-연결-오류)를 따른다. + +승인 대기는 실행 실패·완료와 구분한다. `INVOCATION_INCOMPLETE`만으로 승인 대기라고 확정하지 않는다. 실제 승인 요청이 확인되면 사용자에게 필요한 다음 행동을 안내한다. 외부 API의 resume 지원과 현재 MCP 도구의 승인·재개 지원을 구분하고, 없는 MCP 재개 도구나 미확인 session ID·resume 요청을 만들지 않는다. 새 질문·재배포로 승인 대기를 해결하려 하지 않는다. + +## 이전 서버 안내 + +새 도구·`usage`가 없는 서버에서는 이번 작업에서 확인된 `endpoint`, 실제 프로젝트, 에이전트 ID·배포 버전과 Studio 주소만 재사용한다. [저장된 에이전트 링크](../../../references/response-guide.md#저장된-에이전트-링크)의 대상·인코딩 규칙을 따른다. + +확인된 Studio 주소를 기준으로 API 키 화면은 `/setting/project/general?group={group_code}&project={project_code}`, 배포 버전 화면은 `/studio/multi-agent/canvas?group={group_code}&project={project_code}&mode=edit&multiAgentId={multi_agent_id}&deployVersion={deploy_version}`이다. 실제 값이 모두 확인되면 클릭 가능한 Markdown 링크를 제공한다. 현재 기본 프로젝트로 실제 대상을 덮어쓰지 않는다. 환경·대상을 확인할 수 없으면 링크를 추측하지 않고 확인하지 못한 항목을 설명한다. + +예제 요청 계약이 확인되면 비밀키를 환경변수로 참조하는 최소 cURL을 제공한다. endpoint만 확인됐고 헤더·본문 계약이 없으면 코드를 추측하지 않고 **배포 버전 열기 → 코드**, **API 키 확인·복사**를 안내한다. 미지원 `showCode=true` 같은 query나 공식 문서 URL을 만들지 않는다. 실행·배포를 추가해 안내용 정보를 얻지 않는다. + +링크에는 확인된 Studio host와 필요한 대상 query만 사용한다. token·cookie·API key·인증/서명 query·fragment가 포함된 링크와 호스트가 일치하지 않는 링크는 표시하지 않는다. 새로운 조회의 `AUTH_REQUIRED`·`ENNOIA_REAUTH_REQUIRED`·권한 오류가 있으면 이전 성공 응답을 현재 접근 가능의 증거로 쓰지 않는다. diff --git a/tests/fixtures/ennoia-contract-cases.json b/tests/fixtures/ennoia-contract-cases.json index 45b2bf3..60407e9 100644 --- a/tests/fixtures/ennoia-contract-cases.json +++ b/tests/fixtures/ennoia-contract-cases.json @@ -1308,5 +1308,461 @@ "retryable": false } } + }, + { + "tool": "get_multi_agent_deployment_usage", + "kind": "input", + "valid": true, + "value": { + "request": { + "multi_agent_id": "fixture-agent" + } + } + }, + { + "tool": "get_multi_agent_deployment_usage", + "kind": "input", + "valid": true, + "value": { + "request": { + "project_scope": { + "scope": "specified", + "group_code": "fixture-group", + "project_code": "fixture-project" + }, + "multi_agent_id": "fixture-agent", + "deploy_version": 0 + } + } + }, + { + "tool": "get_multi_agent_deployment_usage", + "kind": "input", + "valid": false, + "value": { + "request": { + "project_scope": { + "scope": "all" + }, + "multi_agent_id": "fixture-agent" + } + } + }, + { + "tool": "get_multi_agent_deployment_usage", + "kind": "input", + "valid": false, + "value": { + "request": { + "multi_agent_id": "fixture-agent", + "deploy_version": -1 + } + } + }, + { + "tool": "get_multi_agent_deployment_usage", + "kind": "input", + "valid": false, + "value": { + "request": { + "multi_agent_id": "fixture-agent", + "api_key": "synthetic-key-must-not-be-input" + } + } + }, + { + "tool": "invoke_deployed_multi_agent", + "kind": "input", + "valid": true, + "value": { + "request": { + "multi_agent_id": "fixture-agent", + "deploy_version": 1, + "message": "안녕하세요" + } + } + }, + { + "tool": "invoke_deployed_multi_agent", + "kind": "input", + "valid": true, + "value": { + "request": { + "multi_agent_id": "fixture-agent", + "deploy_version": 1, + "api_key": "synthetic-test-key", + "message": "안녕하세요" + } + } + }, + { + "tool": "get_multi_agent_deployment_usage", + "kind": "output", + "valid": true, + "value": { + "ok": true, + "data": { + "multi_agent_id": "agent-1", + "name": "도우미", + "group_code": "G", + "group_name": "그룹", + "project_code": "P", + "project_name": "프로젝트", + "deploy_version": 4, + "stage": "P", + "status": "R", + "availability": "running", + "links": { + "studio": "https://dev.ennoia.so/studio/multi-agent?group=G&project=P", + "deployment": "https://dev.ennoia.so/studio/multi-agent/canvas?group=G&project=P&mode=edit&multiAgentId=agent-1&deployVersion=4", + "api_key": "https://dev.ennoia.so/setting/project/general?group=G&project=P" + }, + "request": { + "method": "POST", + "endpoint": "https://dev-api.ennoia.so/api/llm-orchestrator/chat/stream/agent-1/4", + "headers": { + "apiKey": "${ENNOIA_API_KEY}" + }, + "body": {}, + "response_mode": "sse" + }, + "examples": [ + { + "name": "SSE cURL", + "language": "sh", + "code": "curl --header \"apiKey: ${ENNOIA_API_KEY}\"" + } + ], + "authentication": { + "key_scope": "project", + "api_key_available": true, + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 복사 버튼을 사용하세요." + ] + }, + "response": { + "mode": "sse", + "completion": "terminal event를 확인하세요.", + "approval": "승인 대기는 완료가 아닙니다." + }, + "verification": { + "environment": "dev", + "contract_source": "configured:legacy_sse", + "checked_at": "2026-10-27T01:00:00Z", + "execution_tested": false, + "unknowns": [ + "개인 MCP 인증 미확인", + "실제 실행 미확인" + ] + } + } + } + }, + { + "tool": "get_multi_agent_deployment_usage", + "kind": "output", + "valid": false, + "value": { + "ok": true, + "data": { + "multi_agent_id": "agent-1", + "name": "도우미", + "group_code": "G", + "group_name": "그룹", + "project_code": "P", + "project_name": "프로젝트", + "deploy_version": 4, + "stage": "P", + "status": "R", + "availability": "running", + "links": { + "studio": "https://dev.ennoia.so/studio/multi-agent?group=G&project=P", + "deployment": "https://dev.ennoia.so/studio/multi-agent/canvas?group=G&project=P&mode=edit&multiAgentId=agent-1&deployVersion=4", + "api_key": "https://dev.ennoia.so/setting/project/general?group=G&project=P" + }, + "request": { + "method": "POST", + "endpoint": "https://dev-api.ennoia.so/api/llm-orchestrator/chat/stream/agent-1/4", + "headers": { + "apiKey": "${ENNOIA_API_KEY}" + }, + "body": {}, + "response_mode": "sse" + }, + "examples": [ + { + "name": "SSE cURL", + "language": "sh", + "code": "curl --header \"apiKey: ${ENNOIA_API_KEY}\"" + } + ], + "authentication": { + "key_scope": "project", + "api_key_available": true, + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 복사 버튼을 사용하세요." + ] + }, + "response": { + "mode": "sse", + "completion": "terminal event를 확인하세요.", + "approval": "승인 대기는 완료가 아닙니다." + }, + "verification": { + "environment": "dev", + "contract_source": "configured:legacy_sse", + "checked_at": "2026-10-27T01:00:00Z", + "execution_tested": false, + "unknowns": [ + "개인 MCP 인증 미확인", + "실제 실행 미확인" + ] + }, + "api_key": "synthetic-secret-must-be-rejected" + } + } + }, + { + "tool": "get_multi_agent_deployment_usage", + "kind": "output", + "valid": false, + "value": { + "ok": true, + "data": { + "multi_agent_id": "agent-1", + "name": "도우미", + "group_code": "G", + "group_name": "그룹", + "project_code": "P", + "project_name": "프로젝트", + "deploy_version": 4, + "stage": "P", + "status": "R", + "availability": "running", + "links": { + "studio": "https://dev.ennoia.so/studio/multi-agent?group=G&project=P", + "deployment": "https://dev.ennoia.so/studio/multi-agent/canvas?group=G&project=P&mode=edit&multiAgentId=agent-1&deployVersion=4", + "api_key": "https://dev.ennoia.so/setting/project/general?group=G&project=P" + }, + "request": { + "method": "POST", + "endpoint": "https://dev-api.ennoia.so/api/llm-orchestrator/chat/stream/agent-1/4", + "headers": { + "apiKey": "${ENNOIA_API_KEY}" + }, + "body": {}, + "response_mode": "sse" + }, + "examples": [ + { + "name": "SSE cURL", + "language": "sh", + "code": "curl --header \"apiKey: ${ENNOIA_API_KEY}\"" + } + ], + "authentication": { + "key_scope": "project", + "api_key_available": true, + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 복사 버튼을 사용하세요." + ] + }, + "response": { + "mode": "sse", + "completion": "terminal event를 확인하세요.", + "approval": "승인 대기는 완료가 아닙니다." + }, + "verification": { + "environment": "dev", + "contract_source": "configured:legacy_sse", + "checked_at": "2026-10-27T01:00:00Z", + "execution_tested": true, + "unknowns": [ + "개인 MCP 인증 미확인", + "실제 실행 미확인" + ] + } + } + } + }, + { + "tool": "deploy_multi_agent", + "kind": "output", + "valid": true, + "value": { + "ok": true, + "data": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "deploy_version": 2, + "status": "R", + "endpoint": "https://api.ennoia.so/api/llm-orchestrator/chat/stream/fixture-agent/2", + "api_key": "synthetic-existing-contract-key", + "started_at": "2026-10-27T01:00:00Z", + "completed_at": "2026-10-27T01:00:01Z", + "group_code": "g-target", + "project_code": "p-target" + } + } + }, + { + "tool": "deploy_multi_agent", + "kind": "output", + "valid": true, + "value": { + "ok": true, + "data": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "deploy_version": 2, + "status": "R", + "endpoint": "https://api.ennoia.so/api/llm-orchestrator/chat/stream/fixture-agent/2", + "api_key": "synthetic-existing-contract-key", + "started_at": "2026-10-27T01:00:00Z", + "completed_at": "2026-10-27T01:00:01Z", + "group_code": "g-target", + "project_code": "p-target", + "usage": { + "multi_agent_id": "agent-1", + "name": "도우미", + "group_code": "G", + "group_name": "그룹", + "project_code": "P", + "project_name": "프로젝트", + "deploy_version": 4, + "stage": "P", + "status": "R", + "availability": "running", + "links": { + "studio": "https://dev.ennoia.so/studio/multi-agent?group=G&project=P", + "deployment": "https://dev.ennoia.so/studio/multi-agent/canvas?group=G&project=P&mode=edit&multiAgentId=agent-1&deployVersion=4", + "api_key": "https://dev.ennoia.so/setting/project/general?group=G&project=P" + }, + "request": { + "method": "POST", + "endpoint": "https://dev-api.ennoia.so/api/llm-orchestrator/chat/stream/agent-1/4", + "headers": { + "apiKey": "${ENNOIA_API_KEY}" + }, + "body": {}, + "response_mode": "sse" + }, + "examples": [ + { + "name": "SSE cURL", + "language": "sh", + "code": "curl --header \"apiKey: ${ENNOIA_API_KEY}\"" + } + ], + "authentication": { + "key_scope": "project", + "api_key_available": true, + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 복사 버튼을 사용하세요." + ] + }, + "response": { + "mode": "sse", + "completion": "terminal event를 확인하세요.", + "approval": "승인 대기는 완료가 아닙니다." + }, + "verification": { + "environment": "dev", + "contract_source": "configured:legacy_sse", + "checked_at": "2026-10-27T01:00:00Z", + "execution_tested": false, + "unknowns": [ + "개인 MCP 인증 미확인", + "실제 실행 미확인" + ] + } + } + } + } + }, + { + "tool": "deploy_multi_agent", + "kind": "output", + "valid": false, + "value": { + "ok": true, + "data": { + "multi_agent_id": "fixture-agent", + "name": "고객응대봇", + "deploy_version": 2, + "status": "R", + "endpoint": "https://api.ennoia.so/api/llm-orchestrator/chat/stream/fixture-agent/2", + "api_key": "synthetic-existing-contract-key", + "started_at": "2026-10-27T01:00:00Z", + "completed_at": "2026-10-27T01:00:01Z", + "group_code": "g-target", + "project_code": "p-target", + "usage": { + "multi_agent_id": "agent-1", + "name": "도우미", + "group_code": "G", + "group_name": "그룹", + "project_code": "P", + "project_name": "프로젝트", + "deploy_version": 4, + "stage": "P", + "status": "R", + "availability": "running", + "links": { + "studio": "https://dev.ennoia.so/studio/multi-agent?group=G&project=P", + "deployment": "https://dev.ennoia.so/studio/multi-agent/canvas?group=G&project=P&mode=edit&multiAgentId=agent-1&deployVersion=4", + "api_key": "https://dev.ennoia.so/setting/project/general?group=G&project=P" + }, + "request": { + "method": "POST", + "endpoint": "https://dev-api.ennoia.so/api/llm-orchestrator/chat/stream/agent-1/4", + "headers": { + "apiKey": "${ENNOIA_API_KEY}" + }, + "body": {}, + "response_mode": "sse" + }, + "examples": [ + { + "name": "SSE cURL", + "language": "sh", + "code": "curl --header \"apiKey: ${ENNOIA_API_KEY}\"" + } + ], + "authentication": { + "key_scope": "deployment", + "api_key_available": true, + "key_environment_variable": "ENNOIA_API_KEY", + "personal_mcp": "unknown", + "instructions": [ + "API KEY 복사 버튼을 사용하세요." + ] + }, + "response": { + "mode": "sse", + "completion": "terminal event를 확인하세요.", + "approval": "승인 대기는 완료가 아닙니다." + }, + "verification": { + "environment": "dev", + "contract_source": "configured:legacy_sse", + "checked_at": "2026-10-27T01:00:00Z", + "execution_tested": false, + "unknowns": [ + "개인 MCP 인증 미확인", + "실제 실행 미확인" + ] + } + } + } + } } ] diff --git a/tests/fixtures/ennoia-tool-contracts.json b/tests/fixtures/ennoia-tool-contracts.json index 4f7b53d..11073e3 100644 --- a/tests/fixtures/ennoia-tool-contracts.json +++ b/tests/fixtures/ennoia-tool-contracts.json @@ -1,6 +1,6 @@ { "source_repository": "wanteddev/ennoia-mcp-server", - "source_revision": "f7f439099b5d7b8a5858750fbff3f495e9d8f0cd", + "source_revision": "0e7bfe76ce64253597c201ff0ad883122fa863b9", "tools": [ { "name": "start_ennoia_conversation", @@ -4232,8 +4232,6 @@ }, { "name": "start_saved_multi_agent_test", - "title": null, - "description": "저장된 D draft를 deploy 없이 Studio 테스트로 실행합니다. 개인 MCP credential은 서버에서 주입합니다.\n\n 실제 project와 draft deploy_version을 확인하고 부작용 가능성을 알린 뒤 사용자가 테스트를 승인한 경우에만\n confirm=true로 호출하세요. configured tool이 외부 변경을 수행할 수 있으며 read-only 보장은 없습니다.\n 같은 operation_id로 재시도하고 반환 test_id를 get_saved_multi_agent_test로 조회하세요. Canvas를 재작성하지 않습니다.", "inputSchema": { "$defs": { "ProjectSelector": { @@ -4778,22 +4776,10 @@ ], "title": "ResultEnvelope[SavedTestResult]", "type": "object" - }, - "icons": null, - "annotations": { - "title": null, - "readOnlyHint": false, - "destructiveHint": true, - "idempotentHint": true, - "openWorldHint": true - }, - "meta": null, - "execution": null + } }, { "name": "get_saved_multi_agent_test", - "title": null, - "description": "저장 draft 테스트의 같은 test_id로 상태와 결과를 조회합니다. 새 실행을 만들지 않습니다.\n\n running과 needs_approval은 완료가 아닙니다. needs_approval이면 사용자 결정 후 반환 approval_id로 재개합니다.", "inputSchema": { "properties": { "test_id": { @@ -5245,22 +5231,10 @@ ], "title": "ResultEnvelope[SavedTestResult]", "type": "object" - }, - "icons": null, - "annotations": { - "title": null, - "readOnlyHint": true, - "destructiveHint": false, - "idempotentHint": true, - "openWorldHint": true - }, - "meta": null, - "execution": null + } }, { "name": "resume_saved_multi_agent_test", - "title": null, - "description": "needs_approval인 저장 draft 테스트를 반환 approval_id와 사용자의 approve/reject 결정으로 재개합니다.\n\n 도구 실행의 부작용과 승인 대상을 사용자가 확인해야 합니다. 모델이 자동 승인하지 않습니다.\n 같은 operation_id를 유지하고 결과가 불명확하면 같은 test_id를 조회하세요.", "inputSchema": { "$defs": { "SavedTestResumeRequest": { @@ -5750,22 +5724,10 @@ ], "title": "ResultEnvelope[SavedTestResult]", "type": "object" - }, - "icons": null, - "annotations": { - "title": null, - "readOnlyHint": false, - "destructiveHint": true, - "idempotentHint": true, - "openWorldHint": true - }, - "meta": null, - "execution": null + } }, { "name": "cancel_saved_multi_agent_test", - "title": null, - "description": "사용자가 취소한 저장 draft 테스트를 중지합니다. 이미 실행한 외부 변경을 되돌리지는 않습니다.\n\n 재시도에는 같은 operation_id를 사용하고 get_saved_multi_agent_test로 최종 상태를 확인하세요.", "inputSchema": { "$defs": { "SavedTestOperation": { @@ -6238,17 +6200,2098 @@ ], "title": "ResultEnvelope[SavedTestResult]", "type": "object" + } + }, + { + "name": "deploy_multi_agent", + "inputSchema": { + "$defs": { + "DeploymentRequest": { + "additionalProperties": false, + "properties": { + "project_scope": { + "$ref": "#/$defs/ProjectSelector" + }, + "multi_agent_id": { + "anyOf": [ + { + "maxLength": 128, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Multi Agent Id" + }, + "name": { + "anyOf": [ + { + "maxLength": 255, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Name" + }, + "keep_previous_running": { + "default": true, + "title": "Keep Previous Running", + "type": "boolean" + }, + "wait_timeout_seconds": { + "default": 120, + "maximum": 300, + "minimum": 1, + "title": "Wait Timeout Seconds", + "type": "integer" + }, + "operation_id": { + "format": "uuid4", + "title": "Operation Id", + "type": "string" + } + }, + "required": [ + "operation_id" + ], + "title": "DeploymentRequest", + "type": "object" + }, + "ProjectSelector": { + "additionalProperties": false, + "properties": { + "scope": { + "default": "current", + "enum": [ + "current", + "specified", + "all" + ], + "title": "Scope", + "type": "string" + }, + "group_code": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Group Code" + }, + "project_code": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Project Code" + } + }, + "title": "ProjectSelector", + "type": "object" + } + }, + "properties": { + "request": { + "$ref": "#/$defs/DeploymentRequest" + } + }, + "required": [ + "request" + ], + "title": "deploy_multi_agentArguments", + "type": "object" }, - "icons": null, - "annotations": { - "title": null, - "readOnlyHint": false, - "destructiveHint": true, - "idempotentHint": true, - "openWorldHint": true - }, - "meta": null, - "execution": null + "outputSchema": { + "$defs": { + "DeploymentResult": { + "additionalProperties": false, + "properties": { + "multi_agent_id": { + "title": "Multi Agent Id", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "deploy_version": { + "minimum": 0, + "title": "Deploy Version", + "type": "integer" + }, + "status": { + "const": "R", + "title": "Status", + "type": "string" + }, + "endpoint": { + "title": "Endpoint", + "type": "string" + }, + "api_key": { + "title": "Api Key", + "type": "string" + }, + "started_at": { + "format": "date-time", + "title": "Started At", + "type": "string" + }, + "completed_at": { + "format": "date-time", + "title": "Completed At", + "type": "string" + }, + "group_code": { + "title": "Group Code", + "type": "string" + }, + "project_code": { + "title": "Project Code", + "type": "string" + }, + "usage": { + "anyOf": [ + { + "$ref": "#/$defs/DeploymentUsage" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "multi_agent_id", + "name", + "deploy_version", + "status", + "endpoint", + "api_key", + "started_at", + "completed_at", + "group_code", + "project_code" + ], + "title": "DeploymentResult", + "type": "object" + }, + "DeploymentUsage": { + "additionalProperties": false, + "properties": { + "multi_agent_id": { + "title": "Multi Agent Id", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "group_code": { + "title": "Group Code", + "type": "string" + }, + "group_name": { + "title": "Group Name", + "type": "string" + }, + "project_code": { + "title": "Project Code", + "type": "string" + }, + "project_name": { + "title": "Project Name", + "type": "string" + }, + "deploy_version": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Deploy Version" + }, + "stage": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Stage" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Status" + }, + "availability": { + "enum": [ + "running", + "unavailable", + "no_deployment", + "unknown" + ], + "title": "Availability", + "type": "string" + }, + "links": { + "$ref": "#/$defs/DeploymentUsageLinks" + }, + "request": { + "anyOf": [ + { + "$ref": "#/$defs/DeploymentUsageHttpRequest" + }, + { + "type": "null" + } + ], + "default": null + }, + "examples": { + "default": [], + "items": { + "$ref": "#/$defs/DeploymentUsageExample" + }, + "title": "Examples", + "type": "array" + }, + "authentication": { + "$ref": "#/$defs/DeploymentUsageAuthentication" + }, + "response": { + "$ref": "#/$defs/DeploymentUsageResponse" + }, + "verification": { + "$ref": "#/$defs/DeploymentUsageVerification" + } + }, + "required": [ + "multi_agent_id", + "name", + "group_code", + "group_name", + "project_code", + "project_name", + "availability", + "links", + "authentication", + "response", + "verification" + ], + "title": "DeploymentUsage", + "type": "object" + }, + "DeploymentUsageAuthentication": { + "additionalProperties": false, + "properties": { + "key_scope": { + "const": "project", + "default": "project", + "title": "Key Scope", + "type": "string" + }, + "api_key_available": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Api Key Available" + }, + "key_environment_variable": { + "const": "ENNOIA_API_KEY", + "default": "ENNOIA_API_KEY", + "title": "Key Environment Variable", + "type": "string" + }, + "personal_mcp": { + "const": "unknown", + "default": "unknown", + "title": "Personal Mcp", + "type": "string" + }, + "instructions": { + "items": { + "type": "string" + }, + "title": "Instructions", + "type": "array" + } + }, + "required": [ + "instructions" + ], + "title": "DeploymentUsageAuthentication", + "type": "object" + }, + "DeploymentUsageExample": { + "additionalProperties": false, + "properties": { + "name": { + "title": "Name", + "type": "string" + }, + "language": { + "const": "sh", + "default": "sh", + "title": "Language", + "type": "string" + }, + "code": { + "title": "Code", + "type": "string" + } + }, + "required": [ + "name", + "code" + ], + "title": "DeploymentUsageExample", + "type": "object" + }, + "DeploymentUsageHttpRequest": { + "additionalProperties": false, + "properties": { + "method": { + "const": "POST", + "default": "POST", + "title": "Method", + "type": "string" + }, + "endpoint": { + "title": "Endpoint", + "type": "string" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "title": "Headers", + "type": "object" + }, + "body": { + "additionalProperties": true, + "title": "Body", + "type": "object" + }, + "response_mode": { + "enum": [ + "json", + "sse" + ], + "title": "Response Mode", + "type": "string" + } + }, + "required": [ + "endpoint", + "headers", + "body", + "response_mode" + ], + "title": "DeploymentUsageHttpRequest", + "type": "object" + }, + "DeploymentUsageLinks": { + "additionalProperties": false, + "properties": { + "studio": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Studio" + }, + "deployment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Deployment" + }, + "api_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Api Key" + } + }, + "title": "DeploymentUsageLinks", + "type": "object" + }, + "DeploymentUsageResponse": { + "additionalProperties": false, + "properties": { + "mode": { + "anyOf": [ + { + "enum": [ + "json", + "sse" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Mode" + }, + "completion": { + "title": "Completion", + "type": "string" + }, + "approval": { + "title": "Approval", + "type": "string" + } + }, + "required": [ + "completion", + "approval" + ], + "title": "DeploymentUsageResponse", + "type": "object" + }, + "DeploymentUsageVerification": { + "additionalProperties": false, + "properties": { + "environment": { + "title": "Environment", + "type": "string" + }, + "contract_source": { + "title": "Contract Source", + "type": "string" + }, + "checked_at": { + "format": "date-time", + "title": "Checked At", + "type": "string" + }, + "execution_tested": { + "const": false, + "default": false, + "title": "Execution Tested", + "type": "boolean" + }, + "unknowns": { + "items": { + "type": "string" + }, + "title": "Unknowns", + "type": "array" + } + }, + "required": [ + "environment", + "contract_source", + "checked_at", + "unknowns" + ], + "title": "DeploymentUsageVerification", + "type": "object" + }, + "ErrorDetail": { + "additionalProperties": false, + "description": "외부에 노출할 수 있는 allowlist error detail.", + "properties": { + "code": { + "title": "Code", + "type": "string" + }, + "message": { + "title": "Message", + "type": "string" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Path" + }, + "node_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Node Id" + }, + "repair_hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Repair Hint" + }, + "next_action": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Next Action" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + }, + "details": { + "anyOf": [ + { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Details" + } + }, + "required": [ + "code", + "message" + ], + "title": "ErrorDetail", + "type": "object" + }, + "ProjectContextTarget": { + "additionalProperties": false, + "properties": { + "group_code": { + "title": "Group Code", + "type": "string" + }, + "group_name": { + "title": "Group Name", + "type": "string" + }, + "project_code": { + "title": "Project Code", + "type": "string" + }, + "project_name": { + "title": "Project Name", + "type": "string" + } + }, + "required": [ + "group_code", + "group_name", + "project_code", + "project_name" + ], + "title": "ProjectContextTarget", + "type": "object" + }, + "ProjectExecutionContext": { + "additionalProperties": false, + "properties": { + "scope": { + "enum": [ + "current", + "specified", + "all" + ], + "title": "Scope", + "type": "string" + }, + "selection_source": { + "enum": [ + "auto_selected", + "user_selected", + "specified", + "all" + ], + "title": "Selection Source", + "type": "string" + }, + "projects": { + "items": { + "$ref": "#/$defs/ProjectContextTarget" + }, + "title": "Projects", + "type": "array" + }, + "requires_confirmation": { + "title": "Requires Confirmation", + "type": "boolean" + }, + "notice": { + "title": "Notice", + "type": "string" + } + }, + "required": [ + "scope", + "selection_source", + "projects", + "requires_confirmation", + "notice" + ], + "title": "ProjectExecutionContext", + "type": "object" + }, + "ProjectSelectionContext": { + "additionalProperties": false, + "description": "실제 실행 대상과 구분되는 요청 시점의 저장된 선택.", + "properties": { + "status": { + "enum": [ + "selected", + "not_selected", + "unavailable" + ], + "title": "Status", + "type": "string" + }, + "project": { + "anyOf": [ + { + "$ref": "#/$defs/SelectedProject" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "status" + ], + "title": "ProjectSelectionContext", + "type": "object" + }, + "SelectedProject": { + "additionalProperties": false, + "properties": { + "group_code": { + "title": "Group Code", + "type": "string" + }, + "group_name": { + "title": "Group Name", + "type": "string" + }, + "project_code": { + "title": "Project Code", + "type": "string" + }, + "project_name": { + "title": "Project Name", + "type": "string" + }, + "selection_source": { + "enum": [ + "auto_selected", + "user_selected" + ], + "title": "Selection Source", + "type": "string" + } + }, + "required": [ + "group_code", + "group_name", + "project_code", + "project_name", + "selection_source" + ], + "title": "SelectedProject", + "type": "object" + } + }, + "additionalProperties": false, + "properties": { + "ok": { + "title": "Ok", + "type": "boolean" + }, + "data": { + "anyOf": [ + { + "$ref": "#/$defs/DeploymentResult" + }, + { + "type": "null" + } + ], + "default": null + }, + "error": { + "anyOf": [ + { + "$ref": "#/$defs/ErrorDetail" + }, + { + "type": "null" + } + ], + "default": null + }, + "project_context": { + "anyOf": [ + { + "$ref": "#/$defs/ProjectExecutionContext" + }, + { + "type": "null" + } + ], + "default": null + }, + "selection_context": { + "anyOf": [ + { + "$ref": "#/$defs/ProjectSelectionContext" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "ok" + ], + "title": "ResultEnvelope[DeploymentResult]", + "type": "object" + } + }, + { + "name": "invoke_deployed_multi_agent", + "inputSchema": { + "$defs": { + "DeploymentInvokeRequest": { + "additionalProperties": false, + "properties": { + "project_scope": { + "$ref": "#/$defs/ProjectSelector" + }, + "multi_agent_id": { + "maxLength": 128, + "minLength": 1, + "title": "Multi Agent Id", + "type": "string" + }, + "deploy_version": { + "minimum": 0, + "title": "Deploy Version", + "type": "integer" + }, + "api_key": { + "anyOf": [ + { + "maxLength": 4096, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Api Key" + }, + "message": { + "maxLength": 20000, + "minLength": 1, + "title": "Message", + "type": "string" + }, + "timeout_seconds": { + "default": 120, + "maximum": 300, + "minimum": 1, + "title": "Timeout Seconds", + "type": "integer" + } + }, + "required": [ + "multi_agent_id", + "deploy_version", + "message" + ], + "title": "DeploymentInvokeRequest", + "type": "object" + }, + "ProjectSelector": { + "additionalProperties": false, + "properties": { + "scope": { + "default": "current", + "enum": [ + "current", + "specified", + "all" + ], + "title": "Scope", + "type": "string" + }, + "group_code": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Group Code" + }, + "project_code": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Project Code" + } + }, + "title": "ProjectSelector", + "type": "object" + } + }, + "properties": { + "request": { + "$ref": "#/$defs/DeploymentInvokeRequest" + } + }, + "required": [ + "request" + ], + "title": "invoke_deployed_multi_agentArguments", + "type": "object" + }, + "outputSchema": { + "$defs": { + "DeploymentInvokeResult": { + "additionalProperties": false, + "properties": { + "content": { + "title": "Content", + "type": "string" + }, + "finish_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Finish Reason" + }, + "usage": { + "anyOf": [ + { + "additionalProperties": { + "type": "integer" + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Usage" + }, + "trace_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Trace Id" + }, + "elapsed_ms": { + "minimum": 0, + "title": "Elapsed Ms", + "type": "integer" + } + }, + "required": [ + "content", + "elapsed_ms" + ], + "title": "DeploymentInvokeResult", + "type": "object" + }, + "ErrorDetail": { + "additionalProperties": false, + "description": "외부에 노출할 수 있는 allowlist error detail.", + "properties": { + "code": { + "title": "Code", + "type": "string" + }, + "message": { + "title": "Message", + "type": "string" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Path" + }, + "node_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Node Id" + }, + "repair_hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Repair Hint" + }, + "next_action": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Next Action" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + }, + "details": { + "anyOf": [ + { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Details" + } + }, + "required": [ + "code", + "message" + ], + "title": "ErrorDetail", + "type": "object" + }, + "ProjectContextTarget": { + "additionalProperties": false, + "properties": { + "group_code": { + "title": "Group Code", + "type": "string" + }, + "group_name": { + "title": "Group Name", + "type": "string" + }, + "project_code": { + "title": "Project Code", + "type": "string" + }, + "project_name": { + "title": "Project Name", + "type": "string" + } + }, + "required": [ + "group_code", + "group_name", + "project_code", + "project_name" + ], + "title": "ProjectContextTarget", + "type": "object" + }, + "ProjectExecutionContext": { + "additionalProperties": false, + "properties": { + "scope": { + "enum": [ + "current", + "specified", + "all" + ], + "title": "Scope", + "type": "string" + }, + "selection_source": { + "enum": [ + "auto_selected", + "user_selected", + "specified", + "all" + ], + "title": "Selection Source", + "type": "string" + }, + "projects": { + "items": { + "$ref": "#/$defs/ProjectContextTarget" + }, + "title": "Projects", + "type": "array" + }, + "requires_confirmation": { + "title": "Requires Confirmation", + "type": "boolean" + }, + "notice": { + "title": "Notice", + "type": "string" + } + }, + "required": [ + "scope", + "selection_source", + "projects", + "requires_confirmation", + "notice" + ], + "title": "ProjectExecutionContext", + "type": "object" + }, + "ProjectSelectionContext": { + "additionalProperties": false, + "description": "실제 실행 대상과 구분되는 요청 시점의 저장된 선택.", + "properties": { + "status": { + "enum": [ + "selected", + "not_selected", + "unavailable" + ], + "title": "Status", + "type": "string" + }, + "project": { + "anyOf": [ + { + "$ref": "#/$defs/SelectedProject" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "status" + ], + "title": "ProjectSelectionContext", + "type": "object" + }, + "SelectedProject": { + "additionalProperties": false, + "properties": { + "group_code": { + "title": "Group Code", + "type": "string" + }, + "group_name": { + "title": "Group Name", + "type": "string" + }, + "project_code": { + "title": "Project Code", + "type": "string" + }, + "project_name": { + "title": "Project Name", + "type": "string" + }, + "selection_source": { + "enum": [ + "auto_selected", + "user_selected" + ], + "title": "Selection Source", + "type": "string" + } + }, + "required": [ + "group_code", + "group_name", + "project_code", + "project_name", + "selection_source" + ], + "title": "SelectedProject", + "type": "object" + } + }, + "additionalProperties": false, + "properties": { + "ok": { + "title": "Ok", + "type": "boolean" + }, + "data": { + "anyOf": [ + { + "$ref": "#/$defs/DeploymentInvokeResult" + }, + { + "type": "null" + } + ], + "default": null + }, + "error": { + "anyOf": [ + { + "$ref": "#/$defs/ErrorDetail" + }, + { + "type": "null" + } + ], + "default": null + }, + "project_context": { + "anyOf": [ + { + "$ref": "#/$defs/ProjectExecutionContext" + }, + { + "type": "null" + } + ], + "default": null + }, + "selection_context": { + "anyOf": [ + { + "$ref": "#/$defs/ProjectSelectionContext" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "ok" + ], + "title": "ResultEnvelope[DeploymentInvokeResult]", + "type": "object" + } + }, + { + "name": "get_multi_agent_deployment_usage", + "inputSchema": { + "$defs": { + "DeploymentUsageRequest": { + "additionalProperties": false, + "properties": { + "project_scope": { + "$ref": "#/$defs/UsageProjectSelector" + }, + "multi_agent_id": { + "maxLength": 128, + "minLength": 1, + "title": "Multi Agent Id", + "type": "string" + }, + "deploy_version": { + "anyOf": [ + { + "minimum": 0, + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Deploy Version" + } + }, + "required": [ + "multi_agent_id" + ], + "title": "DeploymentUsageRequest", + "type": "object" + }, + "UsageProjectSelector": { + "additionalProperties": false, + "properties": { + "scope": { + "default": "current", + "enum": [ + "current", + "specified" + ], + "title": "Scope", + "type": "string" + }, + "group_code": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Group Code" + }, + "project_code": { + "anyOf": [ + { + "maxLength": 100, + "minLength": 1, + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Project Code" + } + }, + "title": "UsageProjectSelector", + "type": "object" + } + }, + "properties": { + "request": { + "$ref": "#/$defs/DeploymentUsageRequest" + } + }, + "required": [ + "request" + ], + "title": "get_multi_agent_deployment_usageArguments", + "type": "object" + }, + "outputSchema": { + "$defs": { + "DeploymentUsage": { + "additionalProperties": false, + "properties": { + "multi_agent_id": { + "title": "Multi Agent Id", + "type": "string" + }, + "name": { + "title": "Name", + "type": "string" + }, + "group_code": { + "title": "Group Code", + "type": "string" + }, + "group_name": { + "title": "Group Name", + "type": "string" + }, + "project_code": { + "title": "Project Code", + "type": "string" + }, + "project_name": { + "title": "Project Name", + "type": "string" + }, + "deploy_version": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Deploy Version" + }, + "stage": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Stage" + }, + "status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Status" + }, + "availability": { + "enum": [ + "running", + "unavailable", + "no_deployment", + "unknown" + ], + "title": "Availability", + "type": "string" + }, + "links": { + "$ref": "#/$defs/DeploymentUsageLinks" + }, + "request": { + "anyOf": [ + { + "$ref": "#/$defs/DeploymentUsageHttpRequest" + }, + { + "type": "null" + } + ], + "default": null + }, + "examples": { + "default": [], + "items": { + "$ref": "#/$defs/DeploymentUsageExample" + }, + "title": "Examples", + "type": "array" + }, + "authentication": { + "$ref": "#/$defs/DeploymentUsageAuthentication" + }, + "response": { + "$ref": "#/$defs/DeploymentUsageResponse" + }, + "verification": { + "$ref": "#/$defs/DeploymentUsageVerification" + } + }, + "required": [ + "multi_agent_id", + "name", + "group_code", + "group_name", + "project_code", + "project_name", + "availability", + "links", + "authentication", + "response", + "verification" + ], + "title": "DeploymentUsage", + "type": "object" + }, + "DeploymentUsageAuthentication": { + "additionalProperties": false, + "properties": { + "key_scope": { + "const": "project", + "default": "project", + "title": "Key Scope", + "type": "string" + }, + "api_key_available": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Api Key Available" + }, + "key_environment_variable": { + "const": "ENNOIA_API_KEY", + "default": "ENNOIA_API_KEY", + "title": "Key Environment Variable", + "type": "string" + }, + "personal_mcp": { + "const": "unknown", + "default": "unknown", + "title": "Personal Mcp", + "type": "string" + }, + "instructions": { + "items": { + "type": "string" + }, + "title": "Instructions", + "type": "array" + } + }, + "required": [ + "instructions" + ], + "title": "DeploymentUsageAuthentication", + "type": "object" + }, + "DeploymentUsageExample": { + "additionalProperties": false, + "properties": { + "name": { + "title": "Name", + "type": "string" + }, + "language": { + "const": "sh", + "default": "sh", + "title": "Language", + "type": "string" + }, + "code": { + "title": "Code", + "type": "string" + } + }, + "required": [ + "name", + "code" + ], + "title": "DeploymentUsageExample", + "type": "object" + }, + "DeploymentUsageHttpRequest": { + "additionalProperties": false, + "properties": { + "method": { + "const": "POST", + "default": "POST", + "title": "Method", + "type": "string" + }, + "endpoint": { + "title": "Endpoint", + "type": "string" + }, + "headers": { + "additionalProperties": { + "type": "string" + }, + "title": "Headers", + "type": "object" + }, + "body": { + "additionalProperties": true, + "title": "Body", + "type": "object" + }, + "response_mode": { + "enum": [ + "json", + "sse" + ], + "title": "Response Mode", + "type": "string" + } + }, + "required": [ + "endpoint", + "headers", + "body", + "response_mode" + ], + "title": "DeploymentUsageHttpRequest", + "type": "object" + }, + "DeploymentUsageLinks": { + "additionalProperties": false, + "properties": { + "studio": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Studio" + }, + "deployment": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Deployment" + }, + "api_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Api Key" + } + }, + "title": "DeploymentUsageLinks", + "type": "object" + }, + "DeploymentUsageResponse": { + "additionalProperties": false, + "properties": { + "mode": { + "anyOf": [ + { + "enum": [ + "json", + "sse" + ], + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Mode" + }, + "completion": { + "title": "Completion", + "type": "string" + }, + "approval": { + "title": "Approval", + "type": "string" + } + }, + "required": [ + "completion", + "approval" + ], + "title": "DeploymentUsageResponse", + "type": "object" + }, + "DeploymentUsageVerification": { + "additionalProperties": false, + "properties": { + "environment": { + "title": "Environment", + "type": "string" + }, + "contract_source": { + "title": "Contract Source", + "type": "string" + }, + "checked_at": { + "format": "date-time", + "title": "Checked At", + "type": "string" + }, + "execution_tested": { + "const": false, + "default": false, + "title": "Execution Tested", + "type": "boolean" + }, + "unknowns": { + "items": { + "type": "string" + }, + "title": "Unknowns", + "type": "array" + } + }, + "required": [ + "environment", + "contract_source", + "checked_at", + "unknowns" + ], + "title": "DeploymentUsageVerification", + "type": "object" + }, + "ErrorDetail": { + "additionalProperties": false, + "description": "외부에 노출할 수 있는 allowlist error detail.", + "properties": { + "code": { + "title": "Code", + "type": "string" + }, + "message": { + "title": "Message", + "type": "string" + }, + "path": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Path" + }, + "node_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Node Id" + }, + "repair_hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Repair Hint" + }, + "next_action": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Next Action" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + }, + "details": { + "anyOf": [ + { + "additionalProperties": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "integer" + } + ] + }, + "type": "object" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Details" + } + }, + "required": [ + "code", + "message" + ], + "title": "ErrorDetail", + "type": "object" + }, + "ProjectContextTarget": { + "additionalProperties": false, + "properties": { + "group_code": { + "title": "Group Code", + "type": "string" + }, + "group_name": { + "title": "Group Name", + "type": "string" + }, + "project_code": { + "title": "Project Code", + "type": "string" + }, + "project_name": { + "title": "Project Name", + "type": "string" + } + }, + "required": [ + "group_code", + "group_name", + "project_code", + "project_name" + ], + "title": "ProjectContextTarget", + "type": "object" + }, + "ProjectExecutionContext": { + "additionalProperties": false, + "properties": { + "scope": { + "enum": [ + "current", + "specified", + "all" + ], + "title": "Scope", + "type": "string" + }, + "selection_source": { + "enum": [ + "auto_selected", + "user_selected", + "specified", + "all" + ], + "title": "Selection Source", + "type": "string" + }, + "projects": { + "items": { + "$ref": "#/$defs/ProjectContextTarget" + }, + "title": "Projects", + "type": "array" + }, + "requires_confirmation": { + "title": "Requires Confirmation", + "type": "boolean" + }, + "notice": { + "title": "Notice", + "type": "string" + } + }, + "required": [ + "scope", + "selection_source", + "projects", + "requires_confirmation", + "notice" + ], + "title": "ProjectExecutionContext", + "type": "object" + }, + "ProjectSelectionContext": { + "additionalProperties": false, + "description": "실제 실행 대상과 구분되는 요청 시점의 저장된 선택.", + "properties": { + "status": { + "enum": [ + "selected", + "not_selected", + "unavailable" + ], + "title": "Status", + "type": "string" + }, + "project": { + "anyOf": [ + { + "$ref": "#/$defs/SelectedProject" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "status" + ], + "title": "ProjectSelectionContext", + "type": "object" + }, + "SelectedProject": { + "additionalProperties": false, + "properties": { + "group_code": { + "title": "Group Code", + "type": "string" + }, + "group_name": { + "title": "Group Name", + "type": "string" + }, + "project_code": { + "title": "Project Code", + "type": "string" + }, + "project_name": { + "title": "Project Name", + "type": "string" + }, + "selection_source": { + "enum": [ + "auto_selected", + "user_selected" + ], + "title": "Selection Source", + "type": "string" + } + }, + "required": [ + "group_code", + "group_name", + "project_code", + "project_name", + "selection_source" + ], + "title": "SelectedProject", + "type": "object" + } + }, + "additionalProperties": false, + "properties": { + "ok": { + "title": "Ok", + "type": "boolean" + }, + "data": { + "anyOf": [ + { + "$ref": "#/$defs/DeploymentUsage" + }, + { + "type": "null" + } + ], + "default": null + }, + "error": { + "anyOf": [ + { + "$ref": "#/$defs/ErrorDetail" + }, + { + "type": "null" + } + ], + "default": null + }, + "project_context": { + "anyOf": [ + { + "$ref": "#/$defs/ProjectExecutionContext" + }, + { + "type": "null" + } + ], + "default": null + }, + "selection_context": { + "anyOf": [ + { + "$ref": "#/$defs/ProjectSelectionContext" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "ok" + ], + "title": "ResultEnvelope[DeploymentUsage]", + "type": "object" + } } ] } diff --git a/tests/fixtures/ennoia-tools.json b/tests/fixtures/ennoia-tools.json index 2688818..8b2b3cf 100644 --- a/tests/fixtures/ennoia-tools.json +++ b/tests/fixtures/ennoia-tools.json @@ -1,6 +1,6 @@ { "source_repository": "wanteddev/ennoia-mcp-server", - "source_revision": "f7f439099b5d7b8a5858750fbff3f495e9d8f0cd", + "source_revision": "0e7bfe76ce64253597c201ff0ad883122fa863b9", "tools": [ "add_ennoia_mcp_server", "cancel_saved_multi_agent_test", @@ -28,6 +28,7 @@ "get_mcp_registration_status", "get_multi_agent", "get_multi_agent_capabilities", + "get_multi_agent_deployment_usage", "get_multi_agent_edge_schema", "get_multi_agent_mcp_tool_schema", "get_multi_agent_node_prompts",