agno-lark 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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 agno-lark contributors
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,251 @@
1
+ Metadata-Version: 2.3
2
+ Name: agno-lark
3
+ Version: 0.1.0
4
+ Summary: A lightweight Python bridge between Lark/Feishu and Agno AgentOS.
5
+ Keywords: agno,agentos,lark,feishu,im,websocket
6
+ Author: _白开水_
7
+ Author-email: _白开水_ <pkk518@gmail.com>
8
+ License: MIT License
9
+
10
+ Copyright (c) 2026 agno-lark contributors
11
+
12
+ Permission is hereby granted, free of charge, to any person obtaining a copy
13
+ of this software and associated documentation files (the "Software"), to deal
14
+ in the Software without restriction, including without limitation the rights
15
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16
+ copies of the Software, and to permit persons to whom the Software is
17
+ furnished to do so, subject to the following conditions:
18
+
19
+ The above copyright notice and this permission notice shall be included in all
20
+ copies or substantial portions of the Software.
21
+
22
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
28
+ SOFTWARE.
29
+ Classifier: Development Status :: 3 - Alpha
30
+ Classifier: Intended Audience :: Developers
31
+ Classifier: Operating System :: OS Independent
32
+ Classifier: Programming Language :: Python :: 3
33
+ Classifier: Programming Language :: Python :: 3.12
34
+ Classifier: Programming Language :: Python :: 3.13
35
+ Classifier: Topic :: Communications :: Chat
36
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
37
+ Requires-Dist: agno[os]>=3.1,<4
38
+ Requires-Dist: aiosqlite>=0.20,<1
39
+ Requires-Dist: httpx[socks]>=0.28,<1
40
+ Requires-Dist: lark-channel-sdk>=1.4,<2
41
+ Requires-Dist: pydantic-settings>=2.6,<3
42
+ Requires-Python: >=3.12, <4
43
+ Project-URL: Homepage, https://github.com/pangkk18/agno-lark
44
+ Project-URL: Repository, https://github.com/pangkk18/agno-lark
45
+ Project-URL: Issues, https://github.com/pangkk18/agno-lark/issues
46
+ Description-Content-Type: text/markdown
47
+
48
+ # agno-lark
49
+
50
+ A lightweight Python bridge between Lark/Feishu IM and Agno AgentOS.
51
+
52
+ `agno-lark` (import package: `agno_lark`) runs as an independent bridge process. It uses the official `lark-channel-sdk` WebSocket channel to receive Lark/Feishu messages, forwards them to an AgentOS agent, team, or workflow, and stores deduplication, session generations, and run records in SQLite.
53
+
54
+ ```mermaid
55
+ flowchart LR
56
+ U[Lark/Feishu user] --> C[FeishuChannel\nWebSocket]
57
+ C --> B[agno-lark\nLarkInterface]
58
+ B --> S[(SQLite\ndedup / sessions / runs)]
59
+ B --> A[AgentOS\nagent / team / workflow]
60
+ A --> B
61
+ B --> C
62
+ ```
63
+
64
+ The Chinese documentation is available in [`READM_ZH.md`](READM_ZH.md).
65
+
66
+ ## Features
67
+
68
+ - Persistent Lark/Feishu WebSocket connection; HTTP webhook mode is not required.
69
+ - Direct messages and group messages that mention the bot.
70
+ - Text replies, image resources, and file resources converted to Agno media objects.
71
+ - Remote AgentOS targets for `agent`, `team`, and `workflow`.
72
+ - User, chat, and thread session isolation with `/new` generation resets.
73
+ - Configurable group context:
74
+ - `user` (default): each member who mentions the bot gets an independent context.
75
+ - `shared`: members share one context for the same chat and thread.
76
+ - SQLite message deduplication, run records, TTL cleanup, WAL, and busy-timeout handling.
77
+ - Streaming Feishu cards with status, run ID, elapsed time, and cancellation actions.
78
+ - `/new`, `/status`, `/cancel [run_id]`, and `/help` commands.
79
+ - User and chat allowlists, reconnect handling, error handling, and structured logging.
80
+
81
+ The first release does not process audio, video, or voice messages and does not implement HITL resume approval. Long-running tasks use foreground SSE streaming.
82
+
83
+ ## Requirements and installation
84
+
85
+ Python 3.12 or newer (and lower than 4.0) is required. [uv](https://docs.astral.sh/uv/) is recommended:
86
+
87
+ ```bash
88
+ uv sync
89
+ cp .env.example .env
90
+ ```
91
+
92
+ After the first PyPI release, install the published package in an existing project with either:
93
+
94
+ ```bash
95
+ uv add agno-lark
96
+ # or
97
+ python -m pip install agno-lark
98
+ ```
99
+
100
+ The distribution name uses a hyphen (`agno-lark`), while Python imports use an underscore:
101
+
102
+ ```python
103
+ from agno_lark import LarkInterface, build_remote_target, load_settings
104
+ ```
105
+
106
+ The package also installs the `agno-lark` command. After installation, run the bridge with:
107
+
108
+ ```bash
109
+ agno-lark --help
110
+ agno-lark
111
+ ```
112
+
113
+ ## Create the Lark/Feishu application
114
+
115
+ Create an enterprise application in the Lark or Feishu Open Platform and enable bot capabilities. Record the App ID (`cli_...`) and App Secret. Select the long connection (WebSocket) mode in event subscriptions and subscribe to message events. Grant the permissions required to receive and send messages, read image/file resources, and send card messages. Publish the application and add the bot to the target chats.
116
+
117
+ The official Channel SDK handles the WebSocket connection, event normalization, resource downloads, deduplication, and card callbacks. This project does not require a separate webhook endpoint.
118
+
119
+ ## Configuration
120
+
121
+ Copy `.env.example` and fill in the values below. The `FEISHU_*` prefix is retained for compatibility with existing Lark/Feishu application configuration; the distribution and import names are `agno-lark` and `agno_lark`.
122
+
123
+ ```dotenv
124
+ FEISHU_APP_ID=cli_xxx
125
+ FEISHU_APP_SECRET=xxx
126
+
127
+ AGENTOS_URL=http://127.0.0.1:7777
128
+ AGENTOS_TOKEN=xxx
129
+ AGENTOS_TARGET_TYPE=agent
130
+ AGENTOS_TARGET_ID=assistant
131
+ # Legacy alias for an agent target:
132
+ # AGENTOS_AGENT_ID=assistant
133
+
134
+ FEISHU_STATE_DB=.data/agno-feishu.sqlite3
135
+ FEISHU_ALLOWED_USER_IDS=
136
+ FEISHU_ALLOWED_CHAT_IDS=
137
+ # user (default: one context per member) or shared (one context per chat/thread)
138
+ FEISHU_GROUP_SESSION_MODE=user
139
+
140
+ BRIDGE_HOST=127.0.0.1
141
+ BRIDGE_PORT=7788
142
+ ```
143
+
144
+ Allowlist values are comma-separated. If both allowlists are empty, access is open; production deployments should configure at least one allowlist. `AGENTOS_TOKEN` may be empty for a public AgentOS, but a Bearer token is recommended for production.
145
+
146
+ `FEISHU_GROUP_SESSION_MODE` affects group chats only. In `user` mode, the scope includes `sender.open_id`; in `shared` mode, the scope includes the chat and thread but not the sender. Direct messages are always isolated by their direct-message chat. The default SQLite filename remains `.data/agno-feishu.sqlite3` so existing state data can be reused.
147
+
148
+ ## Quick start with a remote AgentOS
149
+
150
+ Start AgentOS at `AGENTOS_URL`, then run the bridge:
151
+
152
+ ```bash
153
+ uv run agno-lark
154
+ uv run agno-lark --host 0.0.0.0 --port 7788
155
+ ```
156
+
157
+ The bridge creates a `RemoteAgent`, `RemoteTeam`, or `RemoteWorkflow` from `AGENTOS_TARGET_TYPE` and mounts the Lark/Feishu interface into the local AgentOS gateway. The status endpoint is `GET /feishu/status`; this path is retained for compatibility with existing deployments.
158
+
159
+ ## Embed in an existing AgentOS application
160
+
161
+ ```python
162
+ from agno.os import AgentOS
163
+ from agno_lark import LarkInterface, build_remote_target, load_settings
164
+
165
+ settings = load_settings()
166
+ target = build_remote_target(settings)
167
+ lark = LarkInterface(target=target, settings=settings)
168
+
169
+ agent_os = AgentOS(
170
+ agents=[target] if settings.target_type == "agent" else None,
171
+ teams=[target] if settings.target_type == "team" else None,
172
+ workflows=[target] if settings.target_type == "workflow" else None,
173
+ interfaces=[lark],
174
+ )
175
+ app = agent_os.get_app()
176
+ ```
177
+
178
+ `LarkInterface.get_router()` returns a FastAPI `APIRouter` with a managed lifespan. Startup opens the SQLite store and connects `FeishuChannel`; shutdown disconnects the channel and closes the store. Only the asynchronous AgentOS execution path is supported. `FeishuInterface` remains exported as a compatibility alias.
179
+
180
+ ## Messages, sessions, and commands
181
+
182
+ - Direct messages are handled immediately; group messages must mention the bot.
183
+ - `user_id` is taken from `sender.open_id`.
184
+ - In the default `user` group mode, a scope can look like `feishu:agent:assistant:chat_oc_xxx:thread_omt_xxx:user:ou_xxx:v3`.
185
+ - In `shared` group mode, the same chat/thread uses a scope such as `feishu:agent:assistant:chat_oc_xxx:thread_omt_xxx:v3` for every member, while each AgentOS run still receives the sender's `user_id`.
186
+ - `/new` increments the generation for the current user scope or shared chat/thread scope.
187
+
188
+ | Command | Behavior |
189
+ | --- | --- |
190
+ | `/new` | Increment the current scope generation and start a fresh session. |
191
+ | `/status` | Show active and recent runs for the current scope. |
192
+ | `/cancel` | Cancel the most recent active run for the current scope. |
193
+ | `/cancel <run_id>` | Request cancellation of a specific run. |
194
+ | `/help` | Show the command help card. |
195
+
196
+ Cancellation first records `cancel_requested` and then calls the scoped AgentOS cancel endpoint. The final state comes from the SSE terminal event. Card actions re-check the operator and chat allowlists before starting status or cancellation work.
197
+
198
+ ## State database and troubleshooting
199
+
200
+ The default database `.data/agno-feishu.sqlite3` uses WAL and a busy timeout. It contains `schema_version`, `dedup_messages`, `session_scopes`, and `runs`. Message deduplication defaults to 24 hours and run records are retained for 7 days.
201
+
202
+ If no messages arrive, check application publication, WebSocket subscriptions, bot membership, and allowlists. For 401/403 responses, check the AgentOS token, target ID, and AgentOS authorization. For resource failures, check Lark/Feishu resource-read permissions. Logs do not include the App Secret, AgentOS token, raw file contents, or complete user messages.
203
+
204
+ If your shell exports a SOCKS proxy and the local environment does not have `socksio`, set `NO_PROXY=127.0.0.1,localhost` (and the AgentOS hostname) when testing a local AgentOS. If outbound AgentOS requests must use a SOCKS proxy, install the HTTPX SOCKS extra in the deployment environment with `uv pip install "httpx[socks]>=0.28,<1"`.
205
+
206
+ ## Development
207
+
208
+ ```bash
209
+ uv sync
210
+ uv run pytest
211
+ uv run ruff check .
212
+ uv run mypy src
213
+ uv build
214
+ uv run agno-lark --help
215
+ ```
216
+
217
+ Tests use fake Channel and Agno targets plus `httpx` mocks; they do not contact Lark/Feishu or AgentOS. See [`examples/agent_os_remote.py`](examples/agent_os_remote.py) for the remote integration example.
218
+
219
+ ## Release and publish
220
+
221
+ The package will be published to [PyPI](https://pypi.org/project/agno-lark/) as `agno-lark`. Every release version must be unique. Update `version` in `pyproject.toml`, then run the local checks and build:
222
+
223
+ ```bash
224
+ uv lock
225
+ uv sync --locked
226
+ uv run pytest
227
+ uv run ruff check .
228
+ uv run mypy src
229
+ uv build
230
+ ```
231
+
232
+ For a first release or a manual release, create a PyPI API token and publish without putting the token in the repository or shell history:
233
+
234
+ ```bash
235
+ export UV_PUBLISH_TOKEN='pypi-...'
236
+ uv publish
237
+ ```
238
+
239
+ To verify a release on TestPyPI first, use a TestPyPI token and the TestPyPI upload endpoint:
240
+
241
+ ```bash
242
+ export UV_PUBLISH_TOKEN='pypi-...'
243
+ uv publish --publish-url https://test.pypi.org/legacy/
244
+ uv pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ agno-lark
245
+ ```
246
+
247
+ This repository also includes a GitHub Actions workflow for PyPI Trusted Publishing. Configure the GitHub repository as a trusted publisher for the `agno-lark` project on PyPI, then push a tag such as `v0.1.0`; the workflow builds and publishes without a long-lived PyPI token.
248
+
249
+ ## License
250
+
251
+ This project is released under the MIT License. See [`LICENSE`](LICENSE).
@@ -0,0 +1,204 @@
1
+ # agno-lark
2
+
3
+ A lightweight Python bridge between Lark/Feishu IM and Agno AgentOS.
4
+
5
+ `agno-lark` (import package: `agno_lark`) runs as an independent bridge process. It uses the official `lark-channel-sdk` WebSocket channel to receive Lark/Feishu messages, forwards them to an AgentOS agent, team, or workflow, and stores deduplication, session generations, and run records in SQLite.
6
+
7
+ ```mermaid
8
+ flowchart LR
9
+ U[Lark/Feishu user] --> C[FeishuChannel\nWebSocket]
10
+ C --> B[agno-lark\nLarkInterface]
11
+ B --> S[(SQLite\ndedup / sessions / runs)]
12
+ B --> A[AgentOS\nagent / team / workflow]
13
+ A --> B
14
+ B --> C
15
+ ```
16
+
17
+ The Chinese documentation is available in [`READM_ZH.md`](READM_ZH.md).
18
+
19
+ ## Features
20
+
21
+ - Persistent Lark/Feishu WebSocket connection; HTTP webhook mode is not required.
22
+ - Direct messages and group messages that mention the bot.
23
+ - Text replies, image resources, and file resources converted to Agno media objects.
24
+ - Remote AgentOS targets for `agent`, `team`, and `workflow`.
25
+ - User, chat, and thread session isolation with `/new` generation resets.
26
+ - Configurable group context:
27
+ - `user` (default): each member who mentions the bot gets an independent context.
28
+ - `shared`: members share one context for the same chat and thread.
29
+ - SQLite message deduplication, run records, TTL cleanup, WAL, and busy-timeout handling.
30
+ - Streaming Feishu cards with status, run ID, elapsed time, and cancellation actions.
31
+ - `/new`, `/status`, `/cancel [run_id]`, and `/help` commands.
32
+ - User and chat allowlists, reconnect handling, error handling, and structured logging.
33
+
34
+ The first release does not process audio, video, or voice messages and does not implement HITL resume approval. Long-running tasks use foreground SSE streaming.
35
+
36
+ ## Requirements and installation
37
+
38
+ Python 3.12 or newer (and lower than 4.0) is required. [uv](https://docs.astral.sh/uv/) is recommended:
39
+
40
+ ```bash
41
+ uv sync
42
+ cp .env.example .env
43
+ ```
44
+
45
+ After the first PyPI release, install the published package in an existing project with either:
46
+
47
+ ```bash
48
+ uv add agno-lark
49
+ # or
50
+ python -m pip install agno-lark
51
+ ```
52
+
53
+ The distribution name uses a hyphen (`agno-lark`), while Python imports use an underscore:
54
+
55
+ ```python
56
+ from agno_lark import LarkInterface, build_remote_target, load_settings
57
+ ```
58
+
59
+ The package also installs the `agno-lark` command. After installation, run the bridge with:
60
+
61
+ ```bash
62
+ agno-lark --help
63
+ agno-lark
64
+ ```
65
+
66
+ ## Create the Lark/Feishu application
67
+
68
+ Create an enterprise application in the Lark or Feishu Open Platform and enable bot capabilities. Record the App ID (`cli_...`) and App Secret. Select the long connection (WebSocket) mode in event subscriptions and subscribe to message events. Grant the permissions required to receive and send messages, read image/file resources, and send card messages. Publish the application and add the bot to the target chats.
69
+
70
+ The official Channel SDK handles the WebSocket connection, event normalization, resource downloads, deduplication, and card callbacks. This project does not require a separate webhook endpoint.
71
+
72
+ ## Configuration
73
+
74
+ Copy `.env.example` and fill in the values below. The `FEISHU_*` prefix is retained for compatibility with existing Lark/Feishu application configuration; the distribution and import names are `agno-lark` and `agno_lark`.
75
+
76
+ ```dotenv
77
+ FEISHU_APP_ID=cli_xxx
78
+ FEISHU_APP_SECRET=xxx
79
+
80
+ AGENTOS_URL=http://127.0.0.1:7777
81
+ AGENTOS_TOKEN=xxx
82
+ AGENTOS_TARGET_TYPE=agent
83
+ AGENTOS_TARGET_ID=assistant
84
+ # Legacy alias for an agent target:
85
+ # AGENTOS_AGENT_ID=assistant
86
+
87
+ FEISHU_STATE_DB=.data/agno-feishu.sqlite3
88
+ FEISHU_ALLOWED_USER_IDS=
89
+ FEISHU_ALLOWED_CHAT_IDS=
90
+ # user (default: one context per member) or shared (one context per chat/thread)
91
+ FEISHU_GROUP_SESSION_MODE=user
92
+
93
+ BRIDGE_HOST=127.0.0.1
94
+ BRIDGE_PORT=7788
95
+ ```
96
+
97
+ Allowlist values are comma-separated. If both allowlists are empty, access is open; production deployments should configure at least one allowlist. `AGENTOS_TOKEN` may be empty for a public AgentOS, but a Bearer token is recommended for production.
98
+
99
+ `FEISHU_GROUP_SESSION_MODE` affects group chats only. In `user` mode, the scope includes `sender.open_id`; in `shared` mode, the scope includes the chat and thread but not the sender. Direct messages are always isolated by their direct-message chat. The default SQLite filename remains `.data/agno-feishu.sqlite3` so existing state data can be reused.
100
+
101
+ ## Quick start with a remote AgentOS
102
+
103
+ Start AgentOS at `AGENTOS_URL`, then run the bridge:
104
+
105
+ ```bash
106
+ uv run agno-lark
107
+ uv run agno-lark --host 0.0.0.0 --port 7788
108
+ ```
109
+
110
+ The bridge creates a `RemoteAgent`, `RemoteTeam`, or `RemoteWorkflow` from `AGENTOS_TARGET_TYPE` and mounts the Lark/Feishu interface into the local AgentOS gateway. The status endpoint is `GET /feishu/status`; this path is retained for compatibility with existing deployments.
111
+
112
+ ## Embed in an existing AgentOS application
113
+
114
+ ```python
115
+ from agno.os import AgentOS
116
+ from agno_lark import LarkInterface, build_remote_target, load_settings
117
+
118
+ settings = load_settings()
119
+ target = build_remote_target(settings)
120
+ lark = LarkInterface(target=target, settings=settings)
121
+
122
+ agent_os = AgentOS(
123
+ agents=[target] if settings.target_type == "agent" else None,
124
+ teams=[target] if settings.target_type == "team" else None,
125
+ workflows=[target] if settings.target_type == "workflow" else None,
126
+ interfaces=[lark],
127
+ )
128
+ app = agent_os.get_app()
129
+ ```
130
+
131
+ `LarkInterface.get_router()` returns a FastAPI `APIRouter` with a managed lifespan. Startup opens the SQLite store and connects `FeishuChannel`; shutdown disconnects the channel and closes the store. Only the asynchronous AgentOS execution path is supported. `FeishuInterface` remains exported as a compatibility alias.
132
+
133
+ ## Messages, sessions, and commands
134
+
135
+ - Direct messages are handled immediately; group messages must mention the bot.
136
+ - `user_id` is taken from `sender.open_id`.
137
+ - In the default `user` group mode, a scope can look like `feishu:agent:assistant:chat_oc_xxx:thread_omt_xxx:user:ou_xxx:v3`.
138
+ - In `shared` group mode, the same chat/thread uses a scope such as `feishu:agent:assistant:chat_oc_xxx:thread_omt_xxx:v3` for every member, while each AgentOS run still receives the sender's `user_id`.
139
+ - `/new` increments the generation for the current user scope or shared chat/thread scope.
140
+
141
+ | Command | Behavior |
142
+ | --- | --- |
143
+ | `/new` | Increment the current scope generation and start a fresh session. |
144
+ | `/status` | Show active and recent runs for the current scope. |
145
+ | `/cancel` | Cancel the most recent active run for the current scope. |
146
+ | `/cancel <run_id>` | Request cancellation of a specific run. |
147
+ | `/help` | Show the command help card. |
148
+
149
+ Cancellation first records `cancel_requested` and then calls the scoped AgentOS cancel endpoint. The final state comes from the SSE terminal event. Card actions re-check the operator and chat allowlists before starting status or cancellation work.
150
+
151
+ ## State database and troubleshooting
152
+
153
+ The default database `.data/agno-feishu.sqlite3` uses WAL and a busy timeout. It contains `schema_version`, `dedup_messages`, `session_scopes`, and `runs`. Message deduplication defaults to 24 hours and run records are retained for 7 days.
154
+
155
+ If no messages arrive, check application publication, WebSocket subscriptions, bot membership, and allowlists. For 401/403 responses, check the AgentOS token, target ID, and AgentOS authorization. For resource failures, check Lark/Feishu resource-read permissions. Logs do not include the App Secret, AgentOS token, raw file contents, or complete user messages.
156
+
157
+ If your shell exports a SOCKS proxy and the local environment does not have `socksio`, set `NO_PROXY=127.0.0.1,localhost` (and the AgentOS hostname) when testing a local AgentOS. If outbound AgentOS requests must use a SOCKS proxy, install the HTTPX SOCKS extra in the deployment environment with `uv pip install "httpx[socks]>=0.28,<1"`.
158
+
159
+ ## Development
160
+
161
+ ```bash
162
+ uv sync
163
+ uv run pytest
164
+ uv run ruff check .
165
+ uv run mypy src
166
+ uv build
167
+ uv run agno-lark --help
168
+ ```
169
+
170
+ Tests use fake Channel and Agno targets plus `httpx` mocks; they do not contact Lark/Feishu or AgentOS. See [`examples/agent_os_remote.py`](examples/agent_os_remote.py) for the remote integration example.
171
+
172
+ ## Release and publish
173
+
174
+ The package will be published to [PyPI](https://pypi.org/project/agno-lark/) as `agno-lark`. Every release version must be unique. Update `version` in `pyproject.toml`, then run the local checks and build:
175
+
176
+ ```bash
177
+ uv lock
178
+ uv sync --locked
179
+ uv run pytest
180
+ uv run ruff check .
181
+ uv run mypy src
182
+ uv build
183
+ ```
184
+
185
+ For a first release or a manual release, create a PyPI API token and publish without putting the token in the repository or shell history:
186
+
187
+ ```bash
188
+ export UV_PUBLISH_TOKEN='pypi-...'
189
+ uv publish
190
+ ```
191
+
192
+ To verify a release on TestPyPI first, use a TestPyPI token and the TestPyPI upload endpoint:
193
+
194
+ ```bash
195
+ export UV_PUBLISH_TOKEN='pypi-...'
196
+ uv publish --publish-url https://test.pypi.org/legacy/
197
+ uv pip install --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ agno-lark
198
+ ```
199
+
200
+ This repository also includes a GitHub Actions workflow for PyPI Trusted Publishing. Configure the GitHub repository as a trusted publisher for the `agno-lark` project on PyPI, then push a tag such as `v0.1.0`; the workflow builds and publishes without a long-lived PyPI token.
201
+
202
+ ## License
203
+
204
+ This project is released under the MIT License. See [`LICENSE`](LICENSE).
@@ -0,0 +1,82 @@
1
+ [project]
2
+ name = "agno-lark"
3
+ version = "0.1.0"
4
+ description = "A lightweight Python bridge between Lark/Feishu and Agno AgentOS."
5
+ readme = "README.md"
6
+ keywords = [
7
+ "agno",
8
+ "agentos",
9
+ "lark",
10
+ "feishu",
11
+ "im",
12
+ "websocket",
13
+ ]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "Operating System :: OS Independent",
18
+ "Programming Language :: Python :: 3",
19
+ "Programming Language :: Python :: 3.12",
20
+ "Programming Language :: Python :: 3.13",
21
+ "Topic :: Communications :: Chat",
22
+ "Topic :: Software Development :: Libraries :: Python Modules",
23
+ ]
24
+ requires-python = ">=3.12,<4"
25
+ dependencies = [
26
+ "agno[os]>=3.1,<4",
27
+ "aiosqlite>=0.20,<1",
28
+ "httpx[socks]>=0.28,<1",
29
+ "lark-channel-sdk>=1.4,<2",
30
+ "pydantic-settings>=2.6,<3",
31
+ ]
32
+
33
+ [[project.authors]]
34
+ name = "_白开水_"
35
+ email = "pkk518@gmail.com"
36
+
37
+ [project.license]
38
+ file = "LICENSE"
39
+
40
+ [project.scripts]
41
+ agno-lark = "agno_lark.cli:main"
42
+
43
+ [project.urls]
44
+ Homepage = "https://github.com/pangkk18/agno-lark"
45
+ Repository = "https://github.com/pangkk18/agno-lark"
46
+ Issues = "https://github.com/pangkk18/agno-lark/issues"
47
+
48
+ [build-system]
49
+ requires = ["uv_build>=0.13.1,<0.14.0"]
50
+ build-backend = "uv_build"
51
+
52
+ [dependency-groups]
53
+ dev = [
54
+ "mypy>=1.15,<2",
55
+ "pytest>=8.3,<9",
56
+ "pytest-asyncio>=0.25,<1",
57
+ "respx>=0.22,<1",
58
+ "ruff>=0.9,<1",
59
+ ]
60
+
61
+ [tool.pytest.ini_options]
62
+ addopts = "-q"
63
+ asyncio_mode = "auto"
64
+ testpaths = ["tests"]
65
+
66
+ [tool.ruff]
67
+ line-length = 100
68
+ target-version = "py312"
69
+
70
+ [tool.ruff.lint]
71
+ select = [
72
+ "E",
73
+ "F",
74
+ "I",
75
+ "UP",
76
+ "B",
77
+ ]
78
+
79
+ [tool.mypy]
80
+ python_version = "3.12"
81
+ strict = true
82
+ files = ["src"]
@@ -0,0 +1,66 @@
1
+ [project]
2
+ name = "agno-lark"
3
+ version = "0.1.0"
4
+ description = "A lightweight Python bridge between Lark/Feishu and Agno AgentOS."
5
+ readme = "README.md"
6
+ authors = [
7
+ { name = "_白开水_", email = "pkk518@gmail.com" }
8
+ ]
9
+ license = { file = "LICENSE" }
10
+ keywords = ["agno", "agentos", "lark", "feishu", "im", "websocket"]
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Intended Audience :: Developers",
14
+ "Operating System :: OS Independent",
15
+ "Programming Language :: Python :: 3",
16
+ "Programming Language :: Python :: 3.12",
17
+ "Programming Language :: Python :: 3.13",
18
+ "Topic :: Communications :: Chat",
19
+ "Topic :: Software Development :: Libraries :: Python Modules",
20
+ ]
21
+ requires-python = ">=3.12,<4"
22
+ dependencies = [
23
+ "agno[os]>=3.1,<4",
24
+ "aiosqlite>=0.20,<1",
25
+ "httpx[socks]>=0.28,<1",
26
+ "lark-channel-sdk>=1.4,<2",
27
+ "pydantic-settings>=2.6,<3",
28
+ ]
29
+
30
+ [build-system]
31
+ requires = ["uv_build>=0.13.1,<0.14.0"]
32
+ build-backend = "uv_build"
33
+
34
+ [project.scripts]
35
+ agno-lark = "agno_lark.cli:main"
36
+
37
+ [project.urls]
38
+ Homepage = "https://github.com/pangkk18/agno-lark"
39
+ Repository = "https://github.com/pangkk18/agno-lark"
40
+ Issues = "https://github.com/pangkk18/agno-lark/issues"
41
+
42
+ [dependency-groups]
43
+ dev = [
44
+ "mypy>=1.15,<2",
45
+ "pytest>=8.3,<9",
46
+ "pytest-asyncio>=0.25,<1",
47
+ "respx>=0.22,<1",
48
+ "ruff>=0.9,<1",
49
+ ]
50
+
51
+ [tool.pytest.ini_options]
52
+ addopts = "-q"
53
+ asyncio_mode = "auto"
54
+ testpaths = ["tests"]
55
+
56
+ [tool.ruff]
57
+ line-length = 100
58
+ target-version = "py312"
59
+
60
+ [tool.ruff.lint]
61
+ select = ["E", "F", "I", "UP", "B"]
62
+
63
+ [tool.mypy]
64
+ python_version = "3.12"
65
+ strict = true
66
+ files = ["src"]
@@ -0,0 +1,28 @@
1
+ """Lark/Feishu bridge for Agno AgentOS."""
2
+
3
+ from .app import create_app
4
+ from .bridge import FeishuBridge, LarkBridge
5
+ from .config import FeishuSettings, LarkSettings, load_settings
6
+ from .interface import FeishuInterface, LarkInterface
7
+ from .session import make_scope_key, make_session_id
8
+ from .state import RunRecord, SqliteStateStore
9
+ from .target import TargetDescriptor, build_remote_target
10
+
11
+ __all__ = [
12
+ "LarkInterface",
13
+ "FeishuInterface",
14
+ "LarkBridge",
15
+ "FeishuBridge",
16
+ "LarkSettings",
17
+ "FeishuSettings",
18
+ "RunRecord",
19
+ "SqliteStateStore",
20
+ "TargetDescriptor",
21
+ "build_remote_target",
22
+ "create_app",
23
+ "load_settings",
24
+ "make_scope_key",
25
+ "make_session_id",
26
+ ]
27
+
28
+ __version__ = "0.1.0"