@bolloon/bolloon-agent 0.1.38 → 0.1.39

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 (33) hide show
  1. package/dist/agents/constraint-layer.js +1 -2
  2. package/dist/web/client.js +2861 -3746
  3. package/dist/web/components/p2p/index.js +226 -264
  4. package/dist/web/ui/message-renderer.js +323 -434
  5. package/dist/web/ui/step-timeline.js +255 -351
  6. package/package.json +1 -1
  7. package/dist/bollharness-integration/llm/pi-ai.js +0 -397
  8. package/dist/bollharness-integration/pi-ecosystem-colony/index.js +0 -365
  9. package/dist/bollharness-integration/pi-ecosystem-goals/index.js +0 -458
  10. package/dist/bollharness-integration/pi-ecosystem-judgment/decision.js +0 -300
  11. package/dist/bollharness-integration/pi-ecosystem-judgment/distillation.js +0 -291
  12. package/dist/bollharness-integration/pi-ecosystem-judgment/index.js +0 -445
  13. package/dist/bollharness-integration/pi-ecosystem-mcp/index.js +0 -331
  14. package/dist/bollharness-integration/pi-ecosystem-subagents/index.js +0 -303
  15. package/dist/constraints/commands.js +0 -100
  16. package/dist/constraints/permissions.js +0 -37
  17. package/dist/constraints/runtime.js +0 -135
  18. package/dist/constraints/session.js +0 -48
  19. package/dist/constraints/system-init.js +0 -51
  20. package/dist/constraints/tools.js +0 -104
  21. package/dist/llm/minimax-provider.js +0 -46
  22. package/dist/llm/minimax.js +0 -45
  23. package/dist/pi-ecosystem-colony/index.js +0 -365
  24. package/dist/runtime/context/minimax-prompt.js +0 -178
  25. package/dist/runtime/context/sys-prompt.js +0 -1
  26. package/dist/social/ant-colony/AdaptiveHeartbeat.js +0 -101
  27. package/dist/social/ant-colony/PheromoneEngine.js +0 -227
  28. package/dist/social/ant-colony/index.js +0 -6
  29. package/dist/social/ant-colony/types.js +0 -24
  30. package/dist/utils/double.js +0 -6
  31. package/dist/web/components/p2p/P2PModal.js +0 -188
  32. package/dist/web/components/p2p/p2p-modal.js +0 -657
  33. package/dist/web/components/p2p/p2p-tools.js +0 -248
