@bolloon/bolloon-agent 0.1.32 → 0.1.34

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 (37) hide show
  1. package/README.md +7 -2
  2. package/dist/agents/pi-sdk.js +10 -1
  3. package/dist/bollharness-integration/index.js +8 -1
  4. package/dist/heartbeat/Watchdog.js +9 -1
  5. package/dist/llm/audio-config-store.js +199 -0
  6. package/dist/llm/config-store.js +20 -10
  7. package/dist/llm/pi-ai.js +2 -2
  8. package/dist/llm/video-config-store.js +31 -1
  9. package/dist/network/p2p-direct.js +59 -2
  10. package/dist/pi-ecosystem/index.js +10 -7
  11. package/dist/pi-ecosystem-judgment/decision.js +5 -2
  12. package/dist/social/heartbeat.js +19 -2
  13. package/dist/web/api-config.html +16 -4
  14. package/dist/web/client.js +1017 -137
  15. package/dist/web/index.html +10 -27
  16. package/dist/web/server.js +865 -52
  17. package/dist/web/style.css +370 -0
  18. package/package.json +2 -1
  19. package/src/agents/pi-sdk.ts +9 -1
  20. package/src/bollharness-integration/index.ts +8 -32
  21. package/src/heartbeat/Watchdog.ts +9 -1
  22. package/src/llm/audio-config-store.ts +6 -1
  23. package/src/llm/config-store.ts +21 -11
  24. package/src/llm/pi-ai.ts +2 -2
  25. package/src/llm/video-config-store.ts +7 -1
  26. package/src/network/p2p-direct.ts +59 -3
  27. package/src/social/ant-colony/index.js +19 -0
  28. package/src/social/heartbeat.ts +18 -2
  29. package/src/web/api-config.html +16 -4
  30. package/src/web/client.js +1017 -137
  31. package/src/web/index.html +10 -27
  32. package/src/web/server.ts +810 -47
  33. package/src/web/style.css +370 -0
  34. package/src/social/ant-colony/AdaptiveHeartbeat.ts +0 -131
  35. package/src/social/ant-colony/PheromoneEngine.ts +0 -302
  36. package/src/social/ant-colony/index.ts +0 -18
  37. package/src/social/ant-colony/types.ts +0 -94
package/src/web/style.css CHANGED
@@ -4083,3 +4083,373 @@ body:has(> .api-config-page) {
4083
4083
  cursor: pointer;
4084
4084
  accent-color: var(--accent);
4085
4085
  }
