clawops 0.2.2__tar.gz → 0.2.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. clawops-0.2.4/.github/workflows/publish.yml +55 -0
  2. {clawops-0.2.2 → clawops-0.2.4}/PKG-INFO +2 -2
  3. {clawops-0.2.2 → clawops-0.2.4}/README.md +1 -1
  4. {clawops-0.2.2 → clawops-0.2.4}/docs/agent.md +39 -0
  5. clawops-0.2.4/src/clawops/_version.py +1 -0
  6. clawops-0.2.2/.claude/settings.local.json +0 -22
  7. clawops-0.2.2/src/clawops/_version.py +0 -1
  8. {clawops-0.2.2 → clawops-0.2.4}/.gitignore +0 -0
  9. {clawops-0.2.2 → clawops-0.2.4}/pyproject.toml +0 -0
  10. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/__init__.py +0 -0
  11. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/_base_client.py +0 -0
  12. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/_client.py +0 -0
  13. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/_constants.py +0 -0
  14. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/_exceptions.py +0 -0
  15. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/_models.py +0 -0
  16. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/_resource.py +0 -0
  17. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/_utils.py +0 -0
  18. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/__init__.py +0 -0
  19. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/_agent.py +0 -0
  20. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/_audio.py +0 -0
  21. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/_control_ws.py +0 -0
  22. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/_media_ws.py +0 -0
  23. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/_recorder.py +0 -0
  24. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/_session.py +0 -0
  25. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/_tool.py +0 -0
  26. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/mcp/__init__.py +0 -0
  27. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/mcp/_http.py +0 -0
  28. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/mcp/_stdio.py +0 -0
  29. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/pipeline/__init__.py +0 -0
  30. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/pipeline/_base.py +0 -0
  31. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/pipeline/_realtime_session.py +0 -0
  32. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/plugins/__init__.py +0 -0
  33. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/agent/plugins/openai_realtime.py +0 -0
  34. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/pagination.py +0 -0
  35. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/py.typed +0 -0
  36. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/resources/__init__.py +0 -0
  37. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/resources/accounts.py +0 -0
  38. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/resources/calls.py +0 -0
  39. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/resources/numbers.py +0 -0
  40. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/resources/sip/__init__.py +0 -0
  41. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/resources/sip/credentials.py +0 -0
  42. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/types/__init__.py +0 -0
  43. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/types/call.py +0 -0
  44. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/types/call_params.py +0 -0
  45. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/types/number.py +0 -0
  46. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/types/number_params.py +0 -0
  47. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/types/shared.py +0 -0
  48. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/types/sip/__init__.py +0 -0
  49. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/types/sip/credential.py +0 -0
  50. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/types/sip/credential_params.py +0 -0
  51. {clawops-0.2.2 → clawops-0.2.4}/src/clawops/webhooks.py +0 -0
  52. {clawops-0.2.2 → clawops-0.2.4}/tests/__init__.py +0 -0
  53. {clawops-0.2.2 → clawops-0.2.4}/tests/agent/__init__.py +0 -0
  54. {clawops-0.2.2 → clawops-0.2.4}/tests/agent/test_agent.py +0 -0
  55. {clawops-0.2.2 → clawops-0.2.4}/tests/agent/test_audio.py +0 -0
  56. {clawops-0.2.2 → clawops-0.2.4}/tests/agent/test_control_ws.py +0 -0
  57. {clawops-0.2.2 → clawops-0.2.4}/tests/agent/test_integration.py +0 -0
  58. {clawops-0.2.2 → clawops-0.2.4}/tests/agent/test_mcp.py +0 -0
  59. {clawops-0.2.2 → clawops-0.2.4}/tests/agent/test_media_ws.py +0 -0
  60. {clawops-0.2.2 → clawops-0.2.4}/tests/agent/test_pipeline_base.py +0 -0
  61. {clawops-0.2.2 → clawops-0.2.4}/tests/agent/test_realtime_session.py +0 -0
  62. {clawops-0.2.2 → clawops-0.2.4}/tests/agent/test_recorder.py +0 -0
  63. {clawops-0.2.2 → clawops-0.2.4}/tests/agent/test_session.py +0 -0
  64. {clawops-0.2.2 → clawops-0.2.4}/tests/agent/test_tool.py +0 -0
  65. {clawops-0.2.2 → clawops-0.2.4}/tests/conftest.py +0 -0
  66. {clawops-0.2.2 → clawops-0.2.4}/tests/test_agent_exceptions.py +0 -0
  67. {clawops-0.2.2 → clawops-0.2.4}/tests/test_base_client.py +0 -0
  68. {clawops-0.2.2 → clawops-0.2.4}/tests/test_calls.py +0 -0
  69. {clawops-0.2.2 → clawops-0.2.4}/tests/test_client.py +0 -0
  70. {clawops-0.2.2 → clawops-0.2.4}/tests/test_exceptions.py +0 -0
  71. {clawops-0.2.2 → clawops-0.2.4}/tests/test_integration.py +0 -0
  72. {clawops-0.2.2 → clawops-0.2.4}/tests/test_models.py +0 -0
  73. {clawops-0.2.2 → clawops-0.2.4}/tests/test_numbers.py +0 -0
  74. {clawops-0.2.2 → clawops-0.2.4}/tests/test_pagination.py +0 -0
  75. {clawops-0.2.2 → clawops-0.2.4}/tests/test_params.py +0 -0
  76. {clawops-0.2.2 → clawops-0.2.4}/tests/test_sip_credentials.py +0 -0
  77. {clawops-0.2.2 → clawops-0.2.4}/tests/test_types.py +0 -0
  78. {clawops-0.2.2 → clawops-0.2.4}/tests/test_utils.py +0 -0
  79. {clawops-0.2.2 → clawops-0.2.4}/tests/test_webhooks.py +0 -0
