mixdog 1.0.1 → 1.0.3
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/README.md +8 -0
- package/package.json +2 -2
- package/src/defaults/skills/browser-use/SKILL.md +14 -6
- package/src/defaults/skills/setup/references/actions.md +6 -3
- package/src/defaults/skills/setup/references/surfaces.md +8 -4
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +0 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-midstream-recovery.mjs +10 -1
- package/src/runtime/agent/orchestrator/session/cache/scoped-cache.mjs +40 -99
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +6 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +7 -3
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/cache-layers.mjs +18 -38
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-path-fanout.mjs +59 -32
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-pattern-fanout.mjs +15 -10
- package/src/runtime/agent/orchestrator/tools/builtin/lib/grep-request.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shared-native-scan.mjs +12 -0
- package/src/runtime/agent/orchestrator/tools/builtin/read-source-windows.mjs +14 -0
- package/src/runtime/agent/orchestrator/tools/graph-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/patch/apply-patch/codex-batch.mjs +3 -1
- package/src/runtime/agent/orchestrator/tools/patch/dispatch.mjs +17 -9
- package/src/runtime/agent/orchestrator/tools/patch/orchestrator.mjs +1 -0
- package/src/runtime/agent/orchestrator/tools/patch/wave.mjs +4 -0
- package/src/runtime/browser-bridge/input-fields.mjs +1 -1
- package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
- package/src/runtime/computer-bridge/actions.mjs +0 -13
- package/src/runtime/media/adapters/antigravity-image.mjs +7 -3
- package/src/runtime/media/adapters/codex-image.mjs +12 -1
- package/src/runtime/media/adapters/gemini-image.mjs +17 -6
- package/src/runtime/media/adapters/gemini-video.mjs +19 -9
- package/src/runtime/media/adapters/xai-media.mjs +20 -7
- package/src/runtime/media/jobs.mjs +35 -3
- package/src/runtime/media/media-usage.mjs +126 -0
- package/src/runtime/media/tool.mjs +16 -4
- package/src/runtime/shared/llm/cost.mjs +50 -3
- package/src/runtime/shared/llm/model-catalog-projection.mjs +7 -2
- package/src/runtime/shared/llm/model-catalog.mjs +2 -1
- package/src/runtime/shared/llm/model-pricing-rates.mjs +21 -0
- package/src/runtime/shared/llm/usage-accounting.mjs +25 -5
- package/src/runtime/shared/llm/usage-context.mjs +6 -0
- package/src/runtime/shared/llm/usage-ledger-import.mjs +1 -0
- package/src/session-runtime/cwd-plugins/plugin-status.mjs +24 -4
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +9 -1
- package/src/session-runtime/services/agent-tool/index-write-queue.mjs +38 -6
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +9 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +6 -3
- package/src/session-runtime/services/hook-bus/event-runner.mjs +10 -2
- package/src/session-runtime/services/hook-bus/tool-gate.mjs +5 -2
- package/src/session-runtime/setup-tool/tool-defs.mjs +1 -1
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +8 -5
- package/src/tui/app/doctor.mjs +78 -2
- package/src/tui/dist/index.mjs +7 -3
- package/scripts/lib/bench-sandbox.test.mjs +0 -54
- package/scripts/lib/cli-args.test.mjs +0 -64
- package/scripts/lib/embedding-model-bench-core.test.mjs +0 -47
- package/scripts/lib/smoke-loop-shared.test.mjs +0 -22
- package/scripts/lib/trace-row.test.mjs +0 -47
- package/scripts/lib/trace-stats.test.mjs +0 -62
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import test from 'node:test';
|
|
3
|
-
import { resolve } from 'node:path';
|
|
4
|
-
import { defaultTraceFiles, field, num, payload, sessionId } from './trace-row.mjs';
|
|
5
|
-
|
|
6
|
-
test('defaultTraceFiles: an explicit path wins, a data dir yields its rotated pair', () => {
|
|
7
|
-
assert.deepEqual(defaultTraceFiles({ pathArg: 'x.jsonl' }), [resolve('x.jsonl')]);
|
|
8
|
-
assert.deepEqual(defaultTraceFiles({ dataDir: 'd' }), [
|
|
9
|
-
resolve('d', 'history', 'agent-trace.jsonl.1'),
|
|
10
|
-
resolve('d', 'history', 'agent-trace.jsonl'),
|
|
11
|
-
]);
|
|
12
|
-
});
|
|
13
|
-
|
|
14
|
-
test('defaultTraceFiles without arguments covers the project and user data dirs, deduplicated', () => {
|
|
15
|
-
const files = defaultTraceFiles();
|
|
16
|
-
assert.equal(files.length, new Set(files).size);
|
|
17
|
-
assert.ok(files.includes(resolve(process.cwd(), '.mixdog', 'data', 'history', 'agent-trace.jsonl')));
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
test('payload is the row payload object, else an empty object', () => {
|
|
21
|
-
assert.deepEqual(payload({ payload: { a: 1 } }), { a: 1 });
|
|
22
|
-
assert.deepEqual(payload({ payload: 'text' }), {});
|
|
23
|
-
assert.deepEqual(payload(null), {});
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
test('field prefers the row itself, falls back to the payload, else null', () => {
|
|
27
|
-
assert.equal(field({ a: 1, payload: { a: 2 } }, 'a'), 1);
|
|
28
|
-
assert.equal(field({ payload: { a: 2 } }, 'a'), 2);
|
|
29
|
-
assert.equal(field({ a: null, payload: { a: 3 } }, 'a'), 3);
|
|
30
|
-
assert.equal(field({}, 'a'), null);
|
|
31
|
-
assert.equal(field(undefined, 'a'), null);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
test('num coerces the field and drops non-finite values', () => {
|
|
35
|
-
assert.equal(num({ payload: { n: '12' } }, 'n'), 12);
|
|
36
|
-
assert.equal(num({ n: 'x' }, 'n'), null);
|
|
37
|
-
// A missing field reads as Number(null) === 0, not null (existing behavior
|
|
38
|
-
// of every trace CLI that used its own copy).
|
|
39
|
-
assert.equal(num({}, 'n'), 0);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test('sessionId reads either spelling, then the payload, as a string', () => {
|
|
43
|
-
assert.equal(sessionId({ session_id: 's1' }), 's1');
|
|
44
|
-
assert.equal(sessionId({ sessionId: 's2' }), 's2');
|
|
45
|
-
assert.equal(sessionId({ payload: { session_id: 's3' } }), 's3');
|
|
46
|
-
assert.equal(sessionId({}), '');
|
|
47
|
-
});
|
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
import assert from 'node:assert/strict';
|
|
2
|
-
import test from 'node:test';
|
|
3
|
-
import { distribution, median, percentile, sortedFinite, stats } from './trace-stats.mjs';
|
|
4
|
-
|
|
5
|
-
test('distribution coerces samples with Number() and reports nearest-rank p50/p95', () => {
|
|
6
|
-
assert.deepEqual(distribution(['10', 20, '30', 40]), { p50: 20, p95: 40 });
|
|
7
|
-
assert.deepEqual(distribution([]), { p50: null, p95: null });
|
|
8
|
-
assert.deepEqual(distribution([undefined, 'x']), { p50: null, p95: null });
|
|
9
|
-
});
|
|
10
|
-
|
|
11
|
-
test('percentile picks the nearest rank of an ascending sample', () => {
|
|
12
|
-
const sorted = [10, 20, 30, 40];
|
|
13
|
-
assert.equal(percentile(sorted, 50), 20);
|
|
14
|
-
assert.equal(percentile(sorted, 90), 40);
|
|
15
|
-
assert.equal(percentile(sorted, 99), 40);
|
|
16
|
-
assert.equal(percentile([5], 50), 5);
|
|
17
|
-
assert.equal(percentile([], 50), null);
|
|
18
|
-
// Rank 0 and below clamp to the first sample, never to undefined.
|
|
19
|
-
assert.equal(percentile(sorted, 0), 10);
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test('median is the nearest-rank p50: the lower middle sample, null when empty', () => {
|
|
23
|
-
assert.equal(median([10, 20, 30, 40]), 20);
|
|
24
|
-
assert.equal(median([10, 20, 30]), 20);
|
|
25
|
-
assert.equal(median([7]), 7);
|
|
26
|
-
assert.equal(median([]), null);
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
test('percentile is nearest-rank, not floor(n*p) index truncation', () => {
|
|
30
|
-
// floor(n*p) indexing reports 20 for p50 of [10,20] and 20 for p95 of 1..20.
|
|
31
|
-
assert.equal(percentile([10, 20], 50), 10);
|
|
32
|
-
assert.equal(
|
|
33
|
-
percentile(
|
|
34
|
-
Array.from({ length: 20 }, (_, i) => i + 1),
|
|
35
|
-
95
|
|
36
|
-
),
|
|
37
|
-
19
|
|
38
|
-
);
|
|
39
|
-
});
|
|
40
|
-
|
|
41
|
-
test('sortedFinite sorts a copy and drops non-finite entries without coercing them', () => {
|
|
42
|
-
const input = [3, null, '2', Number.NaN, 1, undefined, Number.NEGATIVE_INFINITY];
|
|
43
|
-
assert.deepEqual(sortedFinite(input), [1, 3]);
|
|
44
|
-
assert.equal(input[0], 3);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
test('stats summarizes finite samples and reports null for an empty set', () => {
|
|
48
|
-
assert.deepEqual(stats([30, 10, 20]), { n: 3, sum: 60, avg: 20, p50: 20, p90: 30, p99: 30, max: 30 });
|
|
49
|
-
assert.equal(stats([]), null);
|
|
50
|
-
assert.equal(stats([Number.NaN, Number.POSITIVE_INFINITY]), null);
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
test('stats drops non-finite samples and leaves the caller array untouched', () => {
|
|
54
|
-
const input = [3, Number.NaN, 1, Number.POSITIVE_INFINITY, 2];
|
|
55
|
-
assert.deepEqual(stats(input), { n: 3, sum: 6, avg: 2, p50: 2, p90: 3, p99: 3, max: 3 });
|
|
56
|
-
assert.deepEqual(input, [3, Number.NaN, 1, Number.POSITIVE_INFINITY, 2]);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
test('stats rounds the average, matching the reported millisecond columns', () => {
|
|
60
|
-
assert.equal(stats([1, 2]).avg, 2);
|
|
61
|
-
assert.equal(stats([1, 1, 2]).avg, 1);
|
|
62
|
-
});
|