{"_id":"@dongkseo/conversation","_rev":"4-1d23d947d64bda49710ff6b9a46dd430","name":"@dongkseo/conversation","dist-tags":{"latest":"0.1.3"},"versions":{"0.1.0":{"name":"@dongkseo/conversation","version":"0.1.0","_id":"@dongkseo/conversation@0.1.0","maintainers":[{"name":"dongkseo","email":"ssddgg99@daum.net"}],"dist":{"shasum":"26989262e637a814a65d3146c45dea60fa7cf107","tarball":"https://registry.npmjs.org/@dongkseo/conversation/-/conversation-0.1.0.tgz","fileCount":26,"integrity":"sha512-/v+uDrPAX4HEH+8lcvCWpYNENgoFCeQoeJHcNbKJNiIS/1fqhd6/Iosrz9JBeXzT3Y+8ZCsqaKeR3iqYho+uRA==","signatures":[{"sig":"MEUCIQDiVR8ChW9GRyWny40lq8WBFgBwVK8ubQESDeflZp65kgIgIuQFjfI/Dt8oX6p52AwqIjTEi5m8vhJehXNg6K2ONAM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":161666},"main":"./dist/index.js","type":"module","_from":"file:dongkseo-conversation-0.1.0.tgz","types":"./dist/index.d.ts","nexora":{"stability":"advanced"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc","clean":"rm -rf dist .tsbuildinfo"},"_npmUser":{"name":"dongkseo","email":"ssddgg99@daum.net"},"_resolved":"/private/var/folders/lw/t8yfg__j2nxd25m53gt8840h0000gn/T/93d9863b95d7666dc53445b4ba1e5bb4/dongkseo-conversation-0.1.0.tgz","_integrity":"sha512-/v+uDrPAX4HEH+8lcvCWpYNENgoFCeQoeJHcNbKJNiIS/1fqhd6/Iosrz9JBeXzT3Y+8ZCsqaKeR3iqYho+uRA==","_npmVersion":"11.12.1","description":"**Stability: stable**","directories":{},"_nodeVersion":"26.0.0","dependencies":{"@dongkseo/tools":"0.1.0","@dongkseo/contracts":"0.1.0"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/conversation_0.1.0_1781668557044_0.7982037787470444","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@dongkseo/conversation","version":"0.1.1","_id":"@dongkseo/conversation@0.1.1","maintainers":[{"name":"dongkseo","email":"ssddgg99@daum.net"}],"dist":{"shasum":"d18e902b683287e92209d2e7c25e0151b7db52f0","tarball":"https://registry.npmjs.org/@dongkseo/conversation/-/conversation-0.1.1.tgz","fileCount":30,"integrity":"sha512-l+6jy03gQb6sKIzw5MkFOySJG3bWXOWLCSbvQ/K3dpqFYrdMWK0tLqnVKCaFdG6gxHk5NmUpDcJ0jHLvzOQWvQ==","signatures":[{"sig":"MEUCIC/ajmbTNyOr8jQy+bzSe9xRqAOvWSolfue7eZ2ms4K7AiEApG98j3pWI0+ymAme4lb0DfamjZwlEuwvTsYco8QeUMw=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":253726},"main":"./dist/index.js","type":"module","_from":"file:dongkseo-conversation-0.1.1.tgz","types":"./dist/index.d.ts","nexora":{"stability":"advanced"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc","clean":"rm -rf dist .tsbuildinfo"},"_npmUser":{"name":"dongkseo","email":"ssddgg99@daum.net"},"_resolved":"/private/var/folders/f6/dfc3mm717vx9xjh0vbgqnddr0000gn/T/05eb572af1cd8d799e8ddf5c1b64cc1d/dongkseo-conversation-0.1.1.tgz","_integrity":"sha512-l+6jy03gQb6sKIzw5MkFOySJG3bWXOWLCSbvQ/K3dpqFYrdMWK0tLqnVKCaFdG6gxHk5NmUpDcJ0jHLvzOQWvQ==","_npmVersion":"11.12.1","description":"**Stability: stable**","directories":{},"_nodeVersion":"26.0.0","dependencies":{"@dongkseo/tools":"^0.1.3","@dongkseo/contracts":"^0.1.8"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/conversation_0.1.1_1782200198218_0.5233010124225685","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"name":"@dongkseo/conversation","version":"0.1.2","_id":"@dongkseo/conversation@0.1.2","maintainers":[{"name":"dongkseo","email":"ssddgg99@daum.net"}],"dist":{"shasum":"6a193a838721391c267837667019c7e38dad4ca3","tarball":"https://registry.npmjs.org/@dongkseo/conversation/-/conversation-0.1.2.tgz","fileCount":26,"integrity":"sha512-NeAhdYoO+3C56dJUiAn99j+qx7TiZuYo6DIdgzwyOygwLYXgVf1dRxFg3g+RZxUBgnkdHGh7xiRDpDhP+0q/CA==","signatures":[{"sig":"MEUCIQCC9jgrhXdzqk7y7vEf2oeKkc7pGYdePfAzZzwOhbS1KQIgSJ/oB/DGz4bscn/JqXr3xgke0NAxGPTN3Zlbb0mXZgo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":166321},"main":"./dist/index.js","type":"module","_from":"file:dongkseo-conversation-0.1.2.tgz","types":"./dist/index.d.ts","nexora":{"stability":"advanced"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc","clean":"rm -rf dist .tsbuildinfo"},"_npmUser":{"name":"dongkseo","email":"ssddgg99@daum.net"},"_resolved":"/private/var/folders/lw/t8yfg__j2nxd25m53gt8840h0000gn/T/d18fd35807e3b2ff382d9f573c824591/dongkseo-conversation-0.1.2.tgz","_integrity":"sha512-NeAhdYoO+3C56dJUiAn99j+qx7TiZuYo6DIdgzwyOygwLYXgVf1dRxFg3g+RZxUBgnkdHGh7xiRDpDhP+0q/CA==","_npmVersion":"11.16.0","description":"**Stability: advanced** · `pnpm add @dongkseo/conversation`","directories":{},"_nodeVersion":"26.3.1","dependencies":{"@dongkseo/tools":"^0.1.5","@dongkseo/contracts":"^0.1.11"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"typescript":"^5.8.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/conversation_0.1.2_1782389361988_0.6252757054449452","host":"s3://npm-registry-packages-npm-production"}},"0.1.3":{"name":"@dongkseo/conversation","version":"0.1.3","type":"module","main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"dependencies":{"@dongkseo/contracts":"^0.1.32","@dongkseo/tools":"^0.3.4"},"devDependencies":{"@types/node":"^26.1.2","typescript":"^7.0.2"},"nexora":{"stability":"advanced"},"publishConfig":{"access":"public"},"scripts":{"build":"tsc","test":"vitest run","clean":"rm -rf dist .tsbuildinfo"},"_nodeVersion":"26.7.0","_id":"@dongkseo/conversation@0.1.3","dist":{"integrity":"sha512-RIv5kwG2d83mg5AYaiDJnQ3S4xsF/zw6XYGoJCnRQJmdAyB8mi7lB/qxSOEQLp4npLJbklBIfkWc8oW0/OSk9A==","shasum":"222c38783945fc9a560080661721b0cde3d022a6","tarball":"https://registry.npmjs.org/@dongkseo/conversation/-/conversation-0.1.3.tgz","fileCount":26,"unpackedSize":166512,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIHaFyWgb3XaLRIsALJo4NvGVF9sH/8aKHsC6nW21I1KQAiEA1u07rByg5SVp+vKpDeyKAPj7KFlDURUsDRWOb74SEk4="}]},"_npmUser":{"name":"dongkseo","email":"ssddgg99@daum.net"},"directories":{},"maintainers":[{"name":"dongkseo","email":"ssddgg99@daum.net"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/conversation_0.1.3_1786622538312_0.458278528174346"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-17T03:55:56.878Z","modified":"2026-08-13T12:02:18.593Z","0.1.0":"2026-06-17T03:55:57.186Z","0.1.1":"2026-06-23T07:36:38.380Z","0.1.2":"2026-06-25T12:09:22.177Z","0.1.3":"2026-08-13T12:02:18.441Z"},"maintainers":[{"name":"dongkseo","email":"ssddgg99@daum.net"}],"readme":"# @dongkseo/conversation\n\n**Stability: advanced** · `pnpm add @dongkseo/conversation`\n\n> 이 파일은 에이전트(사람·LLM)가 **소스를 열지 않고도** 이 패키지를 쓸 수 있게 하는 오리엔테이션 문서다.\n> 정확한 API 타입은 \"API 표면\" 섹션의 방법으로 `signatures`만 읽어라 — 본문을 베끼지 말 것.\n\n## 무엇인가 / 무엇이 아닌가\n\n여러 에이전트가 한 사람과 **하나의 채널을 공유**할 때, 모두가 동시에 답하지 않고\n사람처럼 그룹챗에서 순서를 지키게 하는 **턴테이킹 프로토콜** 패키지다.\n\n- ✅ 담는 것: 대화방 상태(`ConversationRoom`), 4단계 턴 프로토콜(`TurnManager`), 초저가 \"내가 답할까?\" 판단(`evaluateAgent`/`evaluateAll`), 다자 회의 진행(`MeetingOrchestrator`)\n- ❌ 안 담는 것: LLM 호출 구현, 도구 실행 엔진, 영속 저장소 구현, HTTP/Discord 어댑터 — 그건 `adapters`/`tools`/`store-*` 몫. 이 패키지는 그 위에서 **누가·언제 말하는지** 만 조율한다.\n\n의존 방향은 `conversation → contracts`, `conversation → tools` 단방향. `LLMProvider`·`AgentCard` 같은 계약은 주입받아 쓴다.\n\n## 핵심 개념\n\n| 개념 | 무엇 | 대표 export |\n| --- | --- | --- |\n| **ConversationRoom** | 한 채널의 공유 상태(참여자·히스토리·현재 응답자) | `ConversationRoom`, `RoomParticipant`, `RoomMessage` |\n| **TurnManager** | 4단계 프로토콜(evaluate → select → respond → follow-up) | `TurnManager`, `TurnManagerOptions`, `TurnResult` |\n| **Evaluate** | 토큰 ~50개짜리 \"내가 답할까?\" 이진 판단 + 신뢰도 | `evaluateAgent`, `evaluateAll`, `EvaluationResult` |\n| **MeetingOrchestrator** | 마스터가 진행하는 다자 회의(발언권·정리·스트리밍) | `MeetingOrchestrator`, `MeetingEvent`, `MeetingOrchestratorOptions` |\n| **Meeting prompts** | 회의 프롬프트 템플릿과 치환 헬퍼 | `DEFAULT_MEETING_PROMPTS`, `interpolate`, `MeetingPromptTemplates` |\n\n## 사용 레시피\n\n방을 만들고 에이전트를 넣은 뒤, 한 메시지마다 한 명만 답하게 한다 (`examples/personal-assistant` 기준, 실제 동작 코드):\n\n```ts\nimport { ConversationRoom, TurnManager } from '@dongkseo/conversation';\n\nconst room = new ConversationRoom('session');\nroom.join({\n  card: assistantCard,        // @dongkseo/contracts 의 defineAgent 결과\n  llm: myLLMProvider,         // LLMProvider 주입\n  respondPrompt: 'You are a helpful personal assistant. Be concise.',\n});\n\nconst tm = new TurnManager({ maxResponders: 1 }); // 메시지당 1명만 응답\n\n// 들어온 사용자 메시지를 방에 넣고, 누가 답할지 프로토콜에 맡긴다\nconst rmsg = room.addUserMessage(msg.content, msg.displayName);\nconst result = await tm.handleMessage(room, rmsg);\nconst content = result.responses[0]?.content ?? '(no response)';\n```\n\n여러 에이전트가 함께 있을 때는 `room.join(...)`을 더 호출하면 `TurnManager`가 누가 말할지 정한다.\n다자 **회의**가 필요하면 `MeetingOrchestrator(room, meetingManager)`로 마스터 진행자가 발언권을 돌린다\n(`meetingManager`는 `@dongkseo/tools` 제공):\n\n```ts\nimport { MeetingOrchestrator } from '@dongkseo/conversation';\n\nconst orchestrator = new MeetingOrchestrator(room, meetingMgr);\nconst summary = await orchestrator.runMeeting('master', '릴리스 일정', ['coder', 'reviewer']);\n```\n\n더 큰 예제: [`examples/personal-assistant`](../../examples/personal-assistant) (단일 응답 채널), [`examples/e2e-demo`](../../examples/e2e-demo) (TurnManager + MeetingOrchestrator).\n\n## API 표면 (소스 안 열고 타입만)\n\n`index.ts` 맨 위에 **섹션 맵 주석**이 있다. 정확한 시그니처가 필요하면 구현 본문 대신 **signatures 모드**로만 읽어라:\n\n```bash\nctx_read(path=\"packages/conversation/src/room.ts\",                 mode=\"signatures\")\nctx_read(path=\"packages/conversation/src/turn-manager.ts\",         mode=\"signatures\")\nctx_read(path=\"packages/conversation/src/evaluate.ts\",             mode=\"signatures\")\nctx_read(path=\"packages/conversation/src/meeting-orchestrator.ts\", mode=\"signatures\")\nctx_read(path=\"packages/conversation/src/index.ts\",                mode=\"map\")   # 전체 export 목록\n```\n\n어떤 파일에 뭐가 있는지는 `src/index.ts` 상단 주석 맵을 먼저 보면 된다.\n\n## 유지보수 (drift 방지)\n\n- 이 README = **목적·개념·레시피** 만. 거의 안 변하므로 손으로 관리.\n- **API 정본은 각 소스의 TSDoc** (`/** … */`). API가 바뀌면 코드 옆 TSDoc만 고치면 됨 — 여기 표는 복제하지 말 것.\n- 새 모듈을 export하면 `index.ts` 상단 섹션 맵에 한 줄만 추가.\n\n## Tests\n\n```bash\ncd packages/conversation && pnpm test\n```\n\nPart of the [Nexora](../../README.md) multi-tenant agent framework. · [Package map](../../docs/architecture/packages-map.md)\n","readmeFilename":""}