openbb-agent-server 0.1.0__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 (119) hide show
  1. openbb_agent_server-0.1.0/.gitignore +43 -0
  2. openbb_agent_server-0.1.0/PKG-INFO +137 -0
  3. openbb_agent_server-0.1.0/README.md +68 -0
  4. openbb_agent_server-0.1.0/openbb_agent_server/__init__.py +17 -0
  5. openbb_agent_server-0.1.0/openbb_agent_server/_vendor/__init__.py +0 -0
  6. openbb_agent_server-0.1.0/openbb_agent_server/_vendor/sqlitevec.py +135 -0
  7. openbb_agent_server-0.1.0/openbb_agent_server/acp/__init__.py +32 -0
  8. openbb_agent_server-0.1.0/openbb_agent_server/acp/canvas.py +1056 -0
  9. openbb_agent_server-0.1.0/openbb_agent_server/acp/canvas_app.py +480 -0
  10. openbb_agent_server-0.1.0/openbb_agent_server/acp/provider.py +580 -0
  11. openbb_agent_server-0.1.0/openbb_agent_server/app/__init__.py +1 -0
  12. openbb_agent_server-0.1.0/openbb_agent_server/app/app.py +299 -0
  13. openbb_agent_server-0.1.0/openbb_agent_server/app/config.py +754 -0
  14. openbb_agent_server-0.1.0/openbb_agent_server/app/router.py +1680 -0
  15. openbb_agent_server-0.1.0/openbb_agent_server/app/settings.py +779 -0
  16. openbb_agent_server-0.1.0/openbb_agent_server/main.py +396 -0
  17. openbb_agent_server-0.1.0/openbb_agent_server/memory/__init__.py +1 -0
  18. openbb_agent_server-0.1.0/openbb_agent_server/memory/classifier.py +201 -0
  19. openbb_agent_server-0.1.0/openbb_agent_server/memory/embeddings.py +118 -0
  20. openbb_agent_server-0.1.0/openbb_agent_server/memory/factory.py +226 -0
  21. openbb_agent_server-0.1.0/openbb_agent_server/memory/ingestion.py +424 -0
  22. openbb_agent_server-0.1.0/openbb_agent_server/memory/reranker.py +165 -0
  23. openbb_agent_server-0.1.0/openbb_agent_server/memory/retrievers.py +177 -0
  24. openbb_agent_server-0.1.0/openbb_agent_server/memory/sqlite_store.py +593 -0
  25. openbb_agent_server-0.1.0/openbb_agent_server/memory/store.py +196 -0
  26. openbb_agent_server-0.1.0/openbb_agent_server/memory/translation.py +161 -0
  27. openbb_agent_server-0.1.0/openbb_agent_server/memory/writer.py +163 -0
  28. openbb_agent_server-0.1.0/openbb_agent_server/observability/__init__.py +1 -0
  29. openbb_agent_server-0.1.0/openbb_agent_server/observability/logging.py +272 -0
  30. openbb_agent_server-0.1.0/openbb_agent_server/openbb.toml.example +332 -0
  31. openbb_agent_server-0.1.0/openbb_agent_server/persistence/__init__.py +1 -0
  32. openbb_agent_server-0.1.0/openbb_agent_server/persistence/models.py +650 -0
  33. openbb_agent_server-0.1.0/openbb_agent_server/persistence/prune.py +297 -0
  34. openbb_agent_server-0.1.0/openbb_agent_server/persistence/sqlite_store.py +857 -0
  35. openbb_agent_server-0.1.0/openbb_agent_server/persistence/store.py +444 -0
  36. openbb_agent_server-0.1.0/openbb_agent_server/plugins/__init__.py +1 -0
  37. openbb_agent_server-0.1.0/openbb_agent_server/plugins/auth/__init__.py +1 -0
  38. openbb_agent_server-0.1.0/openbb_agent_server/plugins/auth/api_key_table.py +303 -0
  39. openbb_agent_server-0.1.0/openbb_agent_server/plugins/auth/bearer_static.py +107 -0
  40. openbb_agent_server-0.1.0/openbb_agent_server/plugins/auth/none.py +60 -0
  41. openbb_agent_server-0.1.0/openbb_agent_server/plugins/auth/oidc_jwt.py +138 -0
  42. openbb_agent_server-0.1.0/openbb_agent_server/plugins/auth/openbb_workspace.py +111 -0
  43. openbb_agent_server-0.1.0/openbb_agent_server/plugins/checkpointers/__init__.py +1 -0
  44. openbb_agent_server-0.1.0/openbb_agent_server/plugins/checkpointers/inmemory.py +61 -0
  45. openbb_agent_server-0.1.0/openbb_agent_server/plugins/checkpointers/postgres.py +148 -0
  46. openbb_agent_server-0.1.0/openbb_agent_server/plugins/checkpointers/sqlite.py +109 -0
  47. openbb_agent_server-0.1.0/openbb_agent_server/plugins/middleware/__init__.py +1 -0
  48. openbb_agent_server-0.1.0/openbb_agent_server/plugins/middleware/call_limit.py +143 -0
  49. openbb_agent_server-0.1.0/openbb_agent_server/plugins/middleware/loop_guard.py +152 -0
  50. openbb_agent_server-0.1.0/openbb_agent_server/plugins/middleware/tool_call_announcer.py +120 -0
  51. openbb_agent_server-0.1.0/openbb_agent_server/plugins/middleware/tool_call_ledger.py +147 -0
  52. openbb_agent_server-0.1.0/openbb_agent_server/plugins/middleware/tool_filter.py +117 -0
  53. openbb_agent_server-0.1.0/openbb_agent_server/plugins/middleware/tool_message_normaliser.py +336 -0
  54. openbb_agent_server-0.1.0/openbb_agent_server/plugins/middleware/usage_recorder.py +95 -0
  55. openbb_agent_server-0.1.0/openbb_agent_server/plugins/models/__init__.py +1 -0
  56. openbb_agent_server-0.1.0/openbb_agent_server/plugins/models/_validation.py +55 -0
  57. openbb_agent_server-0.1.0/openbb_agent_server/plugins/models/anthropic_provider.py +158 -0
  58. openbb_agent_server-0.1.0/openbb_agent_server/plugins/models/bedrock_provider.py +182 -0
  59. openbb_agent_server-0.1.0/openbb_agent_server/plugins/models/fake_provider.py +138 -0
  60. openbb_agent_server-0.1.0/openbb_agent_server/plugins/models/google_genai_provider.py +226 -0
  61. openbb_agent_server-0.1.0/openbb_agent_server/plugins/models/groq_provider.py +248 -0
  62. openbb_agent_server-0.1.0/openbb_agent_server/plugins/models/groq_rate_limiter.py +447 -0
  63. openbb_agent_server-0.1.0/openbb_agent_server/plugins/models/nvidia_provider.py +241 -0
  64. openbb_agent_server-0.1.0/openbb_agent_server/plugins/models/openai_compat_provider.py +266 -0
  65. openbb_agent_server-0.1.0/openbb_agent_server/plugins/models/openai_provider.py +198 -0
  66. openbb_agent_server-0.1.0/openbb_agent_server/plugins/models/vertex_provider.py +221 -0
  67. openbb_agent_server-0.1.0/openbb_agent_server/plugins/subagents/__init__.py +1 -0
  68. openbb_agent_server-0.1.0/openbb_agent_server/plugins/subagents/analyst.py +50 -0
  69. openbb_agent_server-0.1.0/openbb_agent_server/plugins/subagents/charter.py +51 -0
  70. openbb_agent_server-0.1.0/openbb_agent_server/plugins/subagents/pdf_reader.py +57 -0
  71. openbb_agent_server-0.1.0/openbb_agent_server/plugins/subagents/researcher.py +69 -0
  72. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/__init__.py +1 -0
  73. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/_media.py +470 -0
  74. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/artifacts.py +328 -0
  75. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/background_jobs.py +158 -0
  76. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/client_side.py +115 -0
  77. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/dashboard.py +108 -0
  78. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/fetch_url.py +294 -0
  79. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/gemini_embeddings.py +230 -0
  80. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/gemini_image.py +621 -0
  81. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/gemma_audio.py +461 -0
  82. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/groq_audio.py +404 -0
  83. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/inspect_widget_data.py +389 -0
  84. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/mcp_http.py +230 -0
  85. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/mcp_local.py +194 -0
  86. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/memory_recall.py +95 -0
  87. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/paligemma_vision.py +468 -0
  88. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/pdf_extract.py +1089 -0
  89. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/python_module.py +93 -0
  90. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/pywry_canvas.py +1730 -0
  91. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/rerank.py +160 -0
  92. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/translate.py +138 -0
  93. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/vision_qa.py +380 -0
  94. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/web_search.py +177 -0
  95. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/widget_data.py +194 -0
  96. openbb_agent_server-0.1.0/openbb_agent_server/plugins/tools/workspace_mcp.py +84 -0
  97. openbb_agent_server-0.1.0/openbb_agent_server/prompts/__init__.py +12 -0
  98. openbb_agent_server-0.1.0/openbb_agent_server/prompts/default_system_prompt.md +412 -0
  99. openbb_agent_server-0.1.0/openbb_agent_server/protocol/__init__.py +1 -0
  100. openbb_agent_server-0.1.0/openbb_agent_server/protocol/adapter.py +771 -0
  101. openbb_agent_server-0.1.0/openbb_agent_server/protocol/schemas.py +556 -0
  102. openbb_agent_server-0.1.0/openbb_agent_server/protocol/sse.py +60 -0
  103. openbb_agent_server-0.1.0/openbb_agent_server/py.typed +0 -0
  104. openbb_agent_server-0.1.0/openbb_agent_server/runtime/__init__.py +1 -0
  105. openbb_agent_server-0.1.0/openbb_agent_server/runtime/builder.py +987 -0
  106. openbb_agent_server-0.1.0/openbb_agent_server/runtime/canvas.py +234 -0
  107. openbb_agent_server-0.1.0/openbb_agent_server/runtime/context.py +216 -0
  108. openbb_agent_server-0.1.0/openbb_agent_server/runtime/embedded.py +384 -0
  109. openbb_agent_server-0.1.0/openbb_agent_server/runtime/emit.py +568 -0
  110. openbb_agent_server-0.1.0/openbb_agent_server/runtime/identity.py +118 -0
  111. openbb_agent_server-0.1.0/openbb_agent_server/runtime/jobs.py +386 -0
  112. openbb_agent_server-0.1.0/openbb_agent_server/runtime/pdf_store.py +715 -0
  113. openbb_agent_server-0.1.0/openbb_agent_server/runtime/plugins.py +190 -0
  114. openbb_agent_server-0.1.0/openbb_agent_server/runtime/principal.py +54 -0
  115. openbb_agent_server-0.1.0/openbb_agent_server/runtime/registry.py +107 -0
  116. openbb_agent_server-0.1.0/openbb_agent_server/runtime/services.py +169 -0
  117. openbb_agent_server-0.1.0/openbb_agent_server/runtime/widget_store.py +707 -0
  118. openbb_agent_server-0.1.0/pyproject.toml +228 -0
  119. openbb_agent_server-0.1.0/website/README.md +37 -0
