pupa-backend 0.0.72__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 (106) hide show
  1. pupa_backend-0.0.72/.gitignore +45 -0
  2. pupa_backend-0.0.72/LICENSE +21 -0
  3. pupa_backend-0.0.72/PKG-INFO +102 -0
  4. pupa_backend-0.0.72/README.md +52 -0
  5. pupa_backend-0.0.72/pupa_backend/__init__.py +0 -0
  6. pupa_backend-0.0.72/pupa_backend/__main__.py +10 -0
  7. pupa_backend-0.0.72/pupa_backend/agent.py +552 -0
  8. pupa_backend-0.0.72/pupa_backend/anthropic_client.py +100 -0
  9. pupa_backend-0.0.72/pupa_backend/app.py +268 -0
  10. pupa_backend-0.0.72/pupa_backend/auth/__init__.py +18 -0
  11. pupa_backend-0.0.72/pupa_backend/auth/devices.py +391 -0
  12. pupa_backend-0.0.72/pupa_backend/auth/middleware.py +95 -0
  13. pupa_backend-0.0.72/pupa_backend/auth/pairing.py +140 -0
  14. pupa_backend-0.0.72/pupa_backend/auth/routes.py +188 -0
  15. pupa_backend-0.0.72/pupa_backend/auth/scopes.py +105 -0
  16. pupa_backend-0.0.72/pupa_backend/backend_tools.py +369 -0
  17. pupa_backend-0.0.72/pupa_backend/claude_code_tool.py +255 -0
  18. pupa_backend-0.0.72/pupa_backend/claude_loop/__init__.py +51 -0
  19. pupa_backend-0.0.72/pupa_backend/claude_loop/config_mcp.py +111 -0
  20. pupa_backend-0.0.72/pupa_backend/claude_loop/endpoint.py +674 -0
  21. pupa_backend-0.0.72/pupa_backend/claude_loop/env.py +351 -0
  22. pupa_backend-0.0.72/pupa_backend/claude_loop/events.py +128 -0
  23. pupa_backend-0.0.72/pupa_backend/claude_loop/frontend_tools.py +105 -0
  24. pupa_backend-0.0.72/pupa_backend/claude_loop/gate.py +335 -0
  25. pupa_backend-0.0.72/pupa_backend/claude_loop/models.py +47 -0
  26. pupa_backend-0.0.72/pupa_backend/claude_loop/registry.py +304 -0
  27. pupa_backend-0.0.72/pupa_backend/cli.py +242 -0
  28. pupa_backend-0.0.72/pupa_backend/credentials.py +74 -0
  29. pupa_backend-0.0.72/pupa_backend/frontend_interrupt.py +229 -0
  30. pupa_backend-0.0.72/pupa_backend/harnesses.py +184 -0
  31. pupa_backend-0.0.72/pupa_backend/harnesses_routes.py +45 -0
  32. pupa_backend-0.0.72/pupa_backend/langfuse_tracing.py +326 -0
  33. pupa_backend-0.0.72/pupa_backend/langfuse_usage.py +275 -0
  34. pupa_backend-0.0.72/pupa_backend/langgraph_connectors/__init__.py +12 -0
  35. pupa_backend-0.0.72/pupa_backend/langgraph_connectors/config.py +204 -0
  36. pupa_backend-0.0.72/pupa_backend/langgraph_connectors/manager.py +227 -0
  37. pupa_backend-0.0.72/pupa_backend/langgraph_connectors/routes.py +391 -0
  38. pupa_backend-0.0.72/pupa_backend/langgraph_connectors/schemas.py +123 -0
  39. pupa_backend-0.0.72/pupa_backend/langgraph_harness.py +228 -0
  40. pupa_backend-0.0.72/pupa_backend/mcp_config_admin.py +199 -0
  41. pupa_backend-0.0.72/pupa_backend/mcp_servers.py +339 -0
  42. pupa_backend-0.0.72/pupa_backend/prompts.py +12 -0
  43. pupa_backend-0.0.72/pupa_backend/pupa_config.py +256 -0
  44. pupa_backend-0.0.72/pupa_backend/screenshare/__init__.py +15 -0
  45. pupa_backend-0.0.72/pupa_backend/screenshare/broker.py +83 -0
  46. pupa_backend-0.0.72/pupa_backend/screenshare/config.py +7 -0
  47. pupa_backend-0.0.72/pupa_backend/screenshare/routes.py +192 -0
  48. pupa_backend-0.0.72/pupa_backend/screenshare/sidecar_token.py +43 -0
  49. pupa_backend-0.0.72/pupa_backend/scripts/__init__.py +0 -0
  50. pupa_backend-0.0.72/pupa_backend/scripts/mcp.py +267 -0
  51. pupa_backend-0.0.72/pupa_backend/scripts/pair.py +242 -0
  52. pupa_backend-0.0.72/pupa_backend/scripts/service.py +300 -0
  53. pupa_backend-0.0.72/pupa_backend/scripts/setup.py +912 -0
  54. pupa_backend-0.0.72/pupa_backend/scripts/smoke.py +396 -0
  55. pupa_backend-0.0.72/pupa_backend/shell_approval.py +261 -0
  56. pupa_backend-0.0.72/pupa_backend/skills.py +175 -0
  57. pupa_backend-0.0.72/pupa_backend/sse_keepalive.py +130 -0
  58. pupa_backend-0.0.72/pupa_backend/sse_replay.py +423 -0
  59. pupa_backend-0.0.72/pupa_backend/tool_gating.py +82 -0
  60. pupa_backend-0.0.72/pyproject.toml +79 -0
  61. pupa_backend-0.0.72/shell_startup.example.sh +16 -0
  62. pupa_backend-0.0.72/tests/__init__.py +0 -0
  63. pupa_backend-0.0.72/tests/conftest.py +89 -0
  64. pupa_backend-0.0.72/tests/test_ag_ui_langgraph_emit_interrupt_bug.py +79 -0
  65. pupa_backend-0.0.72/tests/test_anthropic_system_merge.py +113 -0
  66. pupa_backend-0.0.72/tests/test_ask_user_interrupt.py +265 -0
  67. pupa_backend-0.0.72/tests/test_auth.py +148 -0
  68. pupa_backend-0.0.72/tests/test_auth_devices.py +256 -0
  69. pupa_backend-0.0.72/tests/test_auth_pairing.py +326 -0
  70. pupa_backend-0.0.72/tests/test_auth_scopes.py +275 -0
  71. pupa_backend-0.0.72/tests/test_build_model.py +79 -0
  72. pupa_backend-0.0.72/tests/test_claude_code_tool.py +205 -0
  73. pupa_backend-0.0.72/tests/test_claude_loop.py +849 -0
  74. pupa_backend-0.0.72/tests/test_claude_loop_context.py +121 -0
  75. pupa_backend-0.0.72/tests/test_claude_loop_model.py +134 -0
  76. pupa_backend-0.0.72/tests/test_claude_loop_native_tool_events.py +92 -0
  77. pupa_backend-0.0.72/tests/test_claude_loop_tool_unlock.py +271 -0
  78. pupa_backend-0.0.72/tests/test_credentials.py +81 -0
  79. pupa_backend-0.0.72/tests/test_db_config.py +179 -0
  80. pupa_backend-0.0.72/tests/test_duplicate_tool_call_spiral.py +392 -0
  81. pupa_backend-0.0.72/tests/test_frontend_interrupt.py +357 -0
  82. pupa_backend-0.0.72/tests/test_harnesses.py +119 -0
  83. pupa_backend-0.0.72/tests/test_harnesses_routes.py +54 -0
  84. pupa_backend-0.0.72/tests/test_langfuse_tracing.py +71 -0
  85. pupa_backend-0.0.72/tests/test_mcp_config_admin.py +163 -0
  86. pupa_backend-0.0.72/tests/test_mcp_gate.py +212 -0
  87. pupa_backend-0.0.72/tests/test_mcp_servers.py +246 -0
  88. pupa_backend-0.0.72/tests/test_per_request_model.py +213 -0
  89. pupa_backend-0.0.72/tests/test_planning_middleware.py +141 -0
  90. pupa_backend-0.0.72/tests/test_pupa_config.py +284 -0
  91. pupa_backend-0.0.72/tests/test_recursion_limit.py +64 -0
  92. pupa_backend-0.0.72/tests/test_resume_tool_refresh.py +256 -0
  93. pupa_backend-0.0.72/tests/test_screenshare_broker.py +346 -0
  94. pupa_backend-0.0.72/tests/test_service_unit.py +63 -0
  95. pupa_backend-0.0.72/tests/test_setup_cloudflared.py +157 -0
  96. pupa_backend-0.0.72/tests/test_shell_approval.py +305 -0
  97. pupa_backend-0.0.72/tests/test_shell_startup.py +181 -0
  98. pupa_backend-0.0.72/tests/test_shell_tool_gating.py +71 -0
  99. pupa_backend-0.0.72/tests/test_skills.py +178 -0
  100. pupa_backend-0.0.72/tests/test_sse_keepalive.py +140 -0
  101. pupa_backend-0.0.72/tests/test_sse_replay.py +335 -0
  102. pupa_backend-0.0.72/tests/test_startup_log.py +87 -0
  103. pupa_backend-0.0.72/tests/test_thread_usage.py +242 -0
  104. pupa_backend-0.0.72/tests/test_tool_gating.py +199 -0
  105. pupa_backend-0.0.72/tests/test_transcript.py +171 -0
  106. pupa_backend-0.0.72/uv.lock +3986 -0
