@agentunion/kite 1.0.7 → 1.3.0

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 (100) hide show
  1. package/CHANGELOG.md +208 -0
  2. package/README.md +48 -0
  3. package/cli.js +1 -1
  4. package/extensions/agents/__init__.py +1 -0
  5. package/extensions/agents/assistant/__init__.py +1 -0
  6. package/extensions/agents/assistant/entry.py +329 -0
  7. package/extensions/agents/assistant/module.md +22 -0
  8. package/extensions/agents/assistant/server.py +197 -0
  9. package/extensions/channels/__init__.py +1 -0
  10. package/extensions/channels/acp_channel/__init__.py +1 -0
  11. package/extensions/channels/acp_channel/entry.py +329 -0
  12. package/extensions/channels/acp_channel/module.md +22 -0
  13. package/extensions/channels/acp_channel/server.py +197 -0
  14. package/extensions/event_hub_bench/entry.py +624 -379
  15. package/extensions/event_hub_bench/module.md +2 -1
  16. package/extensions/services/backup/__init__.py +1 -0
  17. package/extensions/services/backup/entry.py +508 -0
  18. package/extensions/services/backup/module.md +22 -0
  19. package/extensions/services/model_service/__init__.py +1 -0
  20. package/extensions/services/model_service/entry.py +508 -0
  21. package/extensions/services/model_service/module.md +22 -0
  22. package/extensions/services/watchdog/entry.py +468 -102
  23. package/extensions/services/watchdog/module.md +3 -0
  24. package/extensions/services/watchdog/monitor.py +170 -69
  25. package/extensions/services/web/__init__.py +1 -0
  26. package/extensions/services/web/config.yaml +149 -0
  27. package/extensions/services/web/entry.py +390 -0
  28. package/extensions/services/web/module.md +24 -0
  29. package/extensions/services/web/routes/__init__.py +1 -0
  30. package/extensions/services/web/routes/routes_call.py +189 -0
  31. package/extensions/services/web/routes/routes_config.py +512 -0
  32. package/extensions/services/web/routes/routes_contacts.py +98 -0
  33. package/extensions/services/web/routes/routes_devlog.py +99 -0
  34. package/extensions/services/web/routes/routes_phone.py +81 -0
  35. package/extensions/services/web/routes/routes_sms.py +48 -0
  36. package/extensions/services/web/routes/routes_stats.py +17 -0
  37. package/extensions/services/web/routes/routes_voicechat.py +554 -0
  38. package/extensions/services/web/routes/schemas.py +216 -0
  39. package/extensions/services/web/server.py +375 -0
  40. package/extensions/services/web/static/css/style.css +1064 -0
  41. package/extensions/services/web/static/index.html +1445 -0
  42. package/extensions/services/web/static/js/app.js +4671 -0
  43. package/extensions/services/web/vendor/__init__.py +1 -0
  44. package/extensions/services/web/vendor/bluetooth/audio.py +348 -0
  45. package/extensions/services/web/vendor/bluetooth/contacts.py +251 -0
  46. package/extensions/services/web/vendor/bluetooth/manager.py +395 -0
  47. package/extensions/services/web/vendor/bluetooth/sms.py +290 -0
  48. package/extensions/services/web/vendor/bluetooth/telephony.py +274 -0
  49. package/extensions/services/web/vendor/config.py +139 -0
  50. package/extensions/services/web/vendor/conversation/asr.py +936 -0
  51. package/extensions/services/web/vendor/conversation/engine.py +548 -0
  52. package/extensions/services/web/vendor/conversation/llm.py +534 -0
  53. package/extensions/services/web/vendor/conversation/mcp_tools.py +190 -0
  54. package/extensions/services/web/vendor/conversation/tts.py +322 -0
  55. package/extensions/services/web/vendor/conversation/vad.py +138 -0
  56. package/extensions/services/web/vendor/storage/__init__.py +1 -0
  57. package/extensions/services/web/vendor/storage/identity.py +312 -0
  58. package/extensions/services/web/vendor/storage/store.py +507 -0
  59. package/extensions/services/web/vendor/task/manager.py +864 -0
  60. package/extensions/services/web/vendor/task/models.py +45 -0
  61. package/extensions/services/web/vendor/task/webhook.py +263 -0
  62. package/extensions/services/web/vendor/tools/registry.py +321 -0
  63. package/kernel/__init__.py +0 -0
  64. package/kernel/entry.py +407 -0
  65. package/{core/event_hub/hub.py → kernel/event_hub.py} +62 -74
  66. package/kernel/module.md +33 -0
  67. package/{core/registry/store.py → kernel/registry_store.py} +23 -8
  68. package/kernel/rpc_router.py +388 -0
  69. package/kernel/server.py +267 -0
  70. package/launcher/__init__.py +10 -0
  71. package/launcher/__main__.py +6 -0
  72. package/launcher/count_lines.py +258 -0
  73. package/launcher/entry.py +1778 -0
  74. package/launcher/logging_setup.py +289 -0
  75. package/{core/launcher → launcher}/module_scanner.py +11 -6
  76. package/launcher/process_manager.py +880 -0
  77. package/main.py +11 -210
  78. package/package.json +6 -9
  79. package/__init__.py +0 -1
  80. package/__main__.py +0 -15
  81. package/core/event_hub/BENCHMARK.md +0 -94
  82. package/core/event_hub/bench.py +0 -459
  83. package/core/event_hub/bench_extreme.py +0 -308
  84. package/core/event_hub/bench_perf.py +0 -350
  85. package/core/event_hub/entry.py +0 -157
  86. package/core/event_hub/module.md +0 -20
  87. package/core/event_hub/server.py +0 -206
  88. package/core/launcher/entry.py +0 -1158
  89. package/core/launcher/process_manager.py +0 -470
  90. package/core/registry/entry.py +0 -110
  91. package/core/registry/module.md +0 -30
  92. package/core/registry/server.py +0 -289
  93. package/extensions/services/watchdog/server.py +0 -167
  94. /package/{core → extensions/services/web/vendor/bluetooth}/__init__.py +0 -0
  95. /package/{core/event_hub → extensions/services/web/vendor/conversation}/__init__.py +0 -0
  96. /package/{core/launcher → extensions/services/web/vendor/task}/__init__.py +0 -0
  97. /package/{core/registry → extensions/services/web/vendor/tools}/__init__.py +0 -0
  98. /package/{core/event_hub → kernel}/dedup.py +0 -0
  99. /package/{core/event_hub → kernel}/router.py +0 -0
  100. /package/{core/launcher → launcher}/module.md +0 -0