4086
+
4087
+ /* ============================================================
4088
+ * 2026-06-10: 远程聊天 modal — 完全对齐本地聊天风格
4089
+ * 用 CSS 变量, 字体继承全局 JetBrains Mono, 支持深/浅色主题切换
4090
+ * ============================================================ */
4091
+ .remote-chat-overlay {
4092
+ position: fixed;
4093
+ inset: 0;
4094
+ background: rgba(0, 0, 0, 0.55);
4095
+ z-index: 10002;
4096
+ display: flex;
4097
+ align-items: center;
4098
+ justify-content: center;
4099
+ }
4100
+ .remote-chat-shell {
4101
+ background: var(--bg-main);
4102
+ color: var(--text);
4103
+ border: 1px solid var(--border);
4104
+ border-radius: 8px;
4105
+ width: 720px;
4106
+ max-width: 92vw;
4107
+ height: 80vh;
4108
+ max-height: 80vh;
4109
+ display: flex;
4110
+ flex-direction: column;
4111
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.35);
4112
+ font-family: inherit;
4113
+ }
4114
+ .remote-chat-header {
4115
+ padding: 12px 16px;
4116
+ border-bottom: 1px solid var(--border);
4117
+ display: flex;
4118
+ align-items: center;
4119
+ justify-content: space-between;
4120
+ gap: 8px;
4121
+ background: var(--bg-sidebar);
4122
+ border-radius: 8px 8px 0 0;
4123
+ }
4124
+ .remote-chat-title {
4125
+ font-size: 15px;
4126
+ font-weight: 600;
4127
+ color: var(--text);
4128
+ }
4129
+ .remote-chat-meta {
4130
+ font-size: 11px;
4131
+ color: var(--text-muted);
4132
+ margin-top: 2px;
4133
+ overflow: hidden;
4134
+ text-overflow: ellipsis;
4135
+ white-space: nowrap;
4136
+ }
4137
+ .remote-chat-btn-secondary {
4138
+ background: var(--bg-hover);
4139
+ border: 1px solid var(--border);
4140
+ color: var(--text-secondary);
4141
+ cursor: pointer;
4142
+ padding: 4px 10px;
4143
+ border-radius: 4px;
4144
+ font-size: 11px;
4145
+ font-family: inherit;
4146
+ }
4147
+ .remote-chat-btn-secondary:hover {
4148
+ background: var(--bg-active);
4149
+ color: var(--text);
4150
+ }
4151
+ .remote-chat-btn-close {
4152
+ background: none;
4153
+ border: none;
4154
+ font-size: 20px;
4155
+ color: var(--text-muted);
4156
+ cursor: pointer;
4157
+ padding: 0 8px;
4158
+ line-height: 1;
4159
+ }
4160
+ .remote-chat-btn-close:hover {
4161
+ color: var(--text);
4162
+ }
4163
+ .remote-chat-thinking {
4164
+ padding: 8px 16px;
4165
+ background: var(--bg-hover);
4166
+ color: var(--text-secondary);
4167
+ font-size: 12px;
4168
+ border-bottom: 1px solid var(--border);
4169
+ }
4170
+ .remote-chat-log {
4171
+ flex: 1;
4172
+ overflow-y: auto;
4173
+ padding: 12px 16px;
4174
+ background: var(--bg-main);
4175
+ }
4176
+ .remote-chat-input-row {
4177
+ padding: 10px 12px;
4178
+ border-top: 1px solid var(--border);
4179
+ display: flex;
4180
+ gap: 6px;
4181
+ background: var(--bg-sidebar);
4182
+ border-radius: 0 0 8px 8px;
4183
+ }
4184
+ .remote-chat-input {
4185
+ flex: 1;
4186
+ padding: 8px 10px;
4187
+ border: 1px solid var(--border);
4188
+ border-radius: 4px;
4189
+ font-size: 13px;
4190
+ background: var(--bg-main);
4191
+ color: var(--text);
4192
+ font-family: inherit;
4193
+ }
4194
+ .remote-chat-input:focus {
4195
+ outline: none;
4196
+ border-color: var(--accent, #a4b630);
4197
+ }
4198
+ .remote-chat-btn-send {
4199
+ padding: 8px 14px;
4200
+ background: var(--user-bg);
4201
+ color: var(--user-text);
4202
+ border: none;
4203
+ border-radius: 4px;
4204
+ cursor: pointer;
4205
+ font-size: 13px;
4206
+ font-weight: 600;
4207
+ font-family: inherit;
4208
+ }
4209
+ .remote-chat-btn-send:hover:not(:disabled) {
4210
+ filter: brightness(1.1);
4211
+ }
4212
+ .remote-chat-btn-send:disabled {
4213
+ opacity: 0.5;
4214
+ cursor: wait;
4215
+ }
4216
+ .remote-chat-sysmsg {
4217
+ margin: 6px 0;
4218
+ padding: 6px 10px;
4219
+ border-radius: 4px;
4220
+ font-size: 11px;
4221
+ text-align: center;
4222
+ border: 1px solid var(--border);
4223
+ }
4224
+ .remote-chat-sysmsg-info {
4225
+ background: var(--bg-hover);
4226
+ color: var(--text-secondary);
4227
+ }
4228
+ .remote-chat-sysmsg-warn {
4229
+ background: var(--bg-hover);
4230
+ color: var(--text);
4231
+ border-color: var(--border-light);
4232
+ }
4233
+ .remote-chat-sysmsg-error {
4234
+ background: rgba(220, 38, 38, 0.12);
4235
+ color: #fca5a5;
4236
+ border-color: rgba(220, 38, 38, 0.3);
4237
+ }
4238
+ .remote-chat-judgments {
4239
+ margin: 0 0 8px;
4240
+ padding: 8px 10px;
4241
+ background: var(--bg-hover);
4242
+ border-left: 3px solid var(--accent, #a4b630);
4243
+ border-radius: 4px;
4244
+ font-size: 12px;
4245
+ }
4246
+ .remote-chat-judgments-title {
4247
+ font-weight: 600;
4248
+ color: var(--text);
4249
+ margin-bottom: 4px;
4250
+ }
4251
+ .remote-chat-judgment-item {
4252
+ margin: 3px 0;
4253
+ padding-left: 8px;
4254
+ color: var(--text);
4255
+ }
4256
+ .remote-chat-judgment-tag {
4257
+ color: var(--text-muted);
4258
+ font-size: 10px;
4259
+ }
4260
+ .remote-chat-judgment-reason {
4261
+ color: var(--text-secondary);
4262
+ font-size: 11px;
4263
+ }
4264
+ .remote-chat-judgments-foot {
4265
+ margin-top: 6px;
4266
+ color: var(--text-muted);
4267
+ font-size: 11px;
4268
+ }
4269
+
4270
+ /* ============================================================
4271
+ * 2026-06-10: 好友申请 modal — 对齐本地风格 + CSS 变量
4272
+ * ============================================================ */
4273
+ .friend-req-overlay {
4274
+ position: fixed;
4275
+ inset: 0;
4276
+ background: rgba(0, 0, 0, 0.55);
4277
+ z-index: 10004;
4278
+ display: flex;
4279
+ align-items: center;
4280
+ justify-content: center;
4281
+ }
4282
+ .friend-req-shell {
4283
+ background: var(--bg-main);
4284
+ color: var(--text);
4285
+ border: 1px solid var(--border);
4286
+ border-radius: 8px;
4287
+ width: 460px;
4288
+ max-width: 92vw;
4289
+ box-shadow: 0 10px 40px rgba(0, 0, 0, 0.4);
4290
+ font-family: inherit;
4291
+ }
4292
+ .friend-req-header {
4293
+ padding: 14px 18px;
4294
+ border-bottom: 1px solid var(--border);
4295
+ background: var(--bg-sidebar);
4296
+ display: flex;
4297
+ align-items: center;
4298
+ gap: 10px;
4299
+ border-radius: 8px 8px 0 0;
4300
+ }
4301
+ .friend-req-title {
4302
+ font-size: 15px;
4303
+ font-weight: 600;
4304
+ color: var(--text);
4305
+ }
4306
+ .friend-req-meta {
4307
+ font-size: 11px;
4308
+ color: var(--text-muted);
4309
+ margin-top: 2px;
4310
+ overflow: hidden;
4311
+ text-overflow: ellipsis;
4312
+ white-space: nowrap;
4313
+ }
4314
+ .friend-req-body {
4315
+ padding: 14px 18px;
4316
+ font-size: 13px;
4317
+ color: var(--text);
4318
+ line-height: 1.5;
4319
+ }
4320
+ .friend-req-actions {
4321
+ padding: 10px 18px;
4322
+ border-top: 1px solid var(--border);
4323
+ display: flex;
4324
+ gap: 8px;
4325
+ justify-content: flex-end;
4326
+ background: var(--bg-sidebar);
4327
+ border-radius: 0 0 8px 8px;
4328
+ }
4329
+ .friend-req-btn-deny {
4330
+ padding: 6px 14px;
4331
+ background: var(--bg-hover);
4332
+ color: var(--text-secondary);
4333
+ border: 1px solid var(--border);
4334
+ border-radius: 4px;
4335
+ cursor: pointer;
4336
+ font-size: 13px;
4337
+ font-family: inherit;
4338
+ }
4339
+ .friend-req-btn-deny:hover {
4340
+ background: var(--bg-active);
4341
+ color: var(--text);
4342
+ }
4343
+ .friend-req-btn-accept {
4344
+ padding: 6px 14px;
4345
+ background: var(--user-bg);
4346
+ color: var(--user-text);
4347
+ border: none;
4348
+ border-radius: 4px;
4349
+ cursor: pointer;
4350
+ font-size: 13px;
4351
+ font-weight: 600;
4352
+ font-family: inherit;
4353
+ }
4354
+ .friend-req-btn-accept:hover {
4355
+ filter: brightness(1.1);
4356
+ }
4357
+
4358
+ /* ============================================================
4359
+ * 2026-06-10: Toast 入场动画 (simple-toast 用)
4360
+ * ============================================================ */
4361
+ @keyframes toast-in {
4362
+ from {
4363
+ opacity: 0;
4364
+ transform: translateX(20px);
4365
+ }
4366
+ to {
4367
+ opacity: 1;
4368
+ transform: translateX(0);
4369
+ }
4370
+ }
4371
+
4372
+ /* ============================================================
4373
+ * 2026-06-10: P2P peer-group 可折叠 — 复用 #remote-agents-section.collapsed 模式
4374
+ * peer header 加 .peer-caret, 点击切 .remote-peer-group.collapsed
4375
+ * 折叠后隐藏 .remote-peer-channels, caret 旋转 -90deg
4376
+ * ============================================================ */
4377
+ .remote-peer-group .peer-caret {
4378
+ display: inline-block;
4379
+ font-size: 10px;
4380
+ color: var(--text-muted);
4381
+ transition: transform 0.15s ease;
4382
+ user-select: none;
4383
+ width: 12px;
4384
+ text-align: center;
4385
+ }
4386
+ .remote-peer-group.collapsed .peer-caret {
4387
+ transform: rotate(-90deg);
4388
+ }
4389
+ .remote-peer-group.collapsed > .remote-peer-channels {
4390
+ display: none;
4391
+ }
4392
+ .remote-peer-group .remote-peer-header {
4393
+ /* 让 caret 单独成可点区域时不撑破 header */
4394
+ user-select: none;
4395
+ }
4396
+
4397
+ /* ============================================================
4398
+ * 2026-06-11: 分享 channel modal (P2P peer 分享) — 用 friend-req-shell 风格
4399
+ * ============================================================ */
4400
+ .share-modal-shell {
4401
+ width: 520px;
4402
+ max-height: 80vh;
4403
+ }
4404
+ .share-modal-hint {
4405
+ padding: 8px 18px;
4406
+ font-size: 12px;
4407
+ color: var(--text-muted);
4408
+ background: var(--bg-sidebar);
4409
+ border-bottom: 1px solid var(--border);
4410
+ }
4411
+ .share-modal-list {
4412
+ flex: 1;
4413
+ overflow-y: auto;
4414
+ padding: 4px 18px;
4415
+ max-height: 50vh;
4416
+ }
4417
+ .share-modal-empty {
4418
+ color: var(--text-muted);
4419
+ padding: 20px;
4420
+ text-align: center;
4421
+ }
4422
+ .share-modal-row {
4423
+ display: flex;
4424
+ align-items: flex-start;
4425
+ gap: 10px;
4426
+ padding: 8px 4px;
4427
+ cursor: pointer;
4428
+ border-bottom: 1px solid var(--border);
4429
+ font-family: inherit;
4430
+ }
4431
+ .share-modal-row:hover {
4432
+ background: var(--bg-hover);
4433
+ }
4434
+ .share-modal-cb {
4435
+ margin-top: 4px;
4436
+ cursor: pointer;
4437
+ width: 16px;
4438
+ height: 16px;
4439
+ accent-color: var(--accent);
4440
+ }
4441
+ .share-modal-row-info {
4442
+ flex: 1;
4443
+ min-width: 0;
4444
+ }
4445
+ .share-modal-row-name {
4446
+ font-size: 13px;
4447
+ font-weight: 500;
4448
+ color: var(--text);
4449
+ }
4450
+ .share-modal-row-meta {
4451
+ font-size: 10px;
4452
+ color: var(--text-muted);
4453
+ margin-top: 2px;
4454
+ font-family: 'JetBrains Mono', monospace;
4455
+ }
@@ -1,131 +0,0 @@
1
- /**
2
- * AdaptiveHeartbeat - 动态心跳策略
3
- *
4
- * 基于活跃度、信息素密度等因子动态调整心跳间隔
5
- */
6
-
7
- import {
8
- HeartbeatDecision,
9
- AdaptiveHeartbeatConfig,
10
- DEFAULT_ADAPTIVE_CONFIG,
11
- } from './types.js';
12
-
13
- export class AdaptiveHeartbeat {
14
- private config: AdaptiveHeartbeatConfig;
15
- private lastActivityTime: number = Date.now();
16
- private activityHistory: number[] = [];
17
- private recentDiscoveries: number = 0;
18
- private pheromoneDensity: number = 0;
19
- private discoveryBoost: number = 0;
20
- private activityTimer: ReturnType<typeof setInterval> | null = null;
21
-
22
- constructor(config?: Partial<AdaptiveHeartbeatConfig>) {
23
- this.config = { ...DEFAULT_ADAPTIVE_CONFIG, ...config };
24
- this.startActivityTracking();
25
- }
26
-
27
- /**
28
- * 获取下一次心跳的决策
29
- */
30
- decide(): HeartbeatDecision {
31
- const now = Date.now();
32
- const timeSinceLastActivity = now - this.lastActivityTime;
33
-
34
- const activityRate = this.calculateActivityRate();
35
- const pheromoneFactor = this.pheromoneDensity;
36
- const discoveryFactor = this.calculateDiscoveryFactor();
37
-
38
- const combinedFactor =
39
- activityRate * 0.2 +
40
- pheromoneFactor * this.config.pheromoneBoostFactor +
41
- discoveryFactor * this.config.discoveryBoostFactor;
42
-
43
- const interval = Math.max(
44
- this.config.minInterval,
45
- Math.min(
46
- this.config.maxInterval,
47
- this.config.baseInterval * (1 - combinedFactor * 0.7)
48
- )
49
- );
50
-
51
- let priority: HeartbeatDecision['priorityLevel'] = 'normal';
52
- if (discoveryFactor > 0.5 || this.discoveryBoost > 0.6) {
53
- priority = 'high';
54
- } else if (this.discoveryBoost > 0.8) {
55
- priority = 'urgent';
56
- } else if (activityRate < this.config.lowActivityThreshold) {
57
- priority = 'low';
58
- }
59
-
60
- return {
61
- interval: Math.round(interval),
62
- shouldExplore: discoveryFactor > 0.3 || pheromoneFactor > 0.5,
63
- shouldBroadcast: priority !== 'low' || timeSinceLastActivity > this.config.baseInterval,
64
- priorityLevel: priority,
65
- };
66
- }
67
-
68
- /**
69
- * 记录活跃事件
70
- */
71
- recordActivity(type: 'message' | 'discovery' | 'channel'): void {
72
- const now = Date.now();
73
- this.lastActivityTime = now;
74
- this.activityHistory.push(now);
75
-
76
- if (type === 'discovery') {
77
- this.recentDiscoveries++;
78
- this.discoveryBoost = Math.min(1, this.discoveryBoost + 0.2);
79
- }
80
-
81
- this.discoveryBoost = Math.max(0, this.discoveryBoost - 0.05);
82
- }
83
-
84
- /**
85
- * 设置信息素密度
86
- */
87
- setPheromoneDensity(density: number): void {
88
- this.pheromoneDensity = Math.max(0, Math.min(1, density));
89
- }
90
-
91
- /**
92
- * 获取当前配置
93
- */
94
- getConfig(): AdaptiveHeartbeatConfig {
95
- return { ...this.config };
96
- }
97
-
98
- /**
99
- * 更新配置
100
- */
101
- updateConfig(updates: Partial<AdaptiveHeartbeatConfig>): void {
102
- this.config = { ...this.config, ...updates };
103
- }
104
-
105
- private calculateActivityRate(): number {
106
- const now = Date.now();
107
- const recentActivity = this.activityHistory.filter(
108
- (t) => now - t < 60000
109
- ).length;
110
- return recentActivity / 60;
111
- }
112
-
113
- private calculateDiscoveryFactor(): number {
114
- return Math.min(1, this.recentDiscoveries / 5);
115
- }
116
-
117
- private startActivityTracking(): void {
118
- this.activityTimer = setInterval(() => {
119
- const cutoff = Date.now() - 5 * 60 * 1000;
120
- this.activityHistory = this.activityHistory.filter((t) => t > cutoff);
121
- this.recentDiscoveries = Math.max(0, this.recentDiscoveries - 1);
122
- this.discoveryBoost = Math.max(0, this.discoveryBoost - 0.1);
123
- }, 60000);
124
- }
125
-
126
- shutdown(): void {
127
- if (this.activityTimer) {
128
- clearInterval(this.activityTimer);
129
- }
130
- }
131
- }