@@ -0,0 +1,43 @@
1
+ # --- Python ---
2
+ __pycache__/
3
+ *.py[cod]
4
+ .venv/
5
+ *.egg-info/
6
+ build/
7
+ dist/
8
+ .coverage
9
+ .coverage.*
10
+ coverage.xml
11
+ htmlcov/
12
+ .pytest_cache/
13
+ .ruff_cache/
14
+ .ty_cache/
15
+ .mypy_cache/
16
+
17
+ # --- Docs site (Docusaurus, in ./website) ---
18
+ node_modules/
19
+ website/build/
20
+ website/.docusaurus/
21
+ website/.cache-loader/
22
+ npm-debug.log*
23
+ yarn-error.log*
24
+
25
+ # Auto-generated API reference: rebuilt from the package docstrings by
26
+ # ``npm run gen-api`` (wiped + regenerated on every run, never
27
+ # hand-edited). The deploy workflow regenerates it in CI, so it is not
28
+ # tracked here.
29
+ /docs/reference/
30
+
31
+ # --- Secrets / local environment ---
32
+ .env
33
+ .env.*
34
+ !.env.example
35
+
36
+ # --- Editors / OS ---
37
+ .vscode/
38
+ .idea/
39
+ .DS_Store
40
+ Thumbs.db
41
+
42
+ # --- Local agent tooling ---
43
+ .claude/
@@ -0,0 +1,137 @@
1
+ Metadata-Version: 2.4
2
+ Name: openbb-agent-server
3
+ Version: 0.1.0
4
+ Summary: OpenBB Agent Server: pluggable, multi-tenant agent backend wired to the OpenBB Workspace UI.
5
+ Project-URL: Homepage, https://github.com/deeleeramone/openbb-agent-server
6
+ Project-URL: Repository, https://github.com/deeleeramone/openbb-agent-server
7
+ Author-email: Danglewood <85772166+deeleeramone@users.noreply.github.com>
8
+ License: AGPL-3.0-only
9
+ Requires-Python: <4,>=3.11
10
+ Requires-Dist: aiosqlite>=0.20
11
+ Requires-Dist: alembic>=1.13
12
+ Requires-Dist: argon2-cffi>=23.1
13
+ Requires-Dist: ddgs>=9.0
14
+ Requires-Dist: deepagents>=0.5.0
15
+ Requires-Dist: fastapi>=0.115.0
16
+ Requires-Dist: fastmcp>=3.2.0
17
+ Requires-Dist: httpx2>=0.1
18
+ Requires-Dist: langchain-core>=1.0.0
19
+ Requires-Dist: langchain-mcp-adapters>=0.2.0
20
+ Requires-Dist: langchain-nvidia-ai-endpoints>=1.0.0
21
+ Requires-Dist: langchain-text-splitters>=0.3
22
+ Requires-Dist: langchain>=1.0.0
23
+ Requires-Dist: langgraph-checkpoint-sqlite>=2.0
24
+ Requires-Dist: langgraph>=1.0.0
25
+ Requires-Dist: pdfplumber>=0.11
26
+ Requires-Dist: pydantic-settings>=2.5
27
+ Requires-Dist: pydantic<3,>=2.7
28
+ Requires-Dist: pyjwt[crypto]>=2.9
29
+ Requires-Dist: python-dotenv>=1.0
30
+ Requires-Dist: sqlalchemy[asyncio]<3,>=2.0
31
+ Requires-Dist: sqlite-vec>=0.1.6
32
+ Requires-Dist: sse-starlette>=2.1.0
33
+ Requires-Dist: uuid7>=0.1
34
+ Requires-Dist: uvicorn>=0.32.0
35
+ Provides-Extra: all
36
+ Requires-Dist: google-genai>=1.0.0; extra == 'all'
37
+ Requires-Dist: langchain-anthropic>=1.0.0; extra == 'all'
38
+ Requires-Dist: langchain-aws>=0.2.0; extra == 'all'
39
+ Requires-Dist: langchain-google-genai>=2.0.0; extra == 'all'
40
+ Requires-Dist: langchain-groq>=0.2.0; extra == 'all'
41
+ Requires-Dist: langchain-openai>=0.2.0; extra == 'all'
42
+ Requires-Dist: langgraph-checkpoint-postgres>=2.0; extra == 'all'
43
+ Requires-Dist: pgvector>=0.3; extra == 'all'
44
+ Requires-Dist: psycopg[binary]>=3.2; extra == 'all'
45
+ Requires-Dist: tavily-python>=0.5; extra == 'all'
46
+ Provides-Extra: anthropic
47
+ Requires-Dist: langchain-anthropic>=1.0.0; extra == 'anthropic'
48
+ Provides-Extra: bedrock
49
+ Requires-Dist: langchain-aws>=0.2.0; extra == 'bedrock'
50
+ Provides-Extra: google-genai
51
+ Requires-Dist: google-genai>=1.0.0; extra == 'google-genai'
52
+ Requires-Dist: langchain-google-genai>=2.0.0; extra == 'google-genai'
53
+ Provides-Extra: groq
54
+ Requires-Dist: langchain-groq>=0.2.0; extra == 'groq'
55
+ Provides-Extra: openai
56
+ Requires-Dist: langchain-openai>=0.2.0; extra == 'openai'
57
+ Provides-Extra: postgres
58
+ Requires-Dist: langgraph-checkpoint-postgres>=2.0; extra == 'postgres'
59
+ Requires-Dist: pgvector>=0.3; extra == 'postgres'
60
+ Requires-Dist: psycopg[binary]>=3.2; extra == 'postgres'
61
+ Provides-Extra: pywry
62
+ Requires-Dist: pywry>=2.0.4; extra == 'pywry'
63
+ Provides-Extra: tavily
64
+ Requires-Dist: tavily-python>=0.5; extra == 'tavily'
65
+ Provides-Extra: vertex
66
+ Requires-Dist: google-genai>=1.0.0; extra == 'vertex'
67
+ Requires-Dist: langchain-google-genai>=2.0.0; extra == 'vertex'
68
+ Description-Content-Type: text/markdown
69
+
70
+ # openbb-agent-server
71
+
72
+ Pluggable, multi-tenant agent backend that speaks the [OpenBB Workspace
73
+ custom-agent SSE protocol](https://docs.openbb.co/workspace/developers/agents-integration) and runs the agent loop
74
+ on top of the [LangChain DeepAgents harness](https://docs.langchain.com/oss/python/deepagents/overview). One process
75
+ hosts many agent profiles; auth, model provider, tools, sub-agents,
76
+ middleware, checkpointer, and persistence are independent plugin axes
77
+ — anything can be swapped without forking the package.
78
+
79
+ <img width="1580" height="834" alt="openbb-agent-server-screenshot" src="https://github.com/user-attachments/assets/f6ed834a-4232-4cbb-a039-275f30dafad9" />
80
+
81
+ The full OpenBB Platform — every command across every installed
82
+ provider — is reachable via the optional `mcp_local` tool source,
83
+ which spawns the
84
+ [`openbb-mcp-server`](https://github.com/OpenBB-finance/OpenBB/tree/main/openbb_platform/extensions/mcp_server)
85
+ extension over stdio.
86
+
87
+ The default setup uses 100% free tokens and embedding models available from [NVIDIA](https://build.nvidia.com/) by registering for an API key [here](https://developer.nvidia.com/login)
88
+
89
+ ## Install & run
90
+
91
+ ```bash
92
+ # from PyPI
93
+ pip install openbb-agent-server
94
+
95
+ # from a checkout of this repository
96
+ pip install -e '.[workspace-mcp]'
97
+ # add or combine more extras: [anthropic] [openai] [bedrock]
98
+ # [vertex] [google_genai] [groq]
99
+ # [tavily] [postgres]
100
+ # [pywry] (desktop chat embedding)
101
+
102
+ export NVIDIA_API_KEY=...
103
+
104
+ openbb-agent-server
105
+ ```
106
+
107
+ In OpenBB Workspace, add a custom agent pointing at
108
+ `http://localhost:8010`. Workspace fetches this once and
109
+ reads every agent profile the server registers in a single payload.
110
+
111
+ The `[workspace-mcp]` extra installs
112
+ [openbb-workspace-mcp](https://github.com/OpenBB-finance/workspace-mcp)
113
+ from its GitHub zip (Python ≥3.13 only). To run it in-process and skip
114
+ the separate `workspace-mcp` sidecar, set `mount_workspace_mcp = true`
115
+ in `openbb.toml` after installing the extra, then point the Workspace
116
+ UI's MCP-servers setting at `http://localhost:8010/mcp/workspace/mcp`.
117
+ The mount is **opt-in** (default `false`) so installing the extra alone
118
+ does not change the server's behavior.
119
+
120
+ For production, generate the config template and edit it:
121
+
122
+ ```bash
123
+ openbb-agent-server --generate-config /etc/openbb/openbb.toml
124
+ openbb-agent-server --config-file /etc/openbb/openbb.toml --host 0.0.0.0
125
+ ```
126
+
127
+ ## Documentation
128
+
129
+ Documentation currently lives in [`docs/`](docs/README.md), and may move in the future:
130
+
131
+ | Audience | Start here |
132
+ | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
133
+ | First-time user | [Getting started](docs/guides/getting-started.md) → [Architecture](docs/guides/architecture.md) → [Workspace integration](docs/guides/workspace-integration.md) |
134
+ | Desktop embedding | [PyWry chat (ACP)](docs/guides/pywry-chat.md) — `openbb-agent-canvas` opens a window whose main page is the agent's live canvas (charts, tables, HTML) with the chat attached; or attach the chat to any PyWry widget via the `[pywry]` extra. Same `openbb.toml`, same loop, no HTTP server |
135
+ | Operator / SRE | [Configuration](docs/operating/configuration.md) → [Auth](docs/operating/auth.md) → [Persistence](docs/operating/persistence.md) → [Observability](docs/operating/observability.md) |
136
+ | Plugin author | [Plugin system](docs/developing/plugin-system.md) → writing a [tool source](docs/developing/writing-a-tool-source.md) / [model provider](docs/developing/writing-a-model-provider.md) / [middleware](docs/developing/writing-a-middleware.md) / [sub-agent](docs/developing/writing-a-subagent.md) / [auth backend](docs/developing/writing-an-auth-backend.md) → [Conventions](docs/developing/conventions.md) → [Testing](docs/developing/testing.md) |
137
+ | API lookup | [Reference](docs/reference/) — module-by-module, mirrors the package tree |
@@ -0,0 +1,68 @@
1
+ # openbb-agent-server
2
+
3
+ Pluggable, multi-tenant agent backend that speaks the [OpenBB Workspace
4
+ custom-agent SSE protocol](https://docs.openbb.co/workspace/developers/agents-integration) and runs the agent loop
5
+ on top of the [LangChain DeepAgents harness](https://docs.langchain.com/oss/python/deepagents/overview). One process
6
+ hosts many agent profiles; auth, model provider, tools, sub-agents,
7
+ middleware, checkpointer, and persistence are independent plugin axes
8
+ — anything can be swapped without forking the package.
9
+
10
+ <img width="1580" height="834" alt="openbb-agent-server-screenshot" src="https://github.com/user-attachments/assets/f6ed834a-4232-4cbb-a039-275f30dafad9" />
11
+
12
+ The full OpenBB Platform — every command across every installed
13
+ provider — is reachable via the optional `mcp_local` tool source,
14
+ which spawns the
15
+ [`openbb-mcp-server`](https://github.com/OpenBB-finance/OpenBB/tree/main/openbb_platform/extensions/mcp_server)
16
+ extension over stdio.
17
+
18
+ The default setup uses 100% free tokens and embedding models available from [NVIDIA](https://build.nvidia.com/) by registering for an API key [here](https://developer.nvidia.com/login)
19
+
20
+ ## Install & run
21
+
22
+ ```bash
23
+ # from PyPI
24
+ pip install openbb-agent-server
25
+
26
+ # from a checkout of this repository
27
+ pip install -e '.[workspace-mcp]'
28
+ # add or combine more extras: [anthropic] [openai] [bedrock]
29
+ # [vertex] [google_genai] [groq]
30
+ # [tavily] [postgres]
31
+ # [pywry] (desktop chat embedding)
32
+
33
+ export NVIDIA_API_KEY=...
34
+
35
+ openbb-agent-server
36
+ ```
37
+
38
+ In OpenBB Workspace, add a custom agent pointing at
39
+ `http://localhost:8010`. Workspace fetches this once and
40
+ reads every agent profile the server registers in a single payload.
41
+
42
+ The `[workspace-mcp]` extra installs
43
+ [openbb-workspace-mcp](https://github.com/OpenBB-finance/workspace-mcp)
44
+ from its GitHub zip (Python ≥3.13 only). To run it in-process and skip
45
+ the separate `workspace-mcp` sidecar, set `mount_workspace_mcp = true`
46
+ in `openbb.toml` after installing the extra, then point the Workspace
47
+ UI's MCP-servers setting at `http://localhost:8010/mcp/workspace/mcp`.
48
+ The mount is **opt-in** (default `false`) so installing the extra alone
49
+ does not change the server's behavior.
50
+
51
+ For production, generate the config template and edit it:
52
+
53
+ ```bash
54
+ openbb-agent-server --generate-config /etc/openbb/openbb.toml
55
+ openbb-agent-server --config-file /etc/openbb/openbb.toml --host 0.0.0.0
56
+ ```
57
+
58
+ ## Documentation
59
+
60
+ Documentation currently lives in [`docs/`](docs/README.md), and may move in the future:
61
+
62
+ | Audience | Start here |
63
+ | ---------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
64
+ | First-time user | [Getting started](docs/guides/getting-started.md) → [Architecture](docs/guides/architecture.md) → [Workspace integration](docs/guides/workspace-integration.md) |
65
+ | Desktop embedding | [PyWry chat (ACP)](docs/guides/pywry-chat.md) — `openbb-agent-canvas` opens a window whose main page is the agent's live canvas (charts, tables, HTML) with the chat attached; or attach the chat to any PyWry widget via the `[pywry]` extra. Same `openbb.toml`, same loop, no HTTP server |
66
+ | Operator / SRE | [Configuration](docs/operating/configuration.md) → [Auth](docs/operating/auth.md) → [Persistence](docs/operating/persistence.md) → [Observability](docs/operating/observability.md) |
67
+ | Plugin author | [Plugin system](docs/developing/plugin-system.md) → writing a [tool source](docs/developing/writing-a-tool-source.md) / [model provider](docs/developing/writing-a-model-provider.md) / [middleware](docs/developing/writing-a-middleware.md) / [sub-agent](docs/developing/writing-a-subagent.md) / [auth backend](docs/developing/writing-an-auth-backend.md) → [Conventions](docs/developing/conventions.md) → [Testing](docs/developing/testing.md) |
68
+ | API lookup | [Reference](docs/reference/) — module-by-module, mirrors the package tree |
@@ -0,0 +1,17 @@
1
+ """OpenBB Platform Agent Server — pluggable, multi-tenant agent backend."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import warnings
6
+
7
+ __version__ = "0.1.0"
8
+
9
+ from langchain_core._api.deprecation import ( # noqa: E402
10
+ LangChainPendingDeprecationWarning,
11
+ )
12
+
13
+ warnings.filterwarnings(
14
+ "ignore",
15
+ message=r"The default value of `allowed_objects` will change.*",
16
+ category=LangChainPendingDeprecationWarning,
17
+ )
@@ -0,0 +1,135 @@
1
+ """Vendored SQLiteVec vector store.
2
+
3
+ Adapted from ``langchain_community.vectorstores.sqlitevec`` (MIT licence)
4
+ to remove the ``langchain-community`` dependency, which is now archived.
5
+
6
+ Only the surface used by this project is kept:
7
+
8
+ * ``create_table_if_not_exists``
9
+ * ``add_texts``
10
+ * ``similarity_search_with_score``
11
+
12
+ The class intentionally does **not** manage connection lifecycle — the
13
+ caller is responsible for opening and closing the ``sqlite3.Connection``.
14
+ """
15
+
16
+ from __future__ import annotations
17
+
18
+ import json
19
+ import sqlite3
20
+ import struct
21
+ from typing import Any
22
+
23
+ from langchain_core.documents import Document
24
+ from langchain_core.embeddings import Embeddings
25
+
26
+
27
+ def _serialize_f32(vector: list[float]) -> bytes:
28
+ """Pack a float vector into the raw-bytes format sqlite-vec expects."""
29
+ return struct.pack(f"{len(vector)}f", *vector)
30
+
31
+
32
+ class SQLiteVec:
33
+ """Thin wrapper around a ``sqlite-vec`` virtual table.
34
+
35
+ Requires a pre-configured ``sqlite3.Connection`` with the ``sqlite-vec``
36
+ extension already loaded.
37
+ """
38
+
39
+ def __init__(
40
+ self,
41
+ table: str,
42
+ connection: sqlite3.Connection,
43
+ embedding: Embeddings,
44
+ db_file: str = "vec.db",
45
+ ) -> None:
46
+ self._connection = connection
47
+ self._table = table
48
+ self._embedding = embedding
49
+
50
+ # ------------------------------------------------------------------
51
+ # Schema helpers
52
+ # ------------------------------------------------------------------
53
+
54
+ def create_table_if_not_exists(self) -> None:
55
+ """Create the data table, vec0 virtual table, and insert trigger."""
56
+ dim = len(self._embedding.embed_query("dim probe"))
57
+ self._connection.execute(
58
+ f"CREATE TABLE IF NOT EXISTS {self._table}"
59
+ " (rowid INTEGER PRIMARY KEY AUTOINCREMENT,"
60
+ " text TEXT, metadata BLOB, text_embedding BLOB)"
61
+ )
62
+ self._connection.execute(
63
+ f"CREATE VIRTUAL TABLE IF NOT EXISTS {self._table}_vec"
64
+ f" USING vec0(rowid INTEGER PRIMARY KEY,"
65
+ f" text_embedding float[{dim}])"
66
+ )
67
+ self._connection.execute(
68
+ f"CREATE TRIGGER IF NOT EXISTS {self._table}_embed_text "
69
+ f"AFTER INSERT ON {self._table} BEGIN"
70
+ f" INSERT INTO {self._table}_vec(rowid, text_embedding)"
71
+ f" VALUES (new.rowid, new.text_embedding); END;"
72
+ )
73
+ self._connection.commit()
74
+
75
+ # ------------------------------------------------------------------
76
+ # Write
77
+ # ------------------------------------------------------------------
78
+
79
+ def add_texts(
80
+ self,
81
+ texts: list[str],
82
+ metadatas: list[dict[str, Any]],
83
+ **kwargs: Any,
84
+ ) -> list[int]:
85
+ """Embed *texts* and insert them into the store.
86
+
87
+ Returns the ``rowid`` values of the newly inserted rows.
88
+ """
89
+ row = self._connection.execute(
90
+ f"SELECT max(rowid) AS rowid FROM {self._table}"
91
+ ).fetchone()
92
+ max_id: int = row["rowid"] if row["rowid"] is not None else 0
93
+
94
+ embeds = self._embedding.embed_documents(list(texts))
95
+
96
+ self._connection.executemany(
97
+ f"INSERT INTO {self._table}(text, metadata, text_embedding)"
98
+ " VALUES (?, ?, ?)",
99
+ [
100
+ (text, json.dumps(meta), _serialize_f32(emb))
101
+ for text, meta, emb in zip(texts, metadatas, embeds)
102
+ ],
103
+ )
104
+ self._connection.commit()
105
+
106
+ rows = self._connection.execute(
107
+ f"SELECT rowid FROM {self._table} WHERE rowid > {max_id}"
108
+ )
109
+ return [r["rowid"] for r in rows]
110
+
111
+ # ------------------------------------------------------------------
112
+ # Read
113
+ # ------------------------------------------------------------------
114
+
115
+ def similarity_search_with_score(
116
+ self, query: str, k: int = 4, **kwargs: Any
117
+ ) -> list[tuple[Document, float]]:
118
+ """Return the *k* closest documents with their distance scores."""
119
+ embedding = self._embedding.embed_query(query)
120
+ cursor = self._connection.cursor()
121
+ cursor.execute(
122
+ f"SELECT text, metadata, distance"
123
+ f" FROM {self._table} AS e"
124
+ f" INNER JOIN {self._table}_vec AS v ON v.rowid = e.rowid"
125
+ f" WHERE v.text_embedding MATCH ? AND k = ?"
126
+ f" ORDER BY distance",
127
+ [_serialize_f32(embedding), k],
128
+ )
129
+ results: list[tuple[Document, float]] = []
130
+ for row in cursor.fetchall():
131
+ meta = json.loads(row["metadata"]) if row["metadata"] else {}
132
+ results.append(
133
+ (Document(page_content=row["text"], metadata=meta), row["distance"])
134
+ )
135
+ return results
@@ -0,0 +1,32 @@
1
+ """ACP shim — expose the agent loop to PyWry chat components.
2
+
3
+ Lazy re-exports so ``import openbb_agent_server.acp`` works without
4
+ pywry installed; the ImportError with install instructions surfaces on
5
+ first attribute access instead. ``PyWryCanvas`` / ``build_canvas_html``
6
+ are pywry-free and always importable.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ from importlib import import_module
12
+ from typing import Any
13
+
14
+ _EXPORTS: dict[str, str] = {
15
+ "OpenBBAgentProvider": "openbb_agent_server.acp.provider",
16
+ "create_chat_manager": "openbb_agent_server.acp.provider",
17
+ "translate_sse": "openbb_agent_server.acp.provider",
18
+ "launch": "openbb_agent_server.acp.canvas_app",
19
+ "CanvasApp": "openbb_agent_server.acp.canvas_app",
20
+ "PyWryCanvas": "openbb_agent_server.acp.canvas",
21
+ "build_canvas_html": "openbb_agent_server.acp.canvas",
22
+ }
23
+
24
+ __all__ = list(_EXPORTS)
25
+
26
+
27
+ def __getattr__(name: str) -> Any:
28
+ """Defer submodule imports until a symbol is actually used."""
29
+ module_path = _EXPORTS.get(name)
30
+ if module_path is None:
31
+ raise AttributeError(f"module {__name__!r} has no attribute {name!r}")
32
+ return getattr(import_module(module_path), name)