@bolloon/bolloon-agent 0.1.38 → 0.1.40
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.
- package/dist/agents/constraint-layer.js +1 -2
- package/dist/llm/system-prompt/layers/channel/local.md +14 -0
- package/dist/llm/system-prompt/layers/channel/p2p-agent.md +18 -0
- package/dist/llm/system-prompt/layers/channel/p2p-visitor.md +19 -0
- package/dist/llm/system-prompt/layers/core/artifacts_storage.md +89 -0
- package/dist/llm/system-prompt/layers/core/evenhandedness.md +21 -0
- package/dist/llm/system-prompt/layers/core/hibs_reminders.md +15 -0
- package/dist/llm/system-prompt/layers/core/identity.md +37 -0
- package/dist/llm/system-prompt/layers/core/knowledge.md +17 -0
- package/dist/llm/system-prompt/layers/core/memory_system.md +12 -0
- package/dist/llm/system-prompt/layers/core/network_filesystem.md +28 -0
- package/dist/llm/system-prompt/layers/core/refusal.md +37 -0
- package/dist/llm/system-prompt/layers/core/tone.md +31 -0
- package/dist/llm/system-prompt/layers/core/tools.thin.md +13 -0
- package/dist/llm/system-prompt/layers/core/wellbeing.md +41 -0
- package/dist/llm/system-prompt/layers/role/architect.md +20 -0
- package/dist/llm/system-prompt/layers/role/expert.md +19 -0
- package/dist/llm/system-prompt/layers/role/implementer.md +15 -0
- package/dist/llm/system-prompt/layers/role/security.md +15 -0
- package/dist/llm/system-prompt/layers/tool/artifacts.md +72 -0
- package/dist/llm/system-prompt/layers/tool/bash.md +25 -0
- package/dist/llm/system-prompt/layers/tool/hibs_api.md +171 -0
- package/dist/llm/system-prompt/layers/tool/image_search.md +70 -0
- package/dist/llm/system-prompt/layers/tool/manifest.md +89 -0
- package/dist/llm/system-prompt/layers/tool/mcp_apps.md +53 -0
- package/dist/llm/system-prompt/layers/tool/web_search.md +83 -0
- package/dist/llm/system-prompt/registry.js +5 -1
- package/dist/web/client.js +28 -1
- package/dist/web/server.js +37 -5
- package/dist/web/ui/message-renderer.js +9 -0
- package/package.json +1 -1
- package/dist/bollharness-integration/llm/pi-ai.js +0 -397
- package/dist/bollharness-integration/pi-ecosystem-colony/index.js +0 -365
- package/dist/bollharness-integration/pi-ecosystem-goals/index.js +0 -458
- package/dist/bollharness-integration/pi-ecosystem-judgment/decision.js +0 -300
- package/dist/bollharness-integration/pi-ecosystem-judgment/distillation.js +0 -291
- package/dist/bollharness-integration/pi-ecosystem-judgment/index.js +0 -445
- package/dist/bollharness-integration/pi-ecosystem-mcp/index.js +0 -331
- package/dist/bollharness-integration/pi-ecosystem-subagents/index.js +0 -303
- package/dist/constraints/commands.js +0 -100
- package/dist/constraints/permissions.js +0 -37
- package/dist/constraints/runtime.js +0 -135
- package/dist/constraints/session.js +0 -48
- package/dist/constraints/system-init.js +0 -51
- package/dist/constraints/tools.js +0 -104
- package/dist/llm/minimax-provider.js +0 -46
- package/dist/llm/minimax.js +0 -45
- package/dist/pi-ecosystem-colony/index.js +0 -365
- package/dist/runtime/context/minimax-prompt.js +0 -178
- package/dist/runtime/context/sys-prompt.js +0 -1
- package/dist/social/ant-colony/AdaptiveHeartbeat.js +0 -101
- package/dist/social/ant-colony/PheromoneEngine.js +0 -227
- package/dist/social/ant-colony/index.js +0 -6
- package/dist/social/ant-colony/types.js +0 -24
- package/dist/utils/double.js +0 -6
|
@@ -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
|
-
}
|