@@ -0,0 +1,55 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ paths:
7
+ - 'src/clawops/_version.py'
8
+
9
+ jobs:
10
+ test:
11
+ runs-on: ubuntu-latest
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+ - uses: actions/setup-python@v5
15
+ with:
16
+ python-version: '3.12'
17
+ - run: pip install -e ".[dev]"
18
+ - run: pytest tests/ -v
19
+
20
+ publish:
21
+ needs: test
22
+ runs-on: ubuntu-latest
23
+ permissions:
24
+ id-token: write
25
+ contents: write
26
+ steps:
27
+ - uses: actions/checkout@v4
28
+ - uses: actions/setup-python@v5
29
+ with:
30
+ python-version: '3.12'
31
+
32
+ - name: Extract version
33
+ id: version
34
+ run: |
35
+ VERSION=$(python -c "exec(open('src/clawops/_version.py').read()); print(__version__)")
36
+ echo "version=$VERSION" >> "$GITHUB_OUTPUT"
37
+
38
+ - run: pip install build
39
+ - run: python -m build
40
+
41
+ - uses: pypa/gh-action-pypi-publish@release/v1
42
+
43
+ - name: Create git tag
44
+ run: |
45
+ git tag "v${{ steps.version.outputs.version }}"
46
+ git push origin "v${{ steps.version.outputs.version }}"
47
+
48
+ - name: Create GitHub Release
49
+ env:
50
+ GH_TOKEN: ${{ github.token }}
51
+ VERSION: ${{ steps.version.outputs.version }}
52
+ run: |
53
+ gh release create "v${VERSION}" dist/* \
54
+ --title "v${VERSION}" \
55
+ --generate-notes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: clawops
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: The official Python library for the ClawOps Voice API
5
5
  Project-URL: Homepage, https://github.com/learners-superpumped/clawops-python
6
6
  Project-URL: Documentation, https://docs.claw-ops.com
@@ -104,7 +104,7 @@ async def on_start(call):
104
104
  agent.listen() # WebSocket 연결 후 인바운드 대기
105
105
  ```
106
106
 
107
- > 자세한 사용법은 **[Agent 문서](docs/agent.md)** 를 참고하세요.
107
+ > 자세한 사용법은 **[Agent 문서](docs/agent.md)** 를 참고하세요. (Tool, 이벤트, 통화 녹음, 파이프라인 모드, MCP 연동 등)
108
108
 
109
109
  ## REST API 사용법
110
110
 
@@ -47,7 +47,7 @@ async def on_start(call):
47
47
  agent.listen() # WebSocket 연결 후 인바운드 대기
48
48
  ```
49
49
 
50
- > 자세한 사용법은 **[Agent 문서](docs/agent.md)** 를 참고하세요.
50
+ > 자세한 사용법은 **[Agent 문서](docs/agent.md)** 를 참고하세요. (Tool, 이벤트, 통화 녹음, 파이프라인 모드, MCP 연동 등)
51
51
 
52
52
  ## REST API 사용법
53
53
 
@@ -10,6 +10,7 @@
10
10
  - [설정 옵션](#설정-옵션)
11
11
  - [Tool (함수 호출)](#tool-함수-호출)
12
12
  - [이벤트 핸들러](#이벤트-핸들러)
13
+ - [통화 녹음](#통화-녹음)
13
14
  - [파이프라인 모드 (커스텀 STT/LLM/TTS)](#파이프라인-모드-커스텀-sttllmtts)
14
15
  - [MCP 서버 연동](#mcp-서버-연동)
15
16
  - [CallSession](#callsession)
@@ -100,6 +101,10 @@ agent = ClawOpsAgent(
100
101
  eagerness="high", # 응답 적극성: low, medium, high, auto
101
102
  greeting=True, # 첫 인사 자동 생성 여부
102
103
 
104
+ # 녹음
105
+ recording=True, # 통화 녹음 활성화
106
+ recording_path="./recordings", # 저장 경로 (기본값: ./recordings)
107
+
103
108
  # 고급
104
109
  base_url="https://api.claw-ops.com", # API 엔드포인트
105
110
  )
@@ -198,6 +203,35 @@ async def on_transcript(call, role, text):
198
203
  | `call_end` | `(call)` | 통화 종료 |
199
204
  | `transcript` | `(call, role, text)` | 음성 텍스트 생성 |
200
205
 
206
+ ## 통화 녹음
207
+
208
+ `recording=True`로 통화를 실시간 녹음할 수 있습니다. 통화마다 3개 WAV 파일(PCM16 8kHz mono)이 생성됩니다.
209
+
210
+ ```python
211
+ agent = ClawOpsAgent(
212
+ from_="07012341234",
213
+ system_prompt="상담원입니다.",
214
+ recording=True,
215
+ recording_path="./recordings", # 기본값
216
+ )
217
+ ```
218
+
219
+ ### 생성되는 파일
220
+
221
+ | 파일 | 내용 |
222
+ |------|------|
223
+ | `{call_id}_in.wav` | 발신자 음성 (수신 오디오) |
224
+ | `{call_id}_out.wav` | AI 응답 (송신 오디오) |
225
+ | `{call_id}_mix.wav` | 양방향 믹스 |
226
+
227
+ ### 동작 원리
228
+
229
+ - 수신 오디오(발신자)가 타임라인 역할을 합니다
230
+ - 송신 오디오(AI 응답)는 버퍼에 쌓이고, 수신 청크가 올 때마다 같은 길이만큼 꺼내서 샘플 단위로 믹스합니다
231
+ - 별도 시간 관리 없이 자연스럽게 정렬됩니다
232
+ - 파일은 실시간으로 기록되므로 통화 중 디스크에 바로 저장됩니다
233
+ - 통화 종료 시 WAV 헤더가 최종 크기로 업데이트됩니다
234
+
201
235
  ## 파이프라인 모드 (커스텀 STT/LLM/TTS)
202
236
 
203
237
  OpenAI Realtime 대신 직접 STT, LLM, TTS 프로바이더를 조합할 수 있습니다.
@@ -374,6 +408,11 @@ ClawOpsAgent
374
408
  │ ├── to_openai_tools() # JSON Schema 자동 생성
375
409
  │ └── call() # 이름으로 함수 호출
376
410
 
411
+ ├── AudioRecorder (콜별) # 실시간 녹음 (recording=True 시)
412
+ │ ├── write_inbound() # 수신 오디오 → _in.wav + _mix.wav
413
+ │ ├── write_outbound() # 송신 오디오 → _out.wav + mix 버퍼
414
+ │ └── stop() # WAV 헤더 업데이트
415
+
377
416
  ├── CallSession (콜별) # 통화 상태 관리
378
417
  │ ├── audio_stream() # 수신 오디오 스트림
379
418
  │ ├── send_audio() # 응답 오디오 전송
@@ -0,0 +1 @@
1
+ __version__ = "0.2.4"
@@ -1,22 +0,0 @@
1
- {
2
- "permissions": {
3
- "allow": [
4
- "Read(//Users/ghyeok/Developments/clawops/**)",
5
- "WebSearch",
6
- "mcp__plugin_context7_context7__resolve-library-id",
7
- "mcp__plugin_context7_context7__query-docs",
8
- "Bash(git:*)",
9
- "Bash(pip install:*)",
10
- "Bash(pytest:*)",
11
- "Bash(python:*)",
12
- "Bash(mypy:*)",
13
- "Bash(ruff check:*)",
14
- "Bash(twine upload:*)",
15
- "Bash(node:*)",
16
- "Skill(commit-commands:commit)",
17
- "Bash(git rm:*)",
18
- "Bash(grep:*)",
19
- "Bash(gcloud compute ssh sip-callbot-vm:*)"
20
- ]
21
- }
22
- }
@@ -1 +0,0 @@
1
- __version__ = "0.2.2"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes