@hmharness/agent 0.23.6 → 0.23.8
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/cognitive-recorder.d.ts +15 -4
- package/dist/cognitive-recorder.js +73 -30
- package/package.json +8 -8
|
@@ -1,8 +1,16 @@
|
|
|
1
|
+
/** tool name → environment id. Calibration trends group by environment, so
|
|
2
|
+
* a browser_open step filed under "terminal" would silently pollute the
|
|
3
|
+
* terminal curve and starve the browser one. harmony_ops_* stays terminal:
|
|
4
|
+
* radar/brief are network reads, not device actions. */
|
|
5
|
+
export declare function envForTool(toolName: string): string;
|
|
1
6
|
export declare class CognitiveRunRecorder {
|
|
2
7
|
private home;
|
|
3
|
-
private
|
|
4
|
-
private
|
|
8
|
+
private task;
|
|
9
|
+
private sessionId;
|
|
5
10
|
private store;
|
|
11
|
+
/** one recorder per environment actually touched in this run */
|
|
12
|
+
private recs;
|
|
13
|
+
private envTools;
|
|
6
14
|
private open;
|
|
7
15
|
private seq;
|
|
8
16
|
private failures;
|
|
@@ -11,15 +19,18 @@ export declare class CognitiveRunRecorder {
|
|
|
11
19
|
* task step carry a prediction, feeding the calibration dimension (the
|
|
12
20
|
* §26-proven value) from 115/3043 steps toward full coverage */
|
|
13
21
|
private beliefs;
|
|
14
|
-
constructor(home: string, task: string, sessionId: string,
|
|
22
|
+
constructor(home: string, task: string, sessionId: string, _cwd: string);
|
|
15
23
|
private seedBeliefs;
|
|
16
24
|
private predict;
|
|
17
25
|
private learn;
|
|
26
|
+
private recFor;
|
|
27
|
+
private countEnv;
|
|
18
28
|
/** loop onToolCall: open a step for this tool invocation */
|
|
19
29
|
call(toolName: string, args: Record<string, unknown>): void;
|
|
20
30
|
/** loop onToolResult: close the matching step (same tool, FIFO) */
|
|
21
31
|
result(toolName: string, _output: string, isError: boolean): void;
|
|
22
|
-
/** task end: persist trajectory
|
|
32
|
+
/** task end: persist one trajectory per touched environment + an episodic
|
|
33
|
+
* memory entry each; the primary (busiest) trajectory id is returned */
|
|
23
34
|
finish(success: boolean, meta: {
|
|
24
35
|
turns: number;
|
|
25
36
|
toolUses: number;
|
|
@@ -3,18 +3,37 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Bridges the LIVE agent loop into the Cognitive OS: every tool call becomes
|
|
5
5
|
* a cognitive trajectory step (action type = tool name, reason = the loop's
|
|
6
|
-
* own event context), and at task end the
|
|
7
|
-
* store (HMH_HOME/cognitive/trajectories/) PLUS
|
|
8
|
-
*
|
|
9
|
-
* environment/session — MEM-007).
|
|
10
|
-
*
|
|
6
|
+
* own event context), and at task end the trajectories land in the episodic
|
|
7
|
+
* store (HMH_HOME/cognitive/trajectories/) PLUS episodic memory index
|
|
8
|
+
* entries with full provenance (source/provenance/confidence/timestamp/
|
|
9
|
+
* environment/session — MEM-007). Steps are attributed to their REAL
|
|
10
|
+
* environment by tool name (browser_, desktop_ and harmony_ prefixed tools
|
|
11
|
+
* feed their own curves) so per-env calibration trends grow from genuine
|
|
12
|
+
* usage. Everything here is best-effort: cognitive recording must never
|
|
13
|
+
* break a task run.
|
|
11
14
|
*/
|
|
12
15
|
import { TrajectoryStore, TrajectoryRecorder, CognitiveMemory, loadTrajectories } from '@hmharness/cognitive';
|
|
16
|
+
/** tool name → environment id. Calibration trends group by environment, so
|
|
17
|
+
* a browser_open step filed under "terminal" would silently pollute the
|
|
18
|
+
* terminal curve and starve the browser one. harmony_ops_* stays terminal:
|
|
19
|
+
* radar/brief are network reads, not device actions. */
|
|
20
|
+
export function envForTool(toolName) {
|
|
21
|
+
if (toolName.startsWith('browser_'))
|
|
22
|
+
return 'browser';
|
|
23
|
+
if (toolName.startsWith('desktop_'))
|
|
24
|
+
return 'desktop';
|
|
25
|
+
if (toolName.startsWith('harmony_') && !toolName.startsWith('harmony_ops_'))
|
|
26
|
+
return 'harmonyos';
|
|
27
|
+
return 'terminal';
|
|
28
|
+
}
|
|
13
29
|
export class CognitiveRunRecorder {
|
|
14
30
|
home;
|
|
15
|
-
|
|
16
|
-
|
|
31
|
+
task;
|
|
32
|
+
sessionId;
|
|
17
33
|
store;
|
|
34
|
+
/** one recorder per environment actually touched in this run */
|
|
35
|
+
recs = new Map();
|
|
36
|
+
envTools = new Map();
|
|
18
37
|
open = new Map();
|
|
19
38
|
seq = 0;
|
|
20
39
|
failures = 0;
|
|
@@ -23,11 +42,11 @@ export class CognitiveRunRecorder {
|
|
|
23
42
|
* task step carry a prediction, feeding the calibration dimension (the
|
|
24
43
|
* §26-proven value) from 115/3043 steps toward full coverage */
|
|
25
44
|
beliefs = new Map();
|
|
26
|
-
constructor(home, task, sessionId,
|
|
45
|
+
constructor(home, task, sessionId, _cwd) {
|
|
27
46
|
this.home = home;
|
|
28
|
-
this.
|
|
47
|
+
this.task = task;
|
|
48
|
+
this.sessionId = sessionId;
|
|
29
49
|
this.store = new TrajectoryStore(home);
|
|
30
|
-
this.rec = new TrajectoryRecorder(`trj-${sessionId}-${Date.now().toString(36)}`, sessionId, { id: 'terminal', version: '1.0.0' }, { id: `goal-${sessionId}`, description: task });
|
|
31
50
|
// seed beliefs from recent history (best-effort, never blocks a task)
|
|
32
51
|
void this.seedBeliefs().catch(() => undefined);
|
|
33
52
|
}
|
|
@@ -58,6 +77,19 @@ export class CognitiveRunRecorder {
|
|
|
58
77
|
b.n += 1;
|
|
59
78
|
this.beliefs.set(type, b);
|
|
60
79
|
}
|
|
80
|
+
recFor(env) {
|
|
81
|
+
// created lazily at RESULT time: calls that never returned must not
|
|
82
|
+
// leave empty trajectories behind
|
|
83
|
+
let rec = this.recs.get(env);
|
|
84
|
+
if (!rec) {
|
|
85
|
+
rec = new TrajectoryRecorder(`trj-${this.sessionId}-${Date.now().toString(36)}-${env}`, this.sessionId, { id: env, version: '1.0.0' }, { id: `goal-${this.sessionId}`, description: this.task });
|
|
86
|
+
this.recs.set(env, rec);
|
|
87
|
+
}
|
|
88
|
+
return rec;
|
|
89
|
+
}
|
|
90
|
+
countEnv(env) {
|
|
91
|
+
this.envTools.set(env, (this.envTools.get(env) ?? 0) + 1);
|
|
92
|
+
}
|
|
61
93
|
/** loop onToolCall: open a step for this tool invocation */
|
|
62
94
|
call(toolName, args) {
|
|
63
95
|
const key = `${toolName}#${++this.seq}`;
|
|
@@ -65,6 +97,7 @@ export class CognitiveRunRecorder {
|
|
|
65
97
|
action: { id: key, type: toolName, args: clip(args), reason: 'agent loop tool call' },
|
|
66
98
|
startedAt: Date.now(),
|
|
67
99
|
prediction: this.predict(toolName),
|
|
100
|
+
env: envForTool(toolName),
|
|
68
101
|
});
|
|
69
102
|
}
|
|
70
103
|
/** loop onToolResult: close the matching step (same tool, FIFO) */
|
|
@@ -79,7 +112,8 @@ export class CognitiveRunRecorder {
|
|
|
79
112
|
else
|
|
80
113
|
this.successes += 1;
|
|
81
114
|
this.learn(toolName, success);
|
|
82
|
-
this.
|
|
115
|
+
this.countEnv(open.env);
|
|
116
|
+
this.recFor(open.env).record({
|
|
83
117
|
action: open.action,
|
|
84
118
|
outcome: isError ? 'failure' : 'success',
|
|
85
119
|
evidence: [],
|
|
@@ -90,36 +124,45 @@ export class CognitiveRunRecorder {
|
|
|
90
124
|
}
|
|
91
125
|
// result without a matching open call (e.g. preflight rejection): still
|
|
92
126
|
// record it so denials are visible in the trajectory
|
|
93
|
-
|
|
127
|
+
const env = envForTool(toolName);
|
|
128
|
+
this.countEnv(env);
|
|
129
|
+
this.recFor(env).record({
|
|
94
130
|
action: { id: `${toolName}#${++this.seq}`, type: toolName, args: {}, reason: 'tool result without recorded call' },
|
|
95
131
|
outcome: isError ? 'failure' : 'success',
|
|
96
132
|
evidence: [],
|
|
97
133
|
prediction: this.predict(toolName),
|
|
98
134
|
});
|
|
99
135
|
}
|
|
100
|
-
/** task end: persist trajectory
|
|
136
|
+
/** task end: persist one trajectory per touched environment + an episodic
|
|
137
|
+
* memory entry each; the primary (busiest) trajectory id is returned */
|
|
101
138
|
async finish(success, meta) {
|
|
102
139
|
try {
|
|
103
|
-
const
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
140
|
+
const written = [];
|
|
141
|
+
for (const [env, rec] of this.recs) {
|
|
142
|
+
const traj = rec.finish(success);
|
|
143
|
+
const w = await this.store.append(traj);
|
|
144
|
+
if (w.ok)
|
|
145
|
+
written.push({ env, traj });
|
|
146
|
+
}
|
|
147
|
+
if (written.length === 0)
|
|
108
148
|
return null;
|
|
109
149
|
const mem = new CognitiveMemory(this.home);
|
|
110
150
|
await mem.load();
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
151
|
+
for (const { traj } of written) {
|
|
152
|
+
await mem.write({
|
|
153
|
+
layer: 'episodic',
|
|
154
|
+
content: `${success ? 'OK' : 'FAIL'} ${traj.environment.id}:${this.envTools.get(traj.environment.id) ?? traj.metrics.actions} tools/${meta.turns} turns: ${meta.task.slice(0, 120)}`,
|
|
155
|
+
payload: { trajectoryId: traj.id, tools: this.envTools.get(traj.environment.id) ?? traj.metrics.actions, turns: meta.turns, successes: this.successes, failures: this.failures },
|
|
156
|
+
source: 'agent-run',
|
|
157
|
+
provenance: `trajectory:${traj.id}`,
|
|
158
|
+
confidence: success ? 0.9 : 0.6,
|
|
159
|
+
environment: traj.environment.id,
|
|
160
|
+
session: traj.sessionId,
|
|
161
|
+
tags: ['run', success ? 'ok' : 'fail', traj.environment.id],
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
const primary = [...written].sort((a, b) => b.traj.metrics.actions - a.traj.metrics.actions)[0];
|
|
165
|
+
return { trajectoryId: primary.traj.id };
|
|
123
166
|
}
|
|
124
167
|
catch {
|
|
125
168
|
return null; // cognitive recording is best-effort, never fatal
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hmharness/agent",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.8",
|
|
4
4
|
"description": "hmharness agent execution layer: base tools, system prompt, sub-agent spawn, and the shared task runner that frontends (cli, web) drive.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -15,13 +15,13 @@
|
|
|
15
15
|
"build": "tsc -p tsconfig.build.json"
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
|
-
"@hmharness/cognitive": "0.23.
|
|
19
|
-
"@hmharness/domain-harmony": "0.23.
|
|
20
|
-
"@hmharness/domain-ops": "0.23.
|
|
21
|
-
"@hmharness/evolution": "0.23.
|
|
22
|
-
"@hmharness/kernel": "0.23.
|
|
23
|
-
"@hmharness/observability": "0.23.
|
|
24
|
-
"@hmharness/sandbox": "0.23.
|
|
18
|
+
"@hmharness/cognitive": "0.23.7",
|
|
19
|
+
"@hmharness/domain-harmony": "0.23.7",
|
|
20
|
+
"@hmharness/domain-ops": "0.23.7",
|
|
21
|
+
"@hmharness/evolution": "0.23.7",
|
|
22
|
+
"@hmharness/kernel": "0.23.7",
|
|
23
|
+
"@hmharness/observability": "0.23.7",
|
|
24
|
+
"@hmharness/sandbox": "0.23.7"
|
|
25
25
|
},
|
|
26
26
|
"files": [
|
|
27
27
|
"dist"
|