feat: OpenMesh 基础平台与 MD/PDF 转换技能
- 后端: coworker 智能体框架, WS API, 文件上传, 附件处理 - 前端: Open WebUI, 文件全量走 upload API (含 MD/TXT/JSON 等文本类) - 技能: md-to-office (pandoc + wkhtmltopdf) - 修复: 上传文件路径丢失, Agent 搜索浪费, 输出文件跑到 uploads/ - 打包: PyInstaller one-dir, 预打包 pandoc/wkhtmltopdf/chromium
This commit is contained in:
69
coworker/testing/fake_slack/__main__.py
Normal file
69
coworker/testing/fake_slack/__main__.py
Normal file
@@ -0,0 +1,69 @@
|
||||
"""Standalone FakeSlack runner — drive the live dev app against a fake Slack.
|
||||
|
||||
python -m coworker.testing.fake_slack --port 8910
|
||||
|
||||
Prints the ``SLACK_API_URL`` to export plus curl examples for the control API, then serves
|
||||
until interrupted. Point the dev server at it by exporting ``SLACK_API_URL`` before starting
|
||||
``openworker-server`` and connecting Slack with any fake ``xoxb-``/``xapp-`` tokens.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
|
||||
import uvicorn
|
||||
|
||||
from .server import FakeSlack
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(prog="coworker.testing.fake_slack")
|
||||
parser.add_argument(
|
||||
"--port", type=int, default=8910, help="port to bind (default 8910)"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--host", default="127.0.0.1", help="host to bind (default 127.0.0.1)"
|
||||
)
|
||||
args = parser.parse_args()
|
||||
|
||||
fake = FakeSlack(host=args.host, port=args.port)
|
||||
base = f"http://{args.host}:{args.port}"
|
||||
ctl = f"{base}/control"
|
||||
|
||||
print("FakeSlack — standalone Slack test double")
|
||||
print(f" listening on {base}")
|
||||
print()
|
||||
print("Point the app at it:")
|
||||
print(f" export SLACK_API_URL={base}/api/")
|
||||
print(
|
||||
" # then start openworker-server and connect Slack with any xoxb-/xapp- tokens"
|
||||
)
|
||||
print()
|
||||
print("Drive scenarios via the control API:")
|
||||
print(f" curl -X POST {ctl}/users -H 'content-type: application/json' \\")
|
||||
print(' -d \'{"id":"U1","name":"alice","real_name":"Alice"}\'')
|
||||
print(f" curl -X POST {ctl}/channels -H 'content-type: application/json' \\")
|
||||
print(' -d \'{"id":"C1","name":"general","is_im":false}\'')
|
||||
print(f" curl -X POST {ctl}/inbound -H 'content-type: application/json' \\")
|
||||
print(' -d \'{"channel":"C1","user":"U1","text":"hello there"}\'')
|
||||
print(f" curl -X POST {ctl}/interaction -H 'content-type: application/json' \\")
|
||||
print(
|
||||
' -d \'{"channel":"C1","user":"U1","username":"alice",'
|
||||
'"message_ts":"1700000001.000001","action_id":"ocw_0","value":"..."}\''
|
||||
)
|
||||
print(
|
||||
f" curl {ctl}/outbound # inspect recorded chat.postMessage/chat.update"
|
||||
)
|
||||
print(f" curl -X POST {ctl}/reset # clean slate")
|
||||
print(f" curl {ctl}/health")
|
||||
print()
|
||||
|
||||
# Port is fixed here, so apps.connections.open can answer with the right ws:// URL without
|
||||
# waiting on an ephemeral bind. Serve blocking (handles signals).
|
||||
uvicorn.run(
|
||||
fake.app, host=args.host, port=args.port, log_level="info", lifespan="off"
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user