package/main.py CHANGED
@@ -1,217 +1,18 @@
1
1
  """
2
2
  Kite development entry point.
3
- Loads .env, sets KITE_* defaults, parses --debug, starts Launcher.
3
+ 1. Run code stats
4
+ 2. Start launcher
4
5
  """
5
- import atexit
6
- import builtins
7
- import os
8
- import secrets
9
6
  import sys
10
- import threading
11
- import time
12
- from datetime import datetime
7
+ from pathlib import Path
13
8
 
14
- # ── Timestamped print with delta + color ──
15
- # Covers the entire Launcher process. Child processes (registry, event_hub) are
16
- # separate PIDs — unaffected. Their stdout is relayed via ProcessManager._read_stdout
17
- # → print(), so timestamps & deltas are added at the relay point automatically.
9
+ # Add project root to sys.path
10
+ sys.path.insert(0, str(Path(__file__).parent))
18
11
 
19
- _builtin_print = builtins.print
20
- _last_ts = time.monotonic()
12
+ # 1. Run code stats
13
+ from launcher.count_lines import run_stats
14
+ run_stats()
21
15
 
22
- # ANSI escape codes
23
- _DIM = "\033[90m" # gray — fast, normal
24
- _GREEN = "\033[32m" # green — noticeable but expected (subprocess launch, network wait)
25
- _RED = "\033[91m" # red — abnormally slow, likely a problem
26
- _RESET = "\033[0m"
27
-
28
- # ── Log file handles ──
29
- # Initialized lazily after KITE_MODULE_DATA is resolved (see _init_log_files)
30
- _log_lock = threading.Lock()
31
- _log_latest = None # file handle: latest.log (cleared each startup)
32
- _log_daily = None # file handle: {YYYY-MM}/{YYYY-MM-DD}.log (append)
33
- _log_daily_date = "" # current date string to detect day rollover
34
-
35
- # Strip ANSI escape sequences for plain-text log files
36
- import re
37
- _ANSI_RE = re.compile(r"\033\[[0-9;]*m")
38
-
39
- def _strip_ansi(s: str) -> str:
40
- return _ANSI_RE.sub("", s)
41
-
42
-
43
- def _init_log_files():
44
- """Initialize log file handles. Called after KITE_MODULE_DATA is set."""
45
- global _log_latest, _log_daily, _log_daily_date
46
- module_data = os.environ.get("KITE_MODULE_DATA")
47
- if not module_data:
48
- return
49
- log_dir = os.path.join(module_data, "log")
50
- os.makedirs(log_dir, exist_ok=True)
51
-
52
- # latest.log — truncate on each startup
53
- try:
54
- _log_latest = open(os.path.join(log_dir, "latest.log"), "w", encoding="utf-8")
55
- except Exception as e:
56
- _builtin_print(f"[launcher] 警告: 无法打开 latest.log: {e}")
57
-
58
- # daily log — append
59
- _open_daily_log(log_dir)
60
-
61
-
62
- def _open_daily_log(log_dir: str = None):
63
- """Open (or rotate) the daily log file based on current date."""
64
- global _log_daily, _log_daily_date
65
- today = datetime.now().strftime("%Y-%m-%d")
66
- if today == _log_daily_date and _log_daily:
67
- return
68
- if _log_daily:
69
- try:
70
- _log_daily.close()
71
- except Exception:
72
- pass
73
- if not log_dir:
74
- module_data = os.environ.get("KITE_MODULE_DATA")
75
- if not module_data:
76
- return
77
- log_dir = os.path.join(module_data, "log")
78
- month_dir = os.path.join(log_dir, today[:7]) # YYYY-MM
79
- os.makedirs(month_dir, exist_ok=True)
80
- try:
81
- _log_daily = open(os.path.join(month_dir, f"{today}.log"), "a", encoding="utf-8")
82
- _log_daily_date = today
83
- except Exception as e:
84
- _builtin_print(f"[launcher] 警告: 无法打开每日日志: {e}")
85
-
86
-
87
- def _write_log(plain_line: str):
88
- """Write a plain-text line to both latest.log and daily log."""
89
- global _log_daily
90
- with _log_lock:
91
- if _log_latest:
92
- try:
93
- _log_latest.write(plain_line)
94
- _log_latest.flush()
95
- except Exception:
96
- pass
97
- # Check daily rotation
98
- today = datetime.now().strftime("%Y-%m-%d")
99
- if today != _log_daily_date:
100
- _open_daily_log()
101
- if _log_daily:
102
- try:
103
- _log_daily.write(plain_line)
104
- _log_daily.flush()
105
- except Exception:
106
- pass
107
-
108
-
109
- def _close_log_files():
110
- """Flush and close log files on exit."""
111
- global _log_latest, _log_daily
112
- for f in (_log_latest, _log_daily):
113
- if f:
114
- try:
115
- f.flush()
116
- f.close()
117
- except Exception:
118
- pass
119
- _log_latest = None
120
- _log_daily = None
121
-
122
- atexit.register(_close_log_files)
123
-
124
-
125
- def _tprint(*args, **kwargs):
126
- global _last_ts
127
- now = time.monotonic()
128
- delta = now - _last_ts
129
- _last_ts = now
130
-
131
- # Timestamp
132
- ts = datetime.now().strftime("%H:%M:%S.%f")[:-3]
133
-
134
- # Format delta string
135
- if delta < 1:
136
- delta_str = f"+{delta * 1000:.0f}ms"
137
- elif delta < 100:
138
- delta_str = f"+{delta:.1f}s"
139
- else:
140
- delta_str = f"+{delta:.0f}s"
141
-
142
- # Color: gray < 1s, green 1–5s, red > 5s
143
- if delta >= 5:
144
- color = _RED
145
- elif delta >= 1:
146
- color = _GREEN
147
- else:
148
- color = _DIM
149
-
150
- prefix = f"{ts} {color}{delta_str:>8}{_RESET} "
151
- _builtin_print(prefix, end="")
152
- _builtin_print(*args, **kwargs)
153
-
154
- # Write to log files (plain text, no ANSI)
155
- if _log_latest or _log_daily:
156
- sep = kwargs.get("sep", " ")
157
- end = kwargs.get("end", "\n")
158
- text = sep.join(str(a) for a in args)
159
- plain_prefix = f"{ts} {delta_str:>8} "
160
- _write_log(plain_prefix + text + end)
161
-
162
- builtins.print = _tprint
163
-
164
- # Load .env (development convenience, not required in production)
165
- try:
166
- from dotenv import load_dotenv
167
- load_dotenv()
168
- except ImportError:
169
- pass
170
-
171
- # Resolve project root (directory containing this file)
172
- _project_root = os.path.dirname(os.path.abspath(__file__))
173
-
174
- # Home base for Kite data
175
- _home = os.environ.get("HOME") or os.environ.get("USERPROFILE") or os.path.expanduser("~")
176
- _kite_home = os.path.join(_home, ".kite")
177
-
178
- # Set KITE_* defaults (only if not already set by cli.js or .env)
179
- _defaults = {
180
- "KITE_PROJECT": _project_root,
181
- "KITE_CWD": os.getcwd(),
182
- "KITE_WORKSPACE": os.path.join(_kite_home, "workspace"),
183
- "KITE_DATA": os.path.join(_kite_home, "data"),
184
- "KITE_MODULES": os.path.join(_kite_home, "modules"),
185
- "KITE_REPO": os.path.join(_kite_home, "repo"),
186
- "KITE_ENV": "development",
187
- }
188
- for key, value in _defaults.items():
189
- if not os.environ.get(key):
190
- os.environ[key] = value
191
-
192
- # Parse --debug flag
193
- if "--debug" in sys.argv:
194
- os.environ["KITE_DEBUG"] = "1"
195
- sys.argv.remove("--debug")
196
-
197
- # Ensure project root is on sys.path
198
- sys.path.insert(0, os.environ["KITE_PROJECT"])
199
-
200
- from core.launcher.entry import Launcher
201
-
202
-
203
- def main():
204
- token = secrets.token_hex(32)
205
- print(f"[main] KITE_TOKEN 已生成 ({len(token)} 字符)")
206
- env = os.environ.get("KITE_ENV", "development")
207
- debug = os.environ.get("KITE_DEBUG") == "1"
208
- print(f"[main] 环境={env}, 调试={debug}, 项目={os.environ['KITE_PROJECT']}")
209
- launcher = Launcher(kite_token=token)
210
- # KITE_MODULE_DATA is now set — initialize log files
211
- _init_log_files()
212
- print(f"[main] 日志文件已初始化: {os.environ.get('KITE_MODULE_DATA', '')}/log/")
213
- launcher.run()
214
-
215
-
216
- if __name__ == "__main__":
217
- main()
16
+ # 2. Start launcher
17
+ from launcher.entry import start_launcher
18
+ start_launcher()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentunion/kite",
3
- "version": "1.0.7",
3
+ "version": "1.3.0",
4
4
  "description": "Kite framework launcher — start Kite from anywhere",
