ken-jo/meeting
v0.10.0
회의 녹음·음성 전사(STT)·요약 생성 익스텐션. 녹음 시작/중지, 실시간 오디오 청크 전사(OpenAI Whisper), AI 요약·하이라이트·액션 아이템 자동 추출. 액션 아이템은 meeting.summary.created 이벤트의 actionItems 페이로드로 broadcast 되며, 요약은 로컬 SessionStore(JSON)에 영속화. MS Teams·Zoom 등 회의 후처리 지원.
plugin.json
- name
- meeting
- version
- 0.10.0
- description
- 회의 녹음·음성 전사(STT)·요약 생성 익스텐션. 녹음 시작/중지, 실시간 오디오 청크 전사(OpenAI Whisper), AI 요약·하이라이트·액션 아이템 자동 추출. 액션 아이템은 meeting.summary.created 이벤트의 actionItems 페이로드로 broadcast 되며, 요약은 로컬 SessionStore(JSON)에 영속화. MS Teams·Zoom 등 회의 후처리 지원.
- extensions
- xyz.lvisai
plugin.json
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "meeting",
"version": "0.10.0",
"description": "회의 녹음·음성 전사(STT)·요약 생성 익스텐션. 녹음 시작/중지, 실시간 오디오 청크 전사(OpenAI Whisper), AI 요약·하이라이트·액션 아이템 자동 추출. 액션 아이템은 meeting.summary.created 이벤트의 actionItems 페이로드로 broadcast 되며, 요약은 로컬 SessionStore(JSON)에 영속화. MS Teams·Zoom 등 회의 후처리 지원.",
"extensions": {
"xyz.lvisai": {
"displayName": "Ave Meeting",
"packageName": "@lvis/plugin-meeting",
"llmKeySource": "host",
"entry": "dist/hostPlugin.js",
"onboarding": {
"firstTask": {
"priority": 10,
"locales": {
"en": {
"headline": "Capture your first meeting",
"body": "Start a recording to turn the conversation into a transcript, summary, highlights, and action items.",
"actionLabel": "Prepare a meeting recording",
"composerPrompt": "Help me start recording a meeting and create meeting notes"
},
"ko": {
"headline": "첫 회의를 기록해 보세요",
"body": "녹음을 시작하면 대화를 전사하고 요약, 하이라이트, 액션 아이템으로 정리할 수 있습니다.",
"actionLabel": "회의 녹음 준비",
"composerPrompt": "회의 녹음을 시작하고 회의록을 만드는 방법을 알려줘"
}
}
}
},
"tools": [
{
"name": "meeting_start",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n녹음 시작 tool입니다. 회의가 시작되거나 사용자가 녹음을 요청할 때 호출합니다. floating recorder 창을 열고 마이크/시스템 오디오 캡처, STT 파이프라인을 시작합니다. 사용 시기: 사용자가 '녹음 시작해줘', '회의록 받아줘', '회의 녹음해줘'라고 할 때. 별도로 batch_processing_audio 를 호출하지 마세요. 종료는 사용자가 Done 을 누르거나 meeting_stop 을 호출합니다. 이 tool 은 예정 회의를 등록하지 않으므로, 일정 저장은 register/open_prep 계열을 사용하세요. 반환: { ok, reused }.",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "회의 세션 고유 식별자 (UUID 권장)"
},
"context": {
"type": "object",
"description": "회의 메타데이터 (제목·참석자·예정시간·화상회의 링크 등). 모든 필드 optional. lengthTier 도 여기에 넣어 전달 가능.",
"additionalProperties": true
},
"lengthTier": {
"type": "string",
"enum": [
"short",
"medium",
"long"
],
"description": "회의록 분량 미리 결정 (생략 시 전역 default). meeting_stop 호출 시 별도 override 안 하면 이 값이 사용됨."
}
},
"required": [
"sessionId"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "batch_processing_audio",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n내부/고급용: 이미 확보한 오디오를 PCM 청크로 나눠 전사·요약하는 배치 처리 세션을 초기화합니다. 일반 사용자의 '녹음 시작', '회의록 받아줘' 요청에는 사용하지 말고 meeting_start 를 사용하세요. 이 tool 은 플로팅 창, 마이크, 시스템 오디오 캡처를 열지 않습니다. 사용 시기: 외부 시스템이나 UI 대용량 업로드 경로가 자체 오디오 소스를 가지고 meeting_push_chunk 로 PCM 청크를 직접 보낼 때. 입력: sessionId, context?. 반환: { sessionId, started, mode, sampleRate }.",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "회의 세션 고유 식별자 (UUID 권장)"
},
"context": {
"type": "object",
"description": "회의 메타데이터 (제목, 참석자 등 선택 정보)",
"properties": {
"title": {
"type": "string",
"description": "회의 제목"
},
"participants": {
"type": "array",
"items": {
"type": "string"
},
"description": "참석자 이름 목록"
}
},
"additionalProperties": true
}
},
"required": [
"sessionId"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_push_chunk",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n내부 전용: 이미 시작된 회의 세션에 PCM16LE 모노 오디오 청크를 추가합니다. 사용자 자연어 요청에서 직접 호출하지 않습니다. 사용 시기: batch_processing_audio 로 만든 세션에 외부 캡처 루프가 raw PCM 을 흘려보낼 때. 일반 녹음은 meeting_start 가 플로팅 창에서 캡처와 push 를 자동 처리합니다. 반환: { sessionId, mode: \"batch\", added }.",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "오디오를 전송할 회의 세션 ID"
},
"chunk": {
"type": "object",
"description": "PCM16LE 모노 오디오 청크",
"properties": {
"pcm16leMono": {
"type": "array",
"items": {
"type": "integer",
"minimum": -32768,
"maximum": 32767
},
"description": "16비트 부호 정수 PCM 샘플 배열"
},
"sampleRate": {
"type": "integer",
"description": "샘플링 레이트 (Hz), 예: 16000"
},
"startSec": {
"type": "number",
"description": "청크 시작 시각 (세션 시작 기준 초)"
},
"endSec": {
"type": "number",
"description": "청크 종료 시각 (세션 시작 기준 초)"
}
},
"required": [
"pcm16leMono",
"sampleRate",
"startSec",
"endSec"
],
"additionalProperties": false
}
},
"required": [
"sessionId",
"chunk"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_stop",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n진행 중인 녹음 세션을 종료하고 최종 회의록을 생성합니다. 사용 시기: 사용자가 '회의 끝났어', '녹음 중지', '회의록 만들어줘'라고 할 때. 사용하지 말 것: 요약 없이 버릴 때는 meeting_cancel, 이미 끝난 회의록만 조회할 때는 meeting_session_detail. lengthTier 로 회의록 길이를 조정할 수 있습니다. 반환: { title, summary, highlights, actionItems, createdAt, lengthTier }.",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "종료할 회의 세션 ID"
},
"lengthTier": {
"type": "string",
"enum": [
"short",
"medium",
"long"
],
"description": "회의록 분량(생략 시 전역 default 사용). short=1-2문장, medium=3-5문장, long=5-10문장+상세."
}
},
"required": [
"sessionId"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_transcript",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n특정 녹음 세션의 전체 전사 텍스트를 시간순으로 조회합니다. 사용 시기: '그 회의에서 누가 뭐라고 했지?', '몇 분쯤 나온 발언이야?'처럼 원문/타임스탬프가 필요할 때. 요약만 필요하면 meeting_session_detail 을 사용하세요. 반환: TranscriptSegment[].",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "전사를 조회할 회의 세션 ID"
}
},
"required": [
"sessionId"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_sessions",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n완료된 회의록 목록을 가져옵니다. 사용 시기: 사용자가 '최근 회의록 보여줘', '지난 회의 목록'처럼 어떤 회의록을 볼지 고르려 할 때. 본문 전사/요약은 포함하지 않으므로, 사용자가 특정 항목을 고르면 meeting_session_detail 을 이어서 호출하세요. 반환: SessionMetadata[].",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_previous_sessions",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n이전 완료 회의록을 조회합니다. 사용 시기: 사용자가 '이 회의 이전 회의 찾아줘', '지난번 같은 카테고리 회의 보여줘'라고 할 때. sessionId 를 주면 해당 회의보다 이전 createdAt 기준으로 찾고, beforeCreatedAt/category/limit 으로도 필터링할 수 있습니다. 반환: SessionMetadata[].",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "기준 회의 sessionId. 제공하면 이 회의보다 이전 회의만 반환합니다."
},
"beforeCreatedAt": {
"type": "string",
"description": "ISO 날짜/시간. sessionId 가 없을 때 이 시각 이전의 회의를 조회합니다."
},
"category": {
"type": "string",
"description": "선택 카테고리 필터. 예: 일반, 프로젝트, 정기회의, 1:1, 고객/외부."
},
"limit": {
"type": "number",
"description": "반환할 최대 개수. 기본 20, 최대 100."
}
},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_sessions_by_category",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n카테고리별 완료 회의록을 조회합니다. 사용 시기: 사용자가 '프로젝트 카테고리 회의 보여줘', '1:1 회의록만 찾아줘'라고 할 때. 카테고리는 필수이며 비어 있으면 사용자에게 먼저 어떤 카테고리로 조회할지 물어보세요. 반환: SessionMetadata[] 또는 { ok:false, needsCategorySelection, categories }.",
"inputSchema": {
"type": "object",
"properties": {
"category": {
"type": "string",
"description": "조회할 카테고리. 예: 일반, 프로젝트, 정기회의, 1:1, 고객/외부."
},
"limit": {
"type": "number",
"description": "반환할 최대 개수. 기본 20, 최대 100."
}
},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_categories",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n등록된 회의 카테고리 목록을 조회합니다. 사용 시기: 다른 익스텐션이 새 회의 카테고리를 등록하려 하거나 사용자가 카테고리를 고르려 할 때. 새 카테고리를 바로 만들지 말고 먼저 이 tool 로 기존 목록을 보여준 뒤 사용자 확인 후 meeting_register_category 를 호출하세요. 반환: { categories }.",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_register_category",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n새 회의 카테고리를 등록합니다. 사용 시기: meeting_categories 로 기존 카테고리를 조회한 뒤 사용자가 새 카테고리 등록을 명확히 승인했을 때만 호출하세요. 예약 회의 등록 중 unknownCategories 응답을 받으면 이 tool 로 카테고리를 등록한 뒤 다시 예약 회의를 등록합니다. 반환: { ok, category, categories }.",
"inputSchema": {
"type": "object",
"properties": {
"category": {
"type": "string",
"description": "등록할 새 회의 카테고리 이름"
}
},
"required": [
"category"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_session_detail",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n완료된 회의록 1건의 상세 데이터를 조회합니다. 사용 시기: 사용자가 목록에서 회의록을 골랐거나 '그 회의록 자세히 보여줘'라고 할 때. 요약, 중간 요약, 전체 전사를 한 번에 반환합니다. 존재하지 않으면 null. 반환: { sessionId, context, transcript, intermediateSummaries, finalSummary, finalized, createdAt, updatedAt }.",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "조회할 회의 세션 ID"
}
},
"required": [
"sessionId"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_related_sessions",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n완료된 회의록 1건에 연결된 관련 회의 목록을 조회합니다. 사용 시기: 사용자가 '이 회의랑 이어진 회의 보여줘', '관련 회의 뭐가 있어?'라고 할 때. 회의를 새로 연결하려면 meeting_link_sessions 를 사용하세요. 반환: SessionMetadata[].",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "관련 회의를 조회할 기준 회의 sessionId"
}
},
"required": [
"sessionId"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_upload_file",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n이미 녹음된 오디오/비디오 파일로 회의록을 생성합니다. 사용 시기: 사용자가 mp3, wav, m4a, mp4, webm, ogg, flac 파일을 주며 '이 파일로 회의록 만들어줘'라고 할 때. 실시간 녹음 세션에는 사용하지 않습니다. 파일은 25MB 이하가 권장됩니다. 반환: { sessionId, transcript, finalSummary }.",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "회의 세션 고유 식별자 (UUID 권장)"
},
"context": {
"type": "object",
"description": "회의 메타데이터 (제목, 참석자, webexUrl, agenda 등). lengthTier 도 여기에 넣어 전달 가능.",
"additionalProperties": true
},
"lengthTier": {
"type": "string",
"enum": [
"short",
"medium",
"long"
],
"description": "회의록 분량 (생략 시 context.lengthTier → configSchema.summaryLengthTier 순으로 fallback). short=1-2문장, medium=3-5문장, long=5-10문장+상세."
},
"file": {
"type": "object",
"description": "업로드할 오디오/비디오 파일",
"properties": {
"name": {
"type": "string",
"description": "원본 파일명 (확장자 포함)"
},
"mimeType": {
"type": "string",
"description": "MIME 타입 (audio/mpeg, audio/wav, video/mp4 등). 비어 있으면 파일명 확장자로 추정."
},
"bytesBase64": {
"type": "string",
"description": "파일 바이트 base64 인코딩 문자열"
}
},
"required": [
"name",
"bytesBase64"
],
"additionalProperties": false
}
},
"required": [
"sessionId",
"file"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_open_prep",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n회의 시작 직전에 회의 전 안내 카드 1건을 저장하고 즉시 사이드바에 표시합니다. context.category 는 필수입니다. 카테고리가 없으면 저장하지 않고 needsCategorySelection 을 반환하므로 사용자에게 카테고리를 물어본 뒤 다시 호출하세요. 사용자가 '녹음 시작해줘'라고 요청한 경우에는 이 tool 이 아니라 meeting_start 를 사용하세요. 이 tool 은 녹음을 시작하지 않고 캘린더 일정도 만들지 않습니다. 반환: { ok, contextId }.",
"inputSchema": {
"type": "object",
"properties": {
"context": {
"type": "object",
"description": "사이드바에 표시할 회의 전 안내 정보. 예: title, organizer, participants, scheduledStart, scheduledEnd, location, conference, agenda, previousSummary.",
"additionalProperties": true
}
},
"required": [
"context"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_register_manual_meeting",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n사용자가 채팅에서 직접 말한 예정 미팅 1건을 등록합니다. 사용 시기: '오늘 3시에 로봇 싱크 등록해줘', '참석자는 지수, 민재야'처럼 title/time/participants 를 사용자가 직접 제공할 때. category 와 회의 안건 (agenda 또는 agendaText 중 하나) 은 필수입니다. 사용자가 카테고리·안건을 말하지 않았다면 이 tool 을 호출하기 전에 먼저 물어보세요. previousSummary (이전 회의 요약) 은 선택 — 같은 주제의 직전 회의가 있으면 함께 등록해서 회의 전 안내 카드에 'previous meeting' 으로 표시됩니다. 이미 캘린더/회의실/화상회의 시스템에서 만들어진 일정 1건을 가져오는 경우는 meeting_register_scheduled_meeting 을 사용하세요. 이 tool 은 녹음을 시작하지 않고 원본 캘린더 일정도 만들지 않습니다. 반환: { ok, id, source: 'manual', focusInUi }.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "선택 stable id. 생략하면 title, scheduledStart, organizer 등으로 결정적 id 를 생성합니다."
},
"title": {
"type": "string",
"description": "필수. 사용자가 말한 미팅 제목."
},
"scheduledStart": {
"type": "string",
"description": "필수. 시작 시각. ISO-8601 timezone 포함 권장. 예: 2026-05-20T15:00:00+09:00."
},
"scheduledEnd": {
"type": "string",
"description": "선택. 종료 시각. 생략해도 upcoming list 에 표시됩니다."
},
"organizer": {
"type": "string",
"description": "선택. 주최자 표시 이름."
},
"location": {
"type": "string",
"description": "선택. 회의 장소 또는 회의실명."
},
"description": {
"type": "string",
"description": "선택. 회의 설명, 초대 본문, 메모."
},
"category": {
"type": "string",
"description": "필수. 회의 카테고리. 기존 카테고리와 맞으면 해당 카테고리의 최근 회의록 요약이 회의 전 안내에 자동 표시됩니다. 값이 없으면 사용자에게 반드시 물어보세요. 새 카테고리라면 먼저 meeting_categories 로 조회한 뒤 meeting_register_category 로 등록해야 합니다."
},
"participants": {
"type": "array",
"items": {
"type": "string"
},
"description": "선택. 참석자 표시 이름 배열."
},
"agenda": {
"type": "array",
"items": {
"type": "string",
"maxLength": 512
},
"minItems": 1,
"maxItems": 50,
"description": "필수. UI의 '오늘 회의 안건'에 표시할 회의 안건 배열. 최소 1개, 최대 50개. agendaText / agendaItems / meetingAgenda / todayAgenda 도 받지만 가능하면 agenda 배열로 전달하세요."
},
"agendaText": {
"type": "string",
"minLength": 1,
"maxLength": 8192,
"description": "선택. agenda 미제공 시 줄바꿈/bullet 텍스트를 자동 split. agenda 가 제공되면 무시."
},
"previousSummary": {
"type": "object",
"description": "선택. 같은 주제의 직전 회의 요약. UI 의 회의 전 안내 카드에 'previous meeting' 으로 표시. 사용자가 명시적으로 알려준 경우만 첨부 — 자동으로 추측하지 마세요. 이미 등록된 같은 카테고리 과거 회의 요약은 자동 첨부되지 않으므로 사용자가 명시한 텍스트만 사용.",
"properties": {
"title": {
"type": "string",
"minLength": 1,
"maxLength": 256,
"description": "선택. 이전 회의 제목."
},
"summary": {
"type": "string",
"minLength": 1,
"maxLength": 16384,
"description": "필수. 이전 회의 요약 텍스트."
}
},
"required": [
"summary"
],
"additionalProperties": false
},
"conference": {
"type": "object",
"description": "선택. 사용자가 참여 링크나 접속 정보를 함께 제공했을 때의 화상회의 정보.",
"properties": {
"type": {
"type": "string",
"enum": [
"webex",
"zoom",
"teams",
"other"
]
},
"joinUrl": {
"type": "string"
},
"accessCode": {
"type": "string"
},
"password": {
"type": "string"
},
"hostDisplayName": {
"type": "string"
}
},
"additionalProperties": false
},
"focusInUi": {
"type": "boolean",
"description": "기본 true. false 면 저장만 하고 현재 회의 전 안내 카드로 전환하지 않습니다."
}
},
"required": [
"title",
"scheduledStart",
"category",
"agenda"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model"
]
}
}
},
{
"name": "meeting_register_scheduled_meeting",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관. 사용 시기: 사용자가 명시적으로 '미팅 익스텐션에 등록', '녹음할 예정 회의로 요청', 회의실 예약/화상회의 생성/캘린더 이벤트 생성 직후 그 결과를 미팅 익스텐션에도 등록하라고 '요청한 경우'에만 호출합니다. 호출 금지: 사용자가 단순히 회의 관련 메일/캘린더 내용을 보여주거나, 메일 요약/질문/답장 작성만 요청한 경우. 회의 관련 메일이 있다는 이유만으로 자동 호출하지 마세요. 입력은 context, event, 또는 title/scheduledStart 같은 top-level 회의 필드 중 편한 형태로 전달할 수 있으며, 회의 category 와 회의 안건(agenda/agendaText, 또는 사용자가 등록하라고 지정한 원문 안건 섹션)이 반드시 필요합니다. 회의 정보가 전혀 없거나 등록 의사가 불명확하면 이 tool 을 호출하지 말고 사용자에게 먼저 물어보세요. category 가 없으면 저장하지 않고 { ok:false, needsCategorySelection, categories, suggestions } 를 반환하므로 사용자에게 카테고리를 물어본 뒤 다시 호출하세요. agenda 를 찾지 못하면 { ok:false, needsAgenda } 를 반환하므로 메일 내용이나 지난 회의 후속 조치에서 안건을 확보해 다시 호출하세요. Webex 회의로 보이면 webexUrl 또는 conference.joinUrl 도 반드시 전달하세요. 새 카테고리라면 meeting_categories 로 기존 목록을 보여주고 사용자 확인 후 meeting_register_category 를 먼저 호출하세요. 참석자는 선택 정보입니다. 권장 사용자 문구: \"해당 미팅에 대해 녹음을 진행하실 거라면, 미팅 익스텐션에도 일정을 등록해두겠습니다.\" 이 tool 은 원본 일정 생성도 녹음 시작도 하지 않습니다. 반환: { ok, id, source, focusInUi }.",
"inputSchema": {
"type": "object",
"properties": {
"context": {
"type": "object",
"description": "선택. 저장할 예정 회의 정보. 예: title, organizer, participants, scheduledStart, scheduledEnd, location, conference, agenda, previousSummary. agenda 는 필수이며, Webex 회의라면 conference.joinUrl 도 필수입니다.",
"additionalProperties": true
},
"event": {
"type": "object",
"description": "선택. 등록 요청이 명시된 캘린더 watcher 원본 이벤트. context 가 없을 때 title/start/end/attendees/joinUrl/본문의 Webex URL/안건 섹션 등을 추출해 예정 회의로 저장합니다. 메일 요약/질문만 하는 상황에서는 전달하지 마세요.",
"additionalProperties": true
},
"id": {
"type": "string",
"description": "선택 stable id. 생략하면 저장 시 파생 id 를 생성합니다."
},
"title": {
"type": "string",
"description": "선택. top-level 로 전달하는 예정 회의 제목."
},
"scheduledStart": {
"type": "string",
"description": "선택. top-level 로 전달하는 시작 시각. ISO-8601 timezone 포함 권장."
},
"scheduledEnd": {
"type": "string",
"description": "선택. top-level 로 전달하는 종료 시각."
},
"organizer": {
"type": "string",
"description": "선택. 주최자 표시 이름."
},
"location": {
"type": "string",
"description": "선택. 회의 장소 또는 회의실명."
},
"description": {
"type": "string",
"description": "선택. 회의 설명, 초대 본문, 메모."
},
"category": {
"type": "string",
"description": "선택. 회의 카테고리. 없으면 needsCategorySelection 을 반환합니다."
},
"participants": {
"type": "array",
"items": {
"type": "string"
},
"description": "선택. 참석자 표시 이름 배열."
},
"agenda": {
"type": "array",
"items": {
"type": "string"
},
"description": "필수. UI의 '오늘 회의 안건'에 표시할 회의 안건 배열. 줄바꿈/bullet 텍스트는 agendaText 로 전달하세요."
},
"agendaItems": {
"type": "array",
"items": {
"type": "string"
},
"description": "필수 대체값. agenda 별칭. UI의 '오늘 회의 안건'에 표시할 안건 배열."
},
"agendaText": {
"type": "string",
"description": "필수 대체값. agenda 별칭. 줄바꿈 또는 bullet 텍스트를 안건 배열로 나누어 표시합니다."
},
"meetingAgenda": {
"type": "string",
"description": "선택. agendaText 별칭. 배열은 meetingAgenda 대신 agenda 또는 agendaItems 로 전달하세요."
},
"todayAgenda": {
"type": "string",
"description": "선택. agendaText 별칭. 배열은 todayAgenda 대신 agenda 또는 agendaItems 로 전달하세요."
},
"conference": {
"type": "object",
"description": "선택. 화상회의 접속 정보.",
"properties": {
"type": {
"type": "string",
"enum": [
"webex",
"zoom",
"teams",
"other"
]
},
"joinUrl": {
"type": "string"
},
"accessCode": {
"type": "string"
},
"password": {
"type": "string"
},
"hostDisplayName": {
"type": "string"
}
},
"additionalProperties": false
},
"joinUrl": {
"type": "string",
"description": "선택. legacy top-level 회의 링크. conference.joinUrl 로 정규화합니다."
},
"webexUrl": {
"type": "string",
"description": "Webex 회의일 때 필수. legacy top-level Webex 참여 링크. conference.joinUrl 로 정규화합니다."
},
"zoomUrl": {
"type": "string",
"description": "선택. legacy top-level Zoom 링크."
},
"teamsUrl": {
"type": "string",
"description": "선택. legacy top-level Teams 링크."
},
"source": {
"type": "string",
"enum": [
"room-reservation",
"video-meeting",
"calendar-sync",
"other"
],
"description": "이 예정 회의가 온 출처. 로깅과 자동화 추적에 사용합니다."
},
"focusInUi": {
"type": "boolean",
"description": "기본 false. true 면 저장 후 이 회의를 현재 회의 전 안내 카드로 표시합니다."
}
},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model"
]
}
}
},
{
"name": "meeting_register_scheduled_meetings",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n이미 외부에서 만들어진 예정 회의 여러 건을 한 번에 저장합니다. 사용 시기: 사용자가 명시적으로 여러 회의를 미팅 익스텐션 upcoming list 에 등록하라고 요청했거나, 캘린더 동기화/회의실 예약 결과/화상회의 생성 결과를 bulk 로 등록하는 자동화가 실행될 때만 호출합니다. 호출 금지: 사용자가 단순히 회의 관련 메일/캘린더 내용을 보여주거나, 메일 요약/질문/답장 작성만 요청한 경우. 회의 관련 메일이 있다는 이유만으로 자동 호출하지 마세요. 필수 입력: meetings 또는 events 중 하나이며, 각 회의 category 와 agenda/agendaText 또는 사용자가 등록하라고 지정한 원문 안건 섹션도 반드시 필요합니다. Webex 회의라면 webexUrl 또는 conference.joinUrl 도 반드시 전달하세요. 둘 다 없으면 이 tool 을 호출하지 말고 사용자에게 먼저 물어보세요. 하나라도 category 가 없으면 저장하지 않고 { ok:false, needsCategorySelection, categories, suggestions } 를 반환하므로 사용자에게 카테고리를 물어본 뒤 다시 호출하세요. 하나라도 agenda 가 없으면 { ok:false, needsAgenda } 를 반환합니다. 새 카테고리라면 meeting_categories 로 기존 목록을 보여주고 사용자 확인 후 meeting_register_category 를 먼저 호출하세요. 사용자 요청으로 1건을 직접 등록하면 meeting_register_manual_meeting, 외부 생성 결과 1건만 등록하면 meeting_register_scheduled_meeting, 즉시 화면 표시가 목적이면 meeting_open_prep 을 사용하세요. 이 tool 은 원본 일정 생성도 녹음 시작도 하지 않습니다. 반환: { ok, ids, count, source }.",
"inputSchema": {
"type": "object",
"properties": {
"meetings": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"description": "필수 선택지 1. 저장할 예정 회의 정보 배열. 각 항목은 title, participants, scheduledStart, conference, agenda 등을 가질 수 있습니다."
},
"events": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
},
"description": "필수 선택지 2. 등록 요청이 명시된 캘린더 watcher 원본 이벤트 배열. meetings 대신 전달하면 각 이벤트에서 회의 정보를 추출합니다. 메일 요약/질문만 하는 상황에서는 전달하지 마세요."
},
"source": {
"type": "string",
"enum": [
"room-reservation",
"video-meeting",
"calendar-sync",
"other"
],
"description": "이 예정 회의들이 온 출처. 로깅과 자동화 추적에 사용합니다."
}
},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model"
]
}
}
},
{
"name": "meeting_get_prep",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n현재 UI가 보고 있거나 가장 가까운 예정 회의 1건의 '회의 전 안내' 정보를 조회합니다. 사용 시기: '오늘 회의 뭐야?', '다음 회의 정보 보여줘'처럼 단일 예정 회의가 필요할 때. 여러 예정 회의를 보여줘야 하면 meeting_list_preps 를 사용하세요. 녹음 시작/회의록 생성은 하지 않습니다. 반환: MeetingContext 또는 null.",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_bulk_upsert_preps",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n저수준 bulk upsert: 회의 전 안내(prep) 여러 건을 그대로 저장/갱신합니다. 일반 LLM 선택에서는 meeting_register_scheduled_meetings 를 우선 사용하세요. 각 prep.category 는 필수입니다. 비어 있으면 저장하지 않고 needsCategorySelection 을 반환하므로 사용자에게 카테고리를 물어본 뒤 다시 호출하세요. UI 포커스를 바꾸지 않고 녹음도 시작하지 않습니다. 반환: { ids, count }.",
"inputSchema": {
"type": "object",
"properties": {
"preps": {
"type": "array",
"items": {
"type": "object",
"additionalProperties": true
}
}
},
"required": [
"preps"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_list_preps",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n저장된 예정 회의/회의 전 안내 목록을 시간순으로 조회합니다. 사용 시기: '예정된 회의 다 보여줘', '회의 목록'처럼 여러 항목을 보여줘야 할 때. 가장 가까운 1건만 필요하면 meeting_get_prep 를 사용하세요. 녹음 세션/완료 회의록 목록은 meeting_sessions 입니다. 반환: MeetingContext[].",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_delete_prep",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n예정 회의/회의 전 안내 1건을 삭제합니다. 사용 시기: 사용자가 '그 예정 회의 빼줘', 캘린더가 cancelled 이벤트를 보낸 경우. 완료된 회의록이나 진행 중 녹음 세션은 삭제하지 않습니다. 진행 중 녹음 폐기는 meeting_cancel 입니다. 반환: { deleted: boolean }.",
"inputSchema": {
"type": "object",
"properties": {
"id": {
"type": "string",
"description": "삭제할 prep id"
}
},
"required": [
"id"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model"
]
}
}
},
{
"name": "meeting_cancel",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n진행 중인 녹음 세션을 요약 없이 폐기합니다. 사용 시기: 사용자가 '녹음 취소', '실수로 시작했어'라고 할 때. meeting_stop 과 달리 회의록을 만들지 않고 현재 세션 데이터를 삭제합니다. 이미 완료된 회의록 삭제나 예정 회의 삭제에는 사용하지 않습니다. 예정 회의 삭제는 meeting_delete_prep 입니다. 반환: { ok }.",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "취소할 회의 세션 ID"
}
},
"required": [
"sessionId"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_open_url",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\nWebex 회의가 연결된 예정 회의에서 전달받은 정확한 Webex joinUrl 만 기본 브라우저로 엽니다. 사용 시기: context.conference.type 이 webex 이고 joinUrl 이 https://*.webex.com/... 형태로 존재하며 사용자가 회의 참여를 요청했을 때만 호출하세요. Zoom/Teams/일반 URL/추측 URL에는 호출하지 마세요. 이 tool 은 녹음 시작, 일정 등록, 회의록 생성을 하지 않습니다. 반환: { ok }.",
"inputSchema": {
"type": "object",
"properties": {
"url": {
"type": "string",
"format": "uri"
}
},
"required": [
"url"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_update_summary",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n이미 완료된 회의록의 제목/요약/하이라이트/액션 아이템을 수정합니다. 사용 시기: 사용자가 '이 회의록 제목 바꿔줘', 인라인 편집 저장을 요청할 때. 누락 필드는 기존 값을 유지합니다. 아직 종료되지 않은 녹음 세션에는 사용할 수 없습니다. 먼저 meeting_stop 또는 meeting_regenerate_summary 가 필요합니다. 반환: 갱신된 finalSummary.",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "수정할 회의 세션 ID (이미 finalized 된 세션)"
},
"title": {
"type": "string",
"description": "새 회의 제목 (최대 200자, 생략 시 기존 유지)"
},
"summary": {
"type": "string",
"description": "새 요약 본문 (최대 8000자, 생략 시 기존 유지)"
},
"highlights": {
"type": "array",
"items": {
"type": "string"
},
"description": "새 하이라이트 목록 (각 항목 최대 500자, 최대 30개, 생략 시 기존 유지)"
},
"actionItems": {
"type": "array",
"items": {
"type": "string"
},
"description": "새 액션 아이템 목록 (각 항목 최대 500자, 최대 50개, 생략 시 기존 유지)"
}
},
"required": [
"sessionId"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_update_session_category",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n완료된 회의록 1건의 카테고리를 변경합니다. 사용 시기: 사용자가 '이 회의 카테고리를 프로젝트로 바꿔줘', 회의록 목록 UI에서 카테고리 셀렉트를 변경할 때. category 는 필수이며 비어 있으면 저장하지 않고 needsCategorySelection 을 반환합니다. 반환: { ok, sessionId, category }.",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "카테고리를 변경할 완료 회의 sessionId"
},
"category": {
"type": "string",
"description": "새 카테고리. 예: 일반, 프로젝트, 정기회의, 1:1, 고객/외부."
}
},
"required": [
"sessionId",
"category"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_link_sessions",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n완료된 회의록 2건을 서로 관련 회의로 연결합니다. 사용 시기: 사용자가 '이 회의랑 저 회의 연결해줘', '후속 회의로 묶어줘'라고 할 때. 양방향으로 저장되며 원문/요약 내용은 변경하지 않습니다. 반환: { ok, sessionId, targetSessionId, linked, relatedSessionIds }.",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "기준 회의 sessionId"
},
"targetSessionId": {
"type": "string",
"description": "연결할 상대 회의 sessionId"
}
},
"required": [
"sessionId",
"targetSessionId"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_unlink_sessions",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n서로 연결된 완료 회의록 2건의 관련 회의 링크를 해제합니다. 사용 시기: 사용자가 '이 회의 연결 끊어줘', '관련 회의에서 빼줘'라고 할 때. 양방향 링크를 제거하며 원문/요약 내용은 변경하지 않습니다. 반환: { ok, sessionId, targetSessionId, linked, relatedSessionIds }.",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "기준 회의 sessionId"
},
"targetSessionId": {
"type": "string",
"description": "연결을 해제할 상대 회의 sessionId"
}
},
"required": [
"sessionId",
"targetSessionId"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_regenerate_summary",
"description": "회의실(공간/시설 단위 자원) 예약·조회와 무관.\n이미 완료된 회의의 전사는 그대로 두고 최종 회의록만 다시 생성합니다. 사용 시기: 사용자가 '회의록 다시 만들어줘', '요약 다시 뽑아줘', '더 길게 다시 정리해줘'라고 할 때. 진행 중인 녹음을 끝내는 용도가 아니며, 녹음 종료는 meeting_stop 입니다. 반환: 새 finalSummary.",
"inputSchema": {
"type": "object",
"properties": {
"sessionId": {
"type": "string",
"description": "재생성할 회의 세션 ID (transcript 가 비어있지 않아야 함)"
},
"lengthTier": {
"type": "string",
"enum": [
"short",
"medium",
"long"
],
"description": "재생성 시 회의록 분량. short=1-2문장, medium=3-5문장, long=5-10문장+상세. 생략 시 전역 default."
}
},
"required": [
"sessionId"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"model",
"app"
]
}
}
},
{
"name": "meeting_stage_upload_begin",
"inputSchema": {
"type": "object",
"properties": {}
},
"_meta": {
"ui": {
"visibility": [
"app"
]
}
}
},
{
"name": "meeting_stage_upload_chunk",
"inputSchema": {
"type": "object",
"properties": {}
},
"_meta": {
"ui": {
"visibility": [
"app"
]
}
}
},
{
"name": "meeting_stage_upload_finish",
"inputSchema": {
"type": "object",
"properties": {}
},
"_meta": {
"ui": {
"visibility": [
"app"
]
}
}
},
{
"name": "meeting_stage_upload_cancel",
"inputSchema": {
"type": "object",
"properties": {}
},
"_meta": {
"ui": {
"visibility": [
"app"
]
}
}
},
{
"name": "meeting_recorder_state",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"app"
]
}
}
},
{
"name": "meeting_recorder_begin_capture",
"inputSchema": {
"type": "object",
"properties": {
"context": {
"type": "object",
"description": "회의 메타데이터. 부착 시 전달된 값이 있으면 생략 가능.",
"additionalProperties": true
},
"lengthTier": {
"type": "string",
"enum": [
"short",
"medium",
"long"
],
"description": "회의록 분량. meeting_stop 이 override 하지 않으면 이 값이 사용됨."
},
"captureMode": {
"type": "string",
"enum": [
"mic-only",
"mic-and-system"
],
"description": "마이크만 열지, 시스템 오디오까지 열지. 실제로 열린 것이 반환됨."
},
"micId": {
"type": "string",
"description": "사용할 마이크 deviceId. 빈 문자열이면 기본 장치."
}
},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"app"
]
}
}
},
{
"name": "meeting_recorder_levels",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"app"
]
}
}
},
{
"name": "meeting_recorder_microphones",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"app"
]
}
}
},
{
"name": "meeting_recorder_restart_capture",
"inputSchema": {
"type": "object",
"properties": {
"captureMode": {
"type": "string",
"enum": [
"mic-only",
"mic-and-system"
],
"description": "교체 후 열 캡처 범위."
},
"micId": {
"type": "string",
"description": "교체할 마이크 deviceId."
}
},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"app"
]
}
}
},
{
"name": "meeting_recorder_set_paused",
"inputSchema": {
"type": "object",
"properties": {
"paused": {
"type": "boolean",
"description": "true 면 프레임을 chunker 로 보내지 않음. 캡처 자체는 열린 채로 둠."
}
},
"required": [
"paused"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"app"
]
}
}
},
{
"name": "meeting_recorder_resize",
"inputSchema": {
"type": "object",
"properties": {
"height": {
"type": "number",
"description": "요청 높이(px). 호스트가 dock 전체 상한에 맞춰 clamp 하며, 실제 적용된 값이 반환됨."
}
},
"required": [
"height"
],
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"app"
]
}
}
},
{
"name": "meeting_recorder_close",
"inputSchema": {
"type": "object",
"properties": {},
"additionalProperties": false
},
"_meta": {
"ui": {
"visibility": [
"app"
]
}
}
}
],
"capabilities": [
"meeting-recorder",
"external-auth-consumer"
],
"networkAccess": {
"allowedDomains": [
"openai.azure.com",
"cognitiveservices.azure.com",
"services.ai.azure.com",
"api.openai.com",
"github.com",
"release-assets.githubusercontent.com"
],
"reasoning": "STT transcription egress to Azure OpenAI / OpenAI Whisper endpoints via host-mediated fetch. github.com and release-assets.githubusercontent.com carry the FFmpeg runtime archive that a marketplace install downloads on first use: the release URL is on github.com and answers 302 to release-assets.githubusercontent.com, and because the host re-runs the full gate on every hop, BOTH hosts have to be declared for the download to complete."
},
"pluginAccess": {
"plugins": [
{
"pluginId": "ms-graph",
"events": [
"calendar.events.loaded",
"calendar.event.added",
"calendar.event.upcoming",
"calendar.event.starting"
]
}
]
},
"eventSubscriptions": [
"calendar.events.loaded",
"calendar.event.added",
"calendar.event.upcoming",
"calendar.event.starting"
],
"emittedEvents": [
"meeting.started",
"meeting.ended",
"meeting.transcript.updated",
"meeting.summary.created",
"meeting.summary.degraded",
"meeting.error",
"meeting.prep.opened",
"meeting.prep.registered",
"meeting.calendar.snapshot.requested"
],
"startupTimeoutMs": 5000,
"ui": [
{
"id": "meeting-control",
"slot": "sidebar",
"kind": "embedded-module",
"displayName": "미팅",
"title": "Meeting Recorder",
"description": "회의 세션 시작/청크 주입/종료/전사 조회를 테스트합니다.",
"entry": "dist/ui/meeting-control.js",
"exportName": "default"
},
{
"id": "meeting-recorder-card",
"slot": "floating",
"kind": "embedded-module",
"displayName": "녹음",
"title": "Meeting Recorder",
"description": "녹음 중인 회의의 타이머·파형·메모를 호스트 플로팅 독에 표시합니다.",
"entry": "dist/ui/recorder-card.js",
"exportName": "default"
}
],
"hostSecrets": {
"read": [
"llm.apiKey.openai",
"llm.apiKey.azure-foundry"
]
},
"configSchema": {
"properties": {
"apiKeySource": {
"type": "string",
"title": "API 키 소스",
"description": "STT 호출에 사용할 API 키 출처. 'host' = Ave host 의 active LLM provider 키와 endpoint 를 hostApi.resolveApiKey 로 임대합니다(Azure active provider 포함). 'plugin' = 본 익스텐션의 sttApiKey secret 을 사용합니다. 로컬/user 설치 익스텐션에서 BYO STT 키를 쓸 때 선택합니다.",
"enum": [
"host",
"plugin"
],
"default": "host"
},
"intermediateSummariesEnabled": {
"type": "boolean",
"title": "중간 요약 사용",
"description": "회의 진행 중 자동으로 중간 요약을 생성할지 여부. 끄면 LLM 호출이 없어 비용/지연이 줄지만 라이브 카드도 비어 있게 됩니다.",
"default": true
},
"intermediateEveryFinalSegments": {
"type": "integer",
"title": "중간 요약 트리거 간격 (세그먼트)",
"description": "중간 요약 한 번을 만들기 위해 누적해야 하는 최종 STT 세그먼트 수. 값이 클수록 호출 빈도가 줄어 비용/노이즈가 감소합니다.",
"default": 6,
"minimum": 1,
"maximum": 50
},
"intermediateMinIntervalMs": {
"type": "integer",
"title": "중간 요약 최소 간격 (ms)",
"description": "직전 중간 요약 생성 후 다음 요약까지의 최소 wall-clock 간격(밀리초). 이 시간이 지나기 전엔 세그먼트 누적과 무관하게 새 요약을 만들지 않습니다. 첫 요약은 throttle 안 걸림. 0 이면 비활성.",
"default": 90000,
"minimum": 0,
"maximum": 600000
},
"uploadIntermediateSummaryBudget": {
"type": "integer",
"title": "파일 업로드 중간 요약 예산",
"description": "파일 업로드 한 세션에서 생성할 중간 요약 최대 횟수. 긴 녹음 파일을 빠르게 처리할 때 host LLM 호출 제한을 최종 회의록 전에 소진하지 않도록 제한합니다. 0이면 업로드 중간 요약을 만들지 않고 최종 회의록만 생성합니다.",
"default": 8,
"minimum": 0,
"maximum": 18
},
"sttModel": {
"type": "string",
"title": "STT 모델",
"description": "음성 전사에 사용할 모델 또는 Azure OpenAI deployment 이름. ⭐ 추천: 'gpt-4o-transcribe-diarize' (화자 분리 지원). host 모드에서는 host 가 제공한 Azure endpoint 에 이 값을 deployment 로 정규화합니다. plugin 모드에서 Azure/custom endpoint 를 쓰려면 sttBaseUrl 의 deployment 이름도 이 값과 맞춰야 합니다.",
"enum": [
"gpt-4o-transcribe-diarize",
"gpt-4o-transcribe",
"gpt-4o-mini-transcribe",
"whisper-1"
],
"default": "gpt-4o-transcribe"
},
"sttApiKey": {
"type": "string",
"title": "STT API Key",
"description": "apiKeySource='plugin' 일 때 사용할 회의 익스텐션 전용 STT API key. host keychain 의 plugin.<pluginId>.sttApiKey 네임스페이스에 저장되며, host 모드에서는 사용하지 않습니다.",
"format": "secret",
"default": ""
},
"sttBaseUrl": {
"type": "string",
"title": "STT 엔드포인트 URL",
"description": "선택 사항. Azure OpenAI 또는 커스텀 OpenAI-호환 STT 엔드포인트 URL. 비워두면 host 모드는 host 가 제공한 endpoint 를 사용하고, plugin 모드는 OpenAI public 기본 전사 endpoint 를 사용합니다. plugin 모드에서 Azure/custom 키를 쓰는 경우 반드시 설정하세요.",
"format": "uri",
"default": ""
},
"sttNoSpeechThreshold": {
"type": "number",
"title": "STT 무음 판정 임계값",
"description": "Whisper 의 no_speech_prob 가 이 값 이상인 세그먼트는 버립니다. 0~1. 기본 0.7. 높이면 더 보수적(노이즈 잘 거름), 낮추면 짧은 발화도 살림.",
"default": 0.7,
"minimum": 0,
"maximum": 1
},
"sttMinSegmentSec": {
"type": "number",
"title": "STT 최소 세그먼트 길이 (초)",
"description": "이 값보다 짧은 세그먼트는 같은 화자의 인접 세그먼트와 자동 병합합니다. STT 가 너무 잘게 쪼개질 때 1.5 정도 권장. 0 이면 비활성.",
"default": 0,
"minimum": 0,
"maximum": 30
},
"sttMaxGapSec": {
"type": "number",
"title": "STT 세그먼트 병합 간격 (초)",
"description": "인접 세그먼트 사이 무음 갭이 이 값 이하면 병합합니다. 자연스러운 문장 결합을 원하면 0.5~0.8 권장. 0 이면 비활성.",
"default": 0,
"minimum": 0,
"maximum": 10
},
"summaryLengthTier": {
"type": "string",
"title": "회의록 길이 (전역 기본값)",
"description": "최종 회의록 분량의 기본값. short=짧게(1-2문장), medium=보통(3-5문장), long=길게(5-10문장+상세). 녹음 시작 화면의 라디오 버튼이 이 기본값을 덮어쓸 수 있습니다.",
"enum": [
"short",
"medium",
"long"
],
"default": "medium"
},
"transcriptBubbleMaxChars": {
"type": "integer",
"title": "회의록 텍스트 bubble 최대 글자수",
"description": "회의록 상세 화면 '텍스트' 탭에서 같은 화자의 발화 단위를 한 bubble 에 묶을 때의 글자수 상한. 이 값을 넘으면 새 bubble 로 break. 작게 하면 bubble 이 더 자주 끊기고(짧고 많음), 크게 하면 한 bubble 에 여러 문장이 묶여 문단처럼 보임. 화자 분리 모델 사용 시엔 화자 변경 자체가 break trigger 라 이 값보다 화자 변경이 우선됨. 기본 320 (한국어 약 3-5문장).",
"default": 320,
"minimum": 80,
"maximum": 2000
},
"customSummaryFinalPrompt": {
"type": "string",
"title": "최종 회의록 프롬프트 (커스텀)",
"description": "최종 회의록 생성 시 LLM 에 보낼 system prompt. 비워두면 내장 기본 프롬프트 사용 (회의록 길이 tier 자동 반영, 한국어 회사 회의 최적화). 커스텀 프롬프트를 입력하면 해당 문자열을 그대로 사용 — 길이 tier 자동 inject 안 되니 직접 short/medium/long 분량 지침을 prompt 안에 포함시켜야 함. JSON 출력 형식도 직접 명시 필요: {\"title\", \"summary\", \"highlights\":[], \"actionItems\":[]}. 런타임 cap 은 8192 UTF-8 bytes.",
"maxLength": 8192,
"default": ""
},
"customSummaryIntermediatePrompt": {
"type": "string",
"title": "중간 요약 프롬프트 (커스텀)",
"description": "회의 진행 중 자동 생성되는 중간 요약(라이브 카드)의 system prompt. 비워두면 내장 기본 사용. 커스텀 입력 시 그대로 사용. JSON 형식 필요: {\"summary\", \"highlights\":[]}. 런타임 cap 은 8192 UTF-8 bytes.",
"maxLength": 8192,
"default": ""
},
"calendarAutomationEnabled": {
"type": "boolean",
"title": "캘린더 자동 회의 준비",
"description": "연결된 일정에서 예정 회의를 등록하고 시작 시 녹음을 준비합니다.",
"default": false
}
}
},
"requires": {
"minAppVersion": "0.14.0",
"hostProtocol": "3"
},
"configInherits": [
{
"pluginId": "work-assistant",
"to": "calendarAutomationEnabled",
"value": true
}
],
"alerts": {
"reasoning": "Meeting summaries and degraded summary generation are useful to surface promptly after a recording.",
"kinds": [
{
"id": "summary-ready",
"label": {
"en": "Meeting summary ready",
"ko": "회의 요약 완료"
},
"defaultEnabled": false,
"visibility": "user-visible",
"osNotification": {
"defaultEnabled": false,
"bypassFocusGate": false,
"body": {
"en": "A meeting summary is ready.",
"ko": "방금 종료된 회의의 액션 아이템이 정리되었습니다"
}
},
"actionLabel": {
"en": "Open",
"ko": "열기"
},
"slots": {
"title": {
"kind": "text",
"maxLength": 80
},
"highlights": {
"kind": "list",
"maxItems": 3,
"maxLength": 100
},
"actionItems": {
"kind": "list",
"maxItems": 3,
"maxLength": 100
},
"sessionId": {
"kind": "ref"
}
},
"summary": {
"en": "Summary ready: {title}; highlights: {highlights}; actions: {actionItems}",
"ko": "회의 요약: {title}; 주요 내용: {highlights}; 할 일: {actionItems}"
},
"prompt": {
"en": "The meeting {title} has ended. Highlights: {highlights}. Action items: {actionItems}. Offer to share the summary by mail, add a work log, create work items, or schedule a follow-up if requested.",
"ko": "{title} 회의가 끝났습니다. 주요 내용: {highlights}. 할 일: {actionItems}. 사용자가 원하면 메일 공유, 업무 기록, 할 일 등록, 후속 회의 일정을 도와주세요."
},
"inherits": [
{
"pluginId": "work-assistant",
"sourceId": "lvis",
"enabled": {
"key": "disabledDetectors",
"listed": "disabled",
"values": [
"meeting-summary"
]
},
"osNotification": {
"key": "osNotificationIntents",
"listed": "enabled",
"values": [
"meeting-summary"
],
"masterKey": "osNotificationsEnabled"
}
}
]
},
{
"id": "summary-degraded",
"label": {
"en": "Summary unavailable",
"ko": "요약 생성 불가"
},
"defaultEnabled": false,
"visibility": "summary-only",
"osNotification": {
"defaultEnabled": false,
"bypassFocusGate": false,
"body": {
"en": "A meeting summary could not be generated.",
"ko": "회의 요약을 만들 수 없습니다"
}
},
"summary": {
"en": "Meeting summary generation was unavailable.",
"ko": "회의 요약을 만들 수 없습니다."
},
"prompt": {
"en": "Meeting summary generation was unavailable.",
"ko": "회의 요약을 만들 수 없습니다."
}
}
]
}
}
}
}
Client extensions
Data this package carries for particular clients. The directory lists the clients named and never reads what is addressed to them.
- xyz.lvisai