@@ -0,0 +1,45 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *.egg-info/
5
+ dist/
6
+ .venv/
7
+ .python-version
8
+
9
+ # Editor / OS
10
+ .DS_Store
11
+ .idea/
12
+ .vscode/
13
+ .claude/*
14
+ !.claude/skills/
15
+ *.swp
16
+
17
+ # Swift (screenshare sidecar)
18
+ .build/
19
+ build/
20
+ .swiftpm/
21
+ Package.resolved
22
+
23
+ # Env / secrets
24
+ .env
25
+ .env.*
26
+ !.env.example
27
+ .api-key
28
+
29
+ # Local shell startup script (personal, not shared)
30
+ backend/shell_startup.local.sh
31
+
32
+ # Backend runtime artifacts
33
+ backend/sqlite_db
34
+ sqlite_db
35
+
36
+ # Paired-device token store (per-operator runtime state; contains hashed
37
+ # bearer tokens). Default path is now ~/.pupa-backend/pupa-auth.json (outside
38
+ # the repo); these patterns defensively ignore any stray in-repo copies from
39
+ # an explicit PUPA_AUTH_DB_PATH or a legacy CWD-relative run.
40
+ pupa-auth.json
41
+ pupa-auth.json.tmp
42
+ backend/pupa-auth.json
43
+ backend/pupa-auth.json.tmp
44
+
45
+ backend/.playwright-mcp
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Pupa
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,102 @@
1
+ Metadata-Version: 2.4
2
+ Name: pupa-backend
3
+ Version: 0.0.72
4
+ Summary: Pupa A2UI agent backend
5
+ Project-URL: Homepage, https://github.com/pupa-app/pupa-backend
6
+ Project-URL: Repository, https://github.com/pupa-app/pupa-backend
7
+ Project-URL: Changelog, https://github.com/pupa-app/pupa-backend/blob/main/CHANGELOG.md
8
+ Project-URL: Issues, https://github.com/pupa-app/pupa-backend/issues
9
+ Author-email: Pupa <pupa-app-help@proton.me>
10
+ License-Expression: MIT
11
+ License-File: LICENSE
12
+ Keywords: ag-ui,agent,fastapi,langgraph,llm
13
+ Classifier: Development Status :: 4 - Beta
14
+ Classifier: Framework :: FastAPI
15
+ Classifier: Intended Audience :: Developers
16
+ Classifier: Operating System :: OS Independent
17
+ Classifier: Programming Language :: Python :: 3
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
21
+ Requires-Python: >=3.11
22
+ Requires-Dist: ag-ui-langgraph>=0.0.42
23
+ Requires-Dist: boto3>=1.34.0
24
+ Requires-Dist: claude-agent-sdk>=0.2.106
25
+ Requires-Dist: copilotkit>=0.1.88
26
+ Requires-Dist: deepagents>=0.6.0
27
+ Requires-Dist: fastapi>=0.110.0
28
+ Requires-Dist: fastmcp>=3.4.2
29
+ Requires-Dist: langchain-anthropic>=0.3.0
30
+ Requires-Dist: langchain-aws>=0.2.0
31
+ Requires-Dist: langchain-mcp-adapters>=0.2.2
32
+ Requires-Dist: langchain-openai>=0.3.0
33
+ Requires-Dist: langchain-tavily>=0.1.0
34
+ Requires-Dist: langchain>=1.0.0
35
+ Requires-Dist: langfuse<4.0.0,>=3.0.0
36
+ Requires-Dist: langgraph-checkpoint-postgres>=2.0.0
37
+ Requires-Dist: langgraph-checkpoint-sqlite>=2.0.0
38
+ Requires-Dist: langgraph>=1.0.0
39
+ Requires-Dist: psycopg[binary,pool]>=3.2.0
40
+ Requires-Dist: pyyaml>=6.0
41
+ Requires-Dist: qrcode>=8.0.0
42
+ Requires-Dist: uvicorn[standard]>=0.30.0
43
+ Provides-Extra: dev
44
+ Requires-Dist: pytest-asyncio>=0.23.0; extra == 'dev'
45
+ Requires-Dist: pytest>=8.0.0; extra == 'dev'
46
+ Provides-Extra: setup
47
+ Requires-Dist: cryptography>=42.0.0; extra == 'setup'
48
+ Requires-Dist: pyyaml>=6.0; extra == 'setup'
49
+ Description-Content-Type: text/markdown
50
+
51
+ # pupa-backend
52
+
53
+ FastAPI / LangGraph backend that powers the [Pupa](https://github.com/pupa-app/pupa-backend)
54
+ iOS / macOS client. Speaks plain [AG-UI](https://github.com/ag-ui-protocol/ag-ui)
55
+ over a single `POST /` SSE stream; pair-once auth keeps a long-lived token in
56
+ each device's Keychain. Runs locally next to the client, or in the cloud
57
+ (Railway + Postgres).
58
+
59
+ ## Install
60
+
61
+ Install from PyPI with [uv](https://docs.astral.sh/uv/) (isolated tool venv, puts
62
+ the `pupa-backend` CLI on your PATH):
63
+
64
+ ```bash
65
+ uv tool install "pupa-backend[setup]" # latest
66
+ uv tool install "pupa-backend[setup]==0.0.72" # pin to match your app
67
+ ```
68
+
69
+ ## Quick start
70
+
71
+ ```bash
72
+ pupa-backend run # start the backend on :8004
73
+ pupa-backend pair # mint a QR pairing code for your iPhone
74
+ pupa-backend status # is it running?
75
+ pupa-backend service-install # run as launchd / systemd background service
76
+ ```
77
+
78
+ LLM credentials (AWS Bedrock, Anthropic, or any OpenAI-compatible endpoint) live
79
+ in your shell environment, never in the config file. Configuration is written by
80
+ `pupa-backend setup` to `~/.pupa-backend/config.yml`.
81
+
82
+ ## Auth model
83
+
84
+ The backend **requires auth by default** — the only client credential is a
85
+ paired-device token in the iOS Keychain. Set `PUPA_API_KEY` server-side, run
86
+ `pupa-backend pair` for an 8-char code, and pair from the app. For a same-laptop
87
+ dev loop only, `PUPA_AUTH_DISABLED=1` skips auth entirely (never on a reachable
88
+ backend).
89
+
90
+ ## Documentation
91
+
92
+ Full docs, architecture, deploy runbook, and contributing guide live in the
93
+ [GitHub repository](https://github.com/pupa-app/pupa-backend):
94
+
95
+ - [Architecture](https://github.com/pupa-app/pupa-backend/blob/main/docs/architecture.md)
96
+ - [Deploy (Railway + Postgres + Langfuse)](https://github.com/pupa-app/pupa-backend/blob/main/docs/deploy.md)
97
+ - [Contributing](https://github.com/pupa-app/pupa-backend/blob/main/CONTRIBUTING.md)
98
+ - [Changelog](https://github.com/pupa-app/pupa-backend/blob/main/CHANGELOG.md)
99
+
100
+ ## License
101
+
102
+ [MIT](https://github.com/pupa-app/pupa-backend/blob/main/LICENSE)
@@ -0,0 +1,52 @@
1
+ # pupa-backend
2
+
3
+ FastAPI / LangGraph backend that powers the [Pupa](https://github.com/pupa-app/pupa-backend)
4
+ iOS / macOS client. Speaks plain [AG-UI](https://github.com/ag-ui-protocol/ag-ui)
5
+ over a single `POST /` SSE stream; pair-once auth keeps a long-lived token in
6
+ each device's Keychain. Runs locally next to the client, or in the cloud
7
+ (Railway + Postgres).
8
+
9
+ ## Install
10
+
11
+ Install from PyPI with [uv](https://docs.astral.sh/uv/) (isolated tool venv, puts
12
+ the `pupa-backend` CLI on your PATH):
13
+
14
+ ```bash
15
+ uv tool install "pupa-backend[setup]" # latest
16
+ uv tool install "pupa-backend[setup]==0.0.72" # pin to match your app
17
+ ```
18
+
19
+ ## Quick start
20
+
21
+ ```bash
22
+ pupa-backend run # start the backend on :8004
23
+ pupa-backend pair # mint a QR pairing code for your iPhone
24
+ pupa-backend status # is it running?
25
+ pupa-backend service-install # run as launchd / systemd background service
26
+ ```
27
+
28
+ LLM credentials (AWS Bedrock, Anthropic, or any OpenAI-compatible endpoint) live
29
+ in your shell environment, never in the config file. Configuration is written by
30
+ `pupa-backend setup` to `~/.pupa-backend/config.yml`.
31
+
32
+ ## Auth model
33
+
34
+ The backend **requires auth by default** — the only client credential is a
35
+ paired-device token in the iOS Keychain. Set `PUPA_API_KEY` server-side, run
36
+ `pupa-backend pair` for an 8-char code, and pair from the app. For a same-laptop
37
+ dev loop only, `PUPA_AUTH_DISABLED=1` skips auth entirely (never on a reachable
38
+ backend).
39
+
40
+ ## Documentation
41
+
42
+ Full docs, architecture, deploy runbook, and contributing guide live in the
43
+ [GitHub repository](https://github.com/pupa-app/pupa-backend):
44
+
45
+ - [Architecture](https://github.com/pupa-app/pupa-backend/blob/main/docs/architecture.md)
46
+ - [Deploy (Railway + Postgres + Langfuse)](https://github.com/pupa-app/pupa-backend/blob/main/docs/deploy.md)
47
+ - [Contributing](https://github.com/pupa-app/pupa-backend/blob/main/CONTRIBUTING.md)
48
+ - [Changelog](https://github.com/pupa-app/pupa-backend/blob/main/CHANGELOG.md)
49
+
50
+ ## License
51
+
52
+ [MIT](https://github.com/pupa-app/pupa-backend/blob/main/LICENSE)
File without changes
@@ -0,0 +1,10 @@
1
+ """`python -m pupa_backend` → the CLI dispatcher.
2
+
3
+ Note the server itself is launched with `python -m pupa_backend.app` (see the
4
+ Makefile / Dockerfile / systemd unit), which runs `app.py`'s `main()` directly.
5
+ """
6
+
7
+ from pupa_backend.cli import main
8
+
9
+ if __name__ == "__main__":
10
+ raise SystemExit(main())