@@ -1,300 +0,0 @@
1
- /**
2
- * Decision Request & Authorization Flow
3
- *
4
- * Handles decision requests when agent confidence is below threshold.
5
- * Supports consulting internal agents (colony/subagents) and external agents (P2P).
6
- *
7
- * Flow:
8
- * Agent Decision Need
9
- * ↓
10
- * Query ValueFunction → Calculate Confidence
11
- * ↓
12
- * Confidence > Threshold → Execute
13
- * ↓ (No)
14
- * DecisionRequest → [Human | Internal Agents | External Agents]
15
- * ↓
16
- * Authorization / Collaboration
17
- * ↓
18
- * Execute & Archive Judgment
19
- */
20
- import { EventEmitter } from 'events';
21
- import { getValueFunction, calculateConfidence, } from './index.js';
22
- import { distillInput, isJudgmentSignal, detectTrigger, processFeedback, } from './distillation.js';
23
- import { listAnts } from '../pi-ecosystem-colony/index.js';
24
- import { listSubagents } from '../pi-ecosystem-subagents/index.js';
25
- class DecisionEventEmitter extends EventEmitter {
26
- }
27
- const decisionEvents = new DecisionEventEmitter();
28
- const decisionRequests = new Map();
29
- let defaultThreshold = 0.7;
30
- let defaultLevel = 'autonomous';
31
- function generateDecisionId() {
32
- return `dec-${Date.now()}-${Math.random().toString(36).substring(2, 8)}`;
33
- }
34
- /**
35
- * Set default confidence threshold
36
- */
37
- export function setConfidenceThreshold(threshold) {
38
- defaultThreshold = Math.max(0, Math.min(1, threshold));
39
- }
40
- /**
41
- * Get default confidence threshold
42
- */
43
- export function getConfidenceThreshold() {
44
- return defaultThreshold;
45
- }
46
- /**
47
- * Set default decision level
48
- */
49
- export function setDefaultDecisionLevel(level) {
50
- defaultLevel = level;
51
- }
52
- /**
53
- * Get default decision level
54
- */
55
- export function getDefaultDecisionLevel() {
56
- return defaultLevel;
57
- }
58
- /**
59
- * Evaluate a decision need and determine appropriate level
60
- */
61
- export async function evaluateDecision(description, context, agentId, threshold) {
62
- const effectiveThreshold = threshold ?? defaultThreshold;
63
- const valueFunction = await getValueFunction(context);
64
- const judgments = valueFunction.judgments.filter((j) => j.context?.toLowerCase().includes(context.toLowerCase()));
65
- const confidence = calculateConfidence(judgments);
66
- const level = determineDecisionLevel(confidence, effectiveThreshold);
67
- const targets = determineConsultationTargets(level);
68
- const request = {
69
- id: generateDecisionId(),
70
- description,
71
- context,
72
- confidence,
73
- threshold: effectiveThreshold,
74
- level,
75
- targets,
76
- status: 'pending',
77
- agentId,
78
- createdAt: new Date().toISOString(),
79
- };
80
- decisionRequests.set(request.id, request);
81
- decisionEvents.emit('decisionCreated', request);
82
- console.log(`[Decision] Request ${request.id}: confidence=${confidence.toFixed(2)}, level=${level}`);
83
- return request;
84
- }
85
- /**
86
- * Determine decision level based on confidence
87
- */
88
- function determineDecisionLevel(confidence, threshold) {
89
- if (confidence >= threshold) {
90
- return 'autonomous';
91
- }
92
- if (confidence >= threshold * 0.7) {
93
- return 'consult_internal';
94
- }
95
- if (confidence >= threshold * 0.4) {
96
- return 'consult_external';
97
- }
98
- return 'require_human';
99
- }
100
- /**
101
- * Determine consultation targets based on decision level
102
- */
103
- function determineConsultationTargets(level) {
104
- switch (level) {
105
- case 'autonomous':
106
- return [];
107
- case 'consult_internal':
108
- return ['colony_ant', 'subagent'];
109
- case 'consult_external':
110
- return ['colony_ant', 'subagent', 'p2p_agent'];
111
- case 'require_human':
112
- return ['human'];
113
- default:
114
- return [];
115
- }
116
- }
117
- /**
118
- * Submit a decision response
119
- */
120
- export async function submitDecisionResponse(requestId, response) {
121
- const request = decisionRequests.get(requestId);
122
- if (!request)
123
- return null;
124
- request.response = response;
125
- request.respondedAt = new Date().toISOString();
126
- if (response.authorized) {
127
- request.status = 'authorized';
128
- }
129
- else {
130
- request.status = 'rejected';
131
- }
132
- decisionRequests.set(requestId, request);
133
- decisionEvents.emit('decisionResponded', request);
134
- if (response.delegate) {
135
- console.log(`[Decision] Request ${requestId} delegated to ${response.delegate}`);
136
- }
137
- return request;
138
- }
139
- /**
140
- * Check if input is a decision response
141
- */
142
- export function isDecisionResponse(input) {
143
- const patterns = [
144
- /^(是|可以|同意|授权|执行|对|好|ok|yes|y)/i,
145
- /^(不|否|拒绝|不行|no|n)/i,
146
- /^(修改|改为|改成|用|用这个)/i,
147
- ];
148
- return patterns.some((p) => p.test(input.trim()));
149
- }
150
- /**
151
- * Parse decision response from natural language
152
- */
153
- export function parseDecisionResponse(input) {
154
- const trimmed = input.trim().toLowerCase();
155
- if (/^(是|可以|同意|授权|执行|对|好|ok|yes|y)/.test(trimmed)) {
156
- return { authorized: true, content: input };
157
- }
158
- if (/^(不|否|拒绝|不行|no|n)/.test(trimmed)) {
159
- return { authorized: false, content: input };
160
- }
161
- if (/^(修改|改为|改成|用|用这个)/.test(trimmed)) {
162
- const match = input.match(/^(?:修改|改为|改成|用|用这个)\s*(.+)/i);
163
- return {
164
- authorized: true,
165
- modifier: match ? match[1] : input,
166
- content: input,
167
- };
168
- }
169
- return { authorized: true, content: input };
170
- }
171
- /**
172
- * Query internal agents (colony ants and subagents)
173
- */
174
- export async function queryInternalAgents(request) {
175
- const results = [];
176
- if (request.targets.includes('colony_ant')) {
177
- const ants = listAnts().filter((a) => a.signal !== 'COMPLETE' && a.signal !== 'FAILED');
178
- for (const ant of ants.slice(0, 3)) {
179
- const result = await consultColonyAnt(ant, request);
180
- if (result)
181
- results.push(result);
182
- }
183
- }
184
- if (request.targets.includes('subagent')) {
185
- const subagents = listSubagents().filter((s) => s.status === 'running');
186
- for (const subagent of subagents.slice(0, 2)) {
187
- const result = await consultSubagent(subagent, request);
188
- if (result)
189
- results.push(result);
190
- }
191
- }
192
- return results;
193
- }
194
- /**
195
- * Consult a colony ant
196
- */
197
- async function consultColonyAnt(ant, request) {
198
- console.log(`[Decision] Consulting ant ${ant.name} for ${request.id}`);
199
- return {
200
- target: 'colony_ant',
201
- agentId: ant.id,
202
- response: `[Simulated] Ant ${ant.name} suggests: ${request.description.substring(0, 30)}...`,
203
- confidence: 0.6,
204
- };
205
- }
206
- /**
207
- * Consult a subagent
208
- */
209
- async function consultSubagent(subagent, request) {
210
- console.log(`[Decision] Consulting subagent ${subagent.name} for ${request.id}`);
211
- return {
212
- target: 'subagent',
213
- agentId: subagent.id,
214
- response: `[Simulated] Subagent ${subagent.name} advises: ${request.description.substring(0, 30)}...`,
215
- confidence: 0.65,
216
- };
217
- }
218
- /**
219
- * Process human feedback and distill to judgment
220
- */
221
- export async function processHumanFeedback(requestId, input) {
222
- const request = decisionRequests.get(requestId);
223
- if (!request)
224
- return null;
225
- const parsed = parseDecisionResponse(input);
226
- const by = 'human';
227
- const response = {
228
- authorized: parsed.authorized ?? false,
229
- content: parsed.content ?? input,
230
- modifier: parsed.modifier,
231
- delegate: parsed.delegate,
232
- by,
233
- timestamp: new Date().toISOString(),
234
- };
235
- await submitDecisionResponse(requestId, response);
236
- if (isJudgmentSignal(input)) {
237
- const trigger = detectTrigger(input);
238
- if (trigger) {
239
- const result = await distillInput({
240
- rawInput: input,
241
- trigger,
242
- context: request.context,
243
- });
244
- if (result.success && result.judgment) {
245
- request.judgment = result.judgment;
246
- decisionRequests.set(requestId, request);
247
- }
248
- }
249
- }
250
- const feedback = {
251
- judgmentId: request.judgment?.id || '',
252
- type: parsed.authorized ? 'approve' : 'reject',
253
- correction: parsed.modifier
254
- ? {
255
- original: request.description,
256
- corrected: parsed.modifier,
257
- }
258
- : undefined,
259
- };
260
- if (feedback.judgmentId) {
261
- await processFeedback(feedback);
262
- }
263
- return request;
264
- }
265
- /**
266
- * Get pending decision requests
267
- */
268
- export function getPendingDecisions() {
269
- return Array.from(decisionRequests.values()).filter((r) => r.status === 'pending');
270
- }
271
- /**
272
- * Get decision request by ID
273
- */
274
- export function getDecisionRequest(id) {
275
- return decisionRequests.get(id);
276
- }
277
- /**
278
- * Get decision statistics
279
- */
280
- export function getDecisionStats() {
281
- const requests = Array.from(decisionRequests.values());
282
- return {
283
- pending: requests.filter((r) => r.status === 'pending').length,
284
- authorized: requests.filter((r) => r.status === 'authorized').length,
285
- rejected: requests.filter((r) => r.status === 'rejected').length,
286
- total: requests.length,
287
- };
288
- }
289
- /**
290
- * Subscribe to decision events
291
- */
292
- export function onDecisionEvent(event, callback) {
293
- decisionEvents.on(event, callback);
294
- }
295
- /**
296
- * Unsubscribe from decision events
297
- */
298
- export function offDecisionEvent(event, callback) {
299
- decisionEvents.off(event, callback);
300
- }
@@ -1,291 +0,0 @@
1
- /**
2
- * Judgment Distillation Module
3
- *
4
- * Real-time LLM-based distillation of human input into Judgment principles.
5
- *
6
- * Flow:
7
- * Human Input → Trigger Detection → LLM Extraction → Judgment
8
- * ↓
9
- * Confidence + Evidence
10
- */
11
- import { createJudgment, updateJudgmentConfidence, } from './index.js';
12
- import { getModel } from '../llm/pi-ai.js';
13
- const TRIGGER_PATTERNS = {
14
- explicit: [
15
- /不,我想要(.+)而不是(.+)/i,
16
- /错了,应该是(.+)/i,
17
- /这不是我想要的(.+),要(.+)/i,
18
- /不对,应该(.+)/i,
19
- /重做,要(.+)/i,
20
- /不对,(?:我|应该|要|必须)(.+)/i,
21
- ],
22
- implicit: [
23
- /^(?!.*[?!]).{10,50}$/, // Short statements that might indicate preference
24
- ],
25
- };
26
- const MIN_TRAJECTORY_COUNT = 3;
27
- const IMPLICIT_THRESHOLD = 0.7;
28
- let trajectoryBuffer = new Map();
29
- let llmModel = null;
30
- /**
31
- * Initialize the distillation system
32
- */
33
- export async function initializeDistillation() {
34
- try {
35
- llmModel = getModel();
36
- }
37
- catch {
38
- console.warn('[Distillation] LLM model not available, using fallback');
39
- }
40
- }
41
- /**
42
- * Detect trigger type from human input
43
- */
44
- export function detectTrigger(input) {
45
- for (const pattern of TRIGGER_PATTERNS.explicit) {
46
- if (pattern.test(input)) {
47
- return 'explicit';
48
- }
49
- }
50
- for (const pattern of TRIGGER_PATTERNS.implicit) {
51
- if (pattern.test(input)) {
52
- return 'implicit';
53
- }
54
- }
55
- return null;
56
- }
57
- /**
58
- * Check if input indicates a judgment correction
59
- */
60
- export function detectCorrection(input) {
61
- for (const pattern of TRIGGER_PATTERNS.explicit) {
62
- const match = input.match(pattern);
63
- if (match) {
64
- if (match.length >= 3) {
65
- return { original: match[2], corrected: match[1] };
66
- }
67
- else if (match.length >= 2) {
68
- return { original: '', corrected: match[1] };
69
- }
70
- }
71
- }
72
- return null;
73
- }
74
- /**
75
- * Add to trajectory buffer
76
- */
77
- export function addToTrajectory(agentId, action, outcome, approved) {
78
- if (!trajectoryBuffer.has(agentId)) {
79
- trajectoryBuffer.set(agentId, []);
80
- }
81
- const entries = trajectoryBuffer.get(agentId);
82
- entries.push({
83
- timestamp: new Date().toISOString(),
84
- action,
85
- outcome,
86
- approved,
87
- });
88
- if (entries.length > 20) {
89
- entries.shift();
90
- }
91
- }
92
- /**
93
- * Detect trajectory pattern (repeated similar actions)
94
- */
95
- export function detectTrajectoryPattern(agentId) {
96
- const entries = trajectoryBuffer.get(agentId);
97
- if (!entries || entries.length < MIN_TRAJECTORY_COUNT)
98
- return null;
99
- const approvals = entries.filter((e) => e.approved);
100
- const approvalRate = approvals.length / entries.length;
101
- if (approvalRate >= IMPLICIT_THRESHOLD) {
102
- return entries.slice(-MIN_TRAJECTORY_COUNT);
103
- }
104
- return null;
105
- }
106
- /**
107
- * Distill human input to judgment using LLM
108
- */
109
- export async function distillInput(request) {
110
- const { rawInput, trigger, context, conversationHistory } = request;
111
- console.log(`[Distillation] Distilling input (${trigger}): ${rawInput.substring(0, 50)}...`);
112
- try {
113
- const judgment = await llmDistill(rawInput, trigger, context, conversationHistory);
114
- const created = await createJudgment({
115
- type: judgment.type,
116
- content: judgment.content,
117
- source: 'human',
118
- confidence: judgment.confidence,
119
- context: context,
120
- evidence: judgment.evidence,
121
- });
122
- return {
123
- success: true,
124
- judgment: created,
125
- trigger,
126
- };
127
- }
128
- catch (error) {
129
- return {
130
- success: false,
131
- error: String(error),
132
- trigger,
133
- };
134
- }
135
- }
136
- /**
137
- * LLM-based distillation
138
- */
139
- async function llmDistill(rawInput, trigger, context, conversationHistory) {
140
- if (!llmModel) {
141
- return fallbackDistill(rawInput, trigger);
142
- }
143
- const historyText = conversationHistory
144
- ? conversationHistory.slice(-5).join('\n')
145
- : 'No history';
146
- const prompt = `从以下人类输入中提取判断力原理。
147
-
148
- 输入类型: ${trigger}
149
- 输入内容: ${rawInput}
150
- 上下文: ${context}
151
- 对话历史:
152
- ${historyText}
153
-
154
- 请提取:
155
- 1. type: rule(明确规则) | preference(偏好) | trajectory(行为轨迹) | reward(奖励信号)
156
- 2. content: 凝练后的原理(简洁,1-2句话)
157
- 3. confidence: 0.0-1.0 的置信度
158
- 4. evidence: 支持证据(如有)
159
-
160
- 直接输出JSON格式,不需要解释。`;
161
- try {
162
- const response = await llmModel.chat(`对话: ${historyText}\n\n输入: ${rawInput}`, `你是判断力提取专家。从人类输入中提取判断力原理。输入类型: ${trigger}`);
163
- return parseDistillationResponse(response.reply, rawInput, trigger);
164
- }
165
- catch (error) {
166
- console.warn('[Distillation] LLM distillation failed, using fallback:', error);
167
- return fallbackDistill(rawInput, trigger);
168
- }
169
- }
170
- /**
171
- * Parse LLM distillation response
172
- */
173
- function parseDistillationResponse(response, rawInput, trigger) {
174
- try {
175
- const jsonMatch = response.match(/\{[\s\S]*\}/);
176
- if (jsonMatch) {
177
- const parsed = JSON.parse(jsonMatch[0]);
178
- return {
179
- type: parsed.type || inferType(rawInput, trigger),
180
- content: parsed.content || rawInput,
181
- confidence: Math.min(1, Math.max(0, parseFloat(parsed.confidence) || 0.7)),
182
- };
183
- }
184
- }
185
- catch { }
186
- return {
187
- ...fallbackDistill(rawInput, trigger),
188
- };
189
- }
190
- /**
191
- * Fallback distillation when LLM is unavailable
192
- */
193
- function fallbackDistill(rawInput, trigger) {
194
- const correction = detectCorrection(rawInput);
195
- if (correction) {
196
- return {
197
- type: 'rule',
198
- content: `${correction.corrected}(而非 ${correction.original})`,
199
- confidence: 0.95,
200
- };
201
- }
202
- if (trigger === 'explicit') {
203
- return {
204
- type: 'rule',
205
- content: rawInput,
206
- confidence: 0.9,
207
- };
208
- }
209
- if (trigger === 'trajectory') {
210
- return {
211
- type: 'trajectory',
212
- content: '检测到重复行为模式',
213
- confidence: 0.75,
214
- };
215
- }
216
- return {
217
- type: 'preference',
218
- content: rawInput,
219
- confidence: 0.6,
220
- };
221
- }
222
- /**
223
- * Infer judgment type from input content
224
- */
225
- function inferType(input, trigger) {
226
- const lower = input.toLowerCase();
227
- if (lower.includes('不要') || lower.includes('禁止') || lower.includes('必须') || lower.includes('应该')) {
228
- return 'rule';
229
- }
230
- if (lower.includes('喜欢') || lower.includes('偏好') || lower.includes('宁愿')) {
231
- return 'preference';
232
- }
233
- if (trigger === 'trajectory') {
234
- return 'trajectory';
235
- }
236
- return 'preference';
237
- }
238
- /**
239
- * Process feedback signal
240
- */
241
- export async function processFeedback(signal) {
242
- const { judgmentId, type, correction } = signal;
243
- if (correction) {
244
- await createJudgment({
245
- type: 'rule',
246
- content: correction.corrected,
247
- source: 'human',
248
- confidence: 0.95,
249
- evidence: {
250
- correction: {
251
- original: correction.original,
252
- corrected: correction.corrected,
253
- reason: correction.reason,
254
- timestamp: new Date().toISOString(),
255
- },
256
- },
257
- });
258
- }
259
- await updateJudgmentConfidence(judgmentId, 0.1, type);
260
- }
261
- /**
262
- * Check if human input contains judgment signal
263
- */
264
- export function isJudgmentSignal(input) {
265
- return detectTrigger(input) !== null;
266
- }
267
- /**
268
- * Get trajectory buffer statistics
269
- */
270
- export function getTrajectoryStats() {
271
- const stats = {};
272
- for (const [agentId, entries] of trajectoryBuffer.entries()) {
273
- const approvals = entries.filter((e) => e.approved).length;
274
- stats[agentId] = {
275
- count: entries.length,
276
- approvalRate: entries.length > 0 ? approvals / entries.length : 0,
277
- };
278
- }
279
- return stats;
280
- }
281
- /**
282
- * Clear trajectory buffer for agent
283
- */
284
- export function clearTrajectory(agentId) {
285
- if (agentId) {
286
- trajectoryBuffer.delete(agentId);
287
- }
288
- else {
289
- trajectoryBuffer.clear();
290
- }
291
- }