5
5
  "bin": {
6
6
  "kite": "./cli.js"
@@ -8,19 +8,16 @@
8
8
  "files": [
9
9
  "cli.js",
10
10
  "main.py",
11
- "__main__.py",
12
- "__init__.py",
13
- "core/**",
11
+ "launcher/**",
12
+ "kernel/**",
14
13
  "extensions/**",
14
+ "scripts/**",
15
+ "CHANGELOG.md",
15
16
  "!**/__pycache__",
16
17
  "!**/__pycache__/**",
17
18
  "!**/*.pyc",
18
19
  "!**/data",
19
- "!**/data/**",
20
- "!**/bench_results",
21
- "!**/bench_results/**",
22
- "!core/event_hub_bench",
23
- "!core/event_hub_bench/**"
20
+ "!**/data/**"
24
21
  ],
25
22
  "engines": {
26
23
  "node": ">=16"
package/__init__.py DELETED
@@ -1 +0,0 @@
1
- # Kite framework package
package/__main__.py DELETED
@@ -1,15 +0,0 @@
1
- """Allow running Kite as a package: python -m Kite"""
2
- import os, sys
3
- sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
4
- import secrets
5
- from core.launcher.entry import Launcher
6
-
7
-
8
- def main():
9
- token = secrets.token_hex(32)
10
- print(f"[main] KITE_TOKEN generated ({len(token)} chars)")
11
- Launcher(kite_token=token).run()
12
-
13
-
14
- if __name__ == "__main__":
15
- main()
@@ -1,94 +0,0 @@
1
- # Event Hub 基准测试指南
2
-
3
- ## 快速开始
4
-
5
- 从 Kite 根目录运行:
6
-
7
- ```bash
8
- python -m core.event_hub.bench_perf
9
- ```
10
-
11
- 运行约 20 秒,结果自动保存到 `core/event_hub/bench_results/` 目录。
12
-
13
- ## 测试项说明
14
-
15
- ### 1. Throughput(吞吐量)
16
-
17
- 一次性发送 10000 个事件,测量整条链路的处理速度。
18
-
19
- | 指标 | 含义 |
20
- |------|------|
21
- | send_rate | publisher 每秒发送事件数(evt/s) |
22
- | hub_queued | hub 成功放入订阅者队列的数量 |
23
- | hub_routed | hub sender loop 成功发出的数量 |
24
- | client_recv | 订阅者客户端实际收到的数量 |
25
-
26
- 三个数字一致 = 零丢失。哪个数字变小,哪个环节就是瓶颈。
27
-
28
- ### 2. Latency(延迟)
29
-
30
- 逐条发送 200 个事件,测量端到端耗时。
31
-
32
- | 指标 | 含义 |
33
- |------|------|
34
- | avg_ms | 平均延迟 |
35
- | p50_ms | 中位数延迟(50% 的请求低于此值) |
36
- | p95_ms | 95 分位延迟 |
37
- | p99_ms | 99 分位延迟(最差情况) |
38
-
39
- ### 3. Fan-out(扇出)
40
-
41
- 1 个 publisher 发送 2000 个事件,N 个 subscriber 同时接收。
42
-
43
- | 场景 | 含义 |
44
- |------|------|
45
- | x1 | 1 个订阅者,基线性能 |
46
- | x10 | 10 个订阅者,中等负载 |
47
- | x50 | 50 个订阅者,高负载 |
48
-
49
- 每个场景报告 `avg_recv`(平均接收数)和 `min_recv`(最少接收数)。全部等于发送数 = 零丢失。
50
-
51
- ## 结果文件
52
-
53
- 每次运行自动保存到 `core/event_hub/bench_results/`:
54
-
55
- ```
56
- bench_results/
57
- 2026-02-28_05-22-18.json
58
- 2026-02-28_06-30-00.json
59
- ```
60
-
61
- JSON 结构:
62
-
63
- ```json
64
- {
65
- "timestamp": "2026-02-28T05:22:18",
66
- "env": { "platform": "win32", "python": "3.12.0" },
67
- "throughput": { "send_rate": 9752, "hub_queued": 10000, ... },
68
- "latency": { "avg_ms": 0.6, "p50_ms": 0.55, ... },
69
- "fanout_1": { ... },
70
- "fanout_10": { ... },
71
- "fanout_50": { ... },
72
- "hub_counters": { ... }
73
- }
74
- ```
75
-
76
- ## 如何对比优化效果
77
-
78
- 1. 改动代码前跑一次 `python -m core.event_hub.bench_perf`
79
- 2. 实施优化
80
- 3. 再跑一次
81
- 4. 对比两个 JSON 文件中的关键指标
82
-
83
- 重点关注:
84
- - `throughput.send_rate` — 越高越好
85
- - `latency.p99_ms` — 越低越好
86
- - `fanout_50.min_recv` — 应等于 2000(零丢失)
87
-
88
- ## 其他测试脚本
89
-
90
- | 脚本 | 用途 | 耗时 |
91
- |------|------|------|
92
- | `bench_perf` | 快速基准对比 | ~20s |
93
- | `bench_extreme` | 极限压测(50000 burst、100MB 消息、50 subscriber) | ~5min |
94
- | `bench` | 长时间混合压力测试 | ~10min |