@animalabs/agent-framework 0.22.0 → 0.22.1
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 +11 -4
- package/dist/src/agent.d.ts.map +1 -1
- package/dist/src/agent.js +3 -1
- package/dist/src/agent.js.map +1 -1
- package/dist/src/api/server.d.ts.map +1 -1
- package/dist/src/api/server.js +41 -4
- package/dist/src/api/server.js.map +1 -1
- package/dist/src/framework.d.ts +319 -20
- package/dist/src/framework.d.ts.map +1 -1
- package/dist/src/framework.js +1500 -182
- package/dist/src/framework.js.map +1 -1
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcpl/index.d.ts +2 -0
- package/dist/src/mcpl/index.d.ts.map +1 -1
- package/dist/src/mcpl/index.js.map +1 -1
- package/dist/src/mcpl/reference-fetcher.d.ts +2 -1
- package/dist/src/mcpl/reference-fetcher.d.ts.map +1 -1
- package/dist/src/mcpl/reference-fetcher.js +20 -9
- package/dist/src/mcpl/reference-fetcher.js.map +1 -1
- package/dist/src/mcpl/references.d.ts +29 -6
- package/dist/src/mcpl/references.d.ts.map +1 -1
- package/dist/src/mcpl/references.js +57 -16
- package/dist/src/mcpl/references.js.map +1 -1
- package/dist/src/mcpl/server-connection.d.ts +28 -1
- package/dist/src/mcpl/server-connection.d.ts.map +1 -1
- package/dist/src/mcpl/server-connection.js +32 -4
- package/dist/src/mcpl/server-connection.js.map +1 -1
- package/dist/src/module-registry.d.ts +9 -3
- package/dist/src/module-registry.d.ts.map +1 -1
- package/dist/src/module-registry.js +3 -2
- package/dist/src/module-registry.js.map +1 -1
- package/dist/src/modules/workspace/index.d.ts.map +1 -1
- package/dist/src/modules/workspace/index.js +46 -4
- package/dist/src/modules/workspace/index.js.map +1 -1
- package/dist/src/modules/workspace/observe.d.ts +13 -3
- package/dist/src/modules/workspace/observe.d.ts.map +1 -1
- package/dist/src/modules/workspace/observe.js +24 -4
- package/dist/src/modules/workspace/observe.js.map +1 -1
- package/dist/src/modules/workspace/reconcile.d.ts +14 -0
- package/dist/src/modules/workspace/reconcile.d.ts.map +1 -1
- package/dist/src/modules/workspace/reconcile.js +10 -2
- package/dist/src/modules/workspace/reconcile.js.map +1 -1
- package/dist/src/operator-log.d.ts +41 -0
- package/dist/src/operator-log.d.ts.map +1 -1
- package/dist/src/operator-log.js.map +1 -1
- package/dist/src/provider-waits.d.ts +216 -0
- package/dist/src/provider-waits.d.ts.map +1 -0
- package/dist/src/provider-waits.js +482 -0
- package/dist/src/provider-waits.js.map +1 -0
- package/dist/src/refusal-reactions.d.ts +14 -12
- package/dist/src/refusal-reactions.d.ts.map +1 -1
- package/dist/src/refusal-reactions.js +14 -12
- package/dist/src/refusal-reactions.js.map +1 -1
- package/dist/src/tool-result-guard.d.ts +30 -13
- package/dist/src/tool-result-guard.d.ts.map +1 -1
- package/dist/src/tool-result-guard.js +71 -25
- package/dist/src/tool-result-guard.js.map +1 -1
- package/dist/src/types/events.d.ts +12 -0
- package/dist/src/types/events.d.ts.map +1 -1
- package/dist/src/types/module.d.ts +12 -4
- package/dist/src/types/module.d.ts.map +1 -1
- package/dist/src/types/trace.d.ts +14 -3
- package/dist/src/types/trace.d.ts.map +1 -1
- package/dist/test/discord-awareness-outbox.test.js +3 -0
- package/dist/test/discord-awareness-outbox.test.js.map +1 -1
- package/dist/test/explicit-prose-routing.test.js +0 -2
- package/dist/test/explicit-prose-routing.test.js.map +1 -1
- package/dist/test/framework.test.js +160 -1
- package/dist/test/framework.test.js.map +1 -1
- package/dist/test/helpers/coalescing-fixture.d.ts.map +1 -1
- package/dist/test/helpers/coalescing-fixture.js +3 -2
- package/dist/test/helpers/coalescing-fixture.js.map +1 -1
- package/dist/test/inference-exhaustion-rewind.test.js +142 -14
- package/dist/test/inference-exhaustion-rewind.test.js.map +1 -1
- package/dist/test/inference-failure-bounds.test.d.ts +2 -0
- package/dist/test/inference-failure-bounds.test.d.ts.map +1 -0
- package/dist/test/inference-failure-bounds.test.js +1201 -0
- package/dist/test/inference-failure-bounds.test.js.map +1 -0
- package/dist/test/late-events-after-stop.test.d.ts +2 -0
- package/dist/test/late-events-after-stop.test.d.ts.map +1 -0
- package/dist/test/late-events-after-stop.test.js +122 -0
- package/dist/test/late-events-after-stop.test.js.map +1 -0
- package/dist/test/mcpl-awareness-barrier.test.js +141 -0
- package/dist/test/mcpl-awareness-barrier.test.js.map +1 -1
- package/dist/test/mcpl-coalescing.test.js +78 -16
- package/dist/test/mcpl-coalescing.test.js.map +1 -1
- package/dist/test/mcpl-config-diagnostics.test.js +6 -3
- package/dist/test/mcpl-config-diagnostics.test.js.map +1 -1
- package/dist/test/mcpl-manifest-changed.test.js +2 -1
- package/dist/test/mcpl-manifest-changed.test.js.map +1 -1
- package/dist/test/mcpl-reference-fetcher.test.js +232 -4
- package/dist/test/mcpl-reference-fetcher.test.js.map +1 -1
- package/dist/test/mcpl-reference-fields.test.js +69 -2
- package/dist/test/mcpl-reference-fields.test.js.map +1 -1
- package/dist/test/mcpl-ws-transport.test.js +103 -0
- package/dist/test/mcpl-ws-transport.test.js.map +1 -1
- package/dist/test/ops-alert.test.js +2 -1
- package/dist/test/ops-alert.test.js.map +1 -1
- package/dist/test/placed-reaction-baseline.test.d.ts +2 -0
- package/dist/test/placed-reaction-baseline.test.d.ts.map +1 -0
- package/dist/test/placed-reaction-baseline.test.js +312 -0
- package/dist/test/placed-reaction-baseline.test.js.map +1 -0
- package/dist/test/provider-acceleration-cooldown.test.js +5 -1
- package/dist/test/provider-acceleration-cooldown.test.js.map +1 -1
- package/dist/test/provider-waits.test.d.ts +2 -0
- package/dist/test/provider-waits.test.d.ts.map +1 -0
- package/dist/test/provider-waits.test.js +2196 -0
- package/dist/test/provider-waits.test.js.map +1 -0
- package/dist/test/reaction-baseline-platform.test.d.ts +2 -0
- package/dist/test/reaction-baseline-platform.test.d.ts.map +1 -0
- package/dist/test/reaction-baseline-platform.test.js +124 -0
- package/dist/test/reaction-baseline-platform.test.js.map +1 -0
- package/dist/test/refusal-reaction-baseline.test.js +10 -3
- package/dist/test/refusal-reaction-baseline.test.js.map +1 -1
- package/dist/test/save-recent-image.test.js +138 -2
- package/dist/test/save-recent-image.test.js.map +1 -1
- package/dist/test/surgery-marks-receipt.test.d.ts +2 -0
- package/dist/test/surgery-marks-receipt.test.d.ts.map +1 -0
- package/dist/test/surgery-marks-receipt.test.js +540 -0
- package/dist/test/surgery-marks-receipt.test.js.map +1 -0
- package/dist/test/tool-result-guard.test.js +221 -7
- package/dist/test/tool-result-guard.test.js.map +1 -1
- package/dist/test/workspace-three-way.test.js +115 -0
- package/dist/test/workspace-three-way.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/agent.ts +4 -1
- package/src/api/server.ts +43 -4
- package/src/framework.ts +1538 -189
- package/src/index.ts +7 -2
- package/src/mcpl/index.ts +2 -0
- package/src/mcpl/reference-fetcher.ts +18 -8
- package/src/mcpl/references.ts +57 -13
- package/src/mcpl/server-connection.ts +55 -4
- package/src/module-registry.ts +17 -9
- package/src/modules/workspace/index.ts +44 -4
- package/src/modules/workspace/observe.ts +31 -5
- package/src/modules/workspace/reconcile.ts +23 -2
- package/src/operator-log.ts +30 -0
- package/src/provider-waits.ts +523 -0
- package/src/refusal-reactions.ts +14 -12
- package/src/tool-result-guard.ts +72 -24
- package/src/types/events.ts +12 -0
- package/src/types/module.ts +12 -4
- package/src/types/trace.ts +14 -3
|
@@ -498,6 +498,121 @@ describe('a path sync', () => {
|
|
|
498
498
|
assert.equal(await stateOf(m, 'a.txt'), 'disk-only');
|
|
499
499
|
});
|
|
500
500
|
});
|
|
501
|
+
describe('a sync says what it passed over (agent-framework #276)', () => {
|
|
502
|
+
test('a sync without a path counts what the mount ignores, by mount and reason', async (t) => {
|
|
503
|
+
const env = new Env(t);
|
|
504
|
+
const m = await env.open({ ignore: ['*.md', 'node_modules'] });
|
|
505
|
+
env.writeDisk('LOG.md', 'an append-heavy log\n');
|
|
506
|
+
env.writeDisk('node_modules/a/index.js', 'one');
|
|
507
|
+
env.writeDisk('node_modules/b/index.js', 'two');
|
|
508
|
+
env.writeDisk('kept.txt', 'taken in');
|
|
509
|
+
const data = await call(m, 'sync', {});
|
|
510
|
+
assert.equal(data.totalSynced, 1, 'only kept.txt is looked at');
|
|
511
|
+
assert.deepEqual(data.passedOver, [{ mount: 'work', reason: 'ignored by the mount', count: 2 }], 'LOG.md and node_modules, the directory counted once');
|
|
512
|
+
assert.equal(data.ignored, undefined, 'nothing was named, so nothing is listed as ignored');
|
|
513
|
+
const quiet = await call(m, 'sync', {});
|
|
514
|
+
assert.equal(quiet.totalSynced, 0);
|
|
515
|
+
assert.deepEqual(quiet.passedOver, [{ mount: 'work', reason: 'ignored by the mount', count: 2 }], 'a 0 still says what it did not look at');
|
|
516
|
+
});
|
|
517
|
+
test('a symlink the mount follows was looked at, so it is not counted as passed over', async (t) => {
|
|
518
|
+
const env = new Env(t);
|
|
519
|
+
const m = await env.open({ followSymlinks: true });
|
|
520
|
+
env.writeDisk('real.txt', 'the target');
|
|
521
|
+
symlinkSync(env.disk('real.txt'), env.disk('link.txt'));
|
|
522
|
+
const data = await call(m, 'sync', {});
|
|
523
|
+
assert.equal(data.totalSynced, 2, 'the link is followed and taken in, beside its target');
|
|
524
|
+
assert.equal(data.passedOver, undefined);
|
|
525
|
+
});
|
|
526
|
+
test("a named directory the ignore list covers is synced, its contents included", async (t) => {
|
|
527
|
+
const env = new Env(t);
|
|
528
|
+
const m = await env.open({ ignore: ['build/**'] });
|
|
529
|
+
env.writeDisk('build/out.txt', 'built');
|
|
530
|
+
env.writeDisk('build/sub/deep.txt', 'deeper');
|
|
531
|
+
const bare = await call(m, 'sync', {});
|
|
532
|
+
assert.equal(bare.totalSynced, 0);
|
|
533
|
+
assert.deepEqual(bare.passedOver, [{ mount: 'work', reason: 'ignored by the mount', count: 1 }]);
|
|
534
|
+
const named = await call(m, 'sync', { path: 'work/build' });
|
|
535
|
+
assert.equal(named.totalSynced, 2, 'both files beneath the named directory');
|
|
536
|
+
assert.equal(await contentOf(m, 'build/sub/deep.txt'), 'deeper');
|
|
537
|
+
assert.deepEqual(named.ignored, [{ mount: 'work', path: 'build',
|
|
538
|
+
note: "this mount's ignore list covers it, so a sync without a path won't maintain it" }]);
|
|
539
|
+
assert.equal(named.passedOver, undefined, 'nothing beneath the named directory was passed over');
|
|
540
|
+
});
|
|
541
|
+
test('naming an ignored directory sets aside only the patterns that cover it: one that covers something inside it still applies', async (t) => {
|
|
542
|
+
const env = new Env(t);
|
|
543
|
+
const m = await env.open({ ignore: ['build/**', '*.md'] });
|
|
544
|
+
env.writeDisk('build/out.txt', 'built');
|
|
545
|
+
env.writeDisk('build/LOG.md', 'log');
|
|
546
|
+
const named = await call(m, 'sync', { path: 'work/build' });
|
|
547
|
+
assert.equal(named.totalSynced, 1, 'out.txt only');
|
|
548
|
+
assert.equal(await contentOf(m, 'build/out.txt'), 'built');
|
|
549
|
+
assert.equal(env.store.treeGet('workspace/work/tree', 'build/LOG.md'), null, 'LOG.md stays untracked');
|
|
550
|
+
assert.deepEqual(named.ignored.map(({ path }) => path), ['build']);
|
|
551
|
+
assert.deepEqual(named.passedOver, [{ mount: 'work', reason: 'ignored by the mount', count: 1 }], 'LOG.md was passed over');
|
|
552
|
+
});
|
|
553
|
+
test('a listing of a directory the ignore list covers keeps the ignore, and tracks nothing beneath it', async (t) => {
|
|
554
|
+
const env = new Env(t);
|
|
555
|
+
const m = await env.open({ ignore: ['build/**'] });
|
|
556
|
+
env.writeDisk('build/sub/a.txt', 'ignored');
|
|
557
|
+
const listed = await call(m, 'ls', { path: 'work/build/sub', recursive: true });
|
|
558
|
+
assert.ok(!listed.entries.some((e) => e.path === 'build/sub/a.txt' && e.state === 'synced'), `the file isn't listed as tracked: ${JSON.stringify(listed.entries)}`);
|
|
559
|
+
assert.equal(env.store.treeGet(TREE, 'build/sub/a.txt'), null, 'nothing beneath the ignored directory is tracked');
|
|
560
|
+
const globbed = await call(m, 'glob', { pattern: 'work/build/**' });
|
|
561
|
+
assert.equal(env.store.treeGet(TREE, 'build/sub/a.txt'), null, `nor after a glob: ${JSON.stringify(globbed)}`);
|
|
562
|
+
});
|
|
563
|
+
test('a symlink is reported by path, not counted as passed over: not followed, or a link to a directory', async (t) => {
|
|
564
|
+
const env = new Env(t);
|
|
565
|
+
const plain = await env.open();
|
|
566
|
+
env.writeDisk('real.txt', 'the target');
|
|
567
|
+
symlinkSync(env.disk('real.txt'), env.disk('link.txt'));
|
|
568
|
+
const notFollowed = await call(plain, 'sync', {});
|
|
569
|
+
assert.equal(notFollowed.passedOver, undefined);
|
|
570
|
+
assert.ok(notFollowed.skipped.some((s) => s.path === 'link.txt'), `the link is listed under skipped, got ${JSON.stringify(notFollowed.skipped)}`);
|
|
571
|
+
const env2 = new Env(t);
|
|
572
|
+
const following = await env2.open({ followSymlinks: true });
|
|
573
|
+
env2.writeDisk('dir/inside.txt', 'in a directory');
|
|
574
|
+
symlinkSync(env2.disk('dir'), env2.disk('dirlink'));
|
|
575
|
+
const followed = await call(following, 'sync', {});
|
|
576
|
+
assert.equal(followed.passedOver, undefined);
|
|
577
|
+
const skip = followed.skipped.find((s) => s.path === 'dirlink');
|
|
578
|
+
assert.match(String(skip?.reason), /a symlink to a directory, not walked/);
|
|
579
|
+
});
|
|
580
|
+
test('an ignored region hides only what lies beneath it, not a sibling sharing its name prefix', async (t) => {
|
|
581
|
+
const env = new Env(t);
|
|
582
|
+
const m = await env.open({ ignore: ['build', 'build2'] });
|
|
583
|
+
env.writeDisk('build2/kept.txt', 'tracked, beneath the ignored build2');
|
|
584
|
+
env.writeDisk('build/out.txt', 'ignored, and never tracked');
|
|
585
|
+
await call(m, 'sync', { path: 'work/build2/kept.txt' }); // named, so tracked
|
|
586
|
+
const bare = await call(m, 'sync', {});
|
|
587
|
+
assert.deepEqual(bare.incomplete.map((r) => r.path), ['build2'], 'build2 hides a tracked path');
|
|
588
|
+
assert.deepEqual(bare.passedOver, [{ mount: 'work', reason: 'ignored by the mount', count: 1 }], 'build hides nothing tracked: build2/kept.txt is not beneath it, though it shares the name prefix');
|
|
589
|
+
});
|
|
590
|
+
test('a path the mount ignores is taken when named, and the result says a bare sync will not maintain it', async (t) => {
|
|
591
|
+
const env = new Env(t);
|
|
592
|
+
const m = await env.open({ ignore: ['*.md', 'vendor'] });
|
|
593
|
+
env.writeDisk('LOG.md', 'an append-heavy log\n');
|
|
594
|
+
env.writeDisk('vendor/lib/notes.txt', 'beneath an ignored directory');
|
|
595
|
+
const named = await call(m, 'sync', { path: 'work/LOG.md' });
|
|
596
|
+
assert.equal(named.totalSynced, 1);
|
|
597
|
+
assert.deepEqual(named.ignored, [{ mount: 'work', path: 'LOG.md',
|
|
598
|
+
note: "this mount's ignore list covers it, so a sync without a path won't maintain it" }]);
|
|
599
|
+
assert.equal(await contentOf(m, 'LOG.md'), 'an append-heavy log\n');
|
|
600
|
+
const nested = await call(m, 'sync', { path: 'work/vendor/lib/notes.txt' });
|
|
601
|
+
assert.equal(nested.totalSynced, 1);
|
|
602
|
+
assert.deepEqual(nested.ignored?.map((i) => i.path), ['vendor/lib/notes.txt'], 'covered through the directory above it, which the list names');
|
|
603
|
+
env.writeDisk('plain.txt', 'not ignored');
|
|
604
|
+
const control = await call(m, 'sync', { path: 'work/plain.txt' });
|
|
605
|
+
assert.equal(control.totalSynced, 1);
|
|
606
|
+
assert.equal(control.ignored, undefined, 'a path the ignore list does not cover gets no note');
|
|
607
|
+
// Now tracked, both ignored regions hide something the workspace holds:
|
|
608
|
+
// a bare sync reports them under `incomplete`, and never counts them too.
|
|
609
|
+
const bare = await call(m, 'sync', {});
|
|
610
|
+
const regions = bare.incomplete
|
|
611
|
+
.filter((r) => r.reason === 'ignored by the mount').map((r) => r.path).sort();
|
|
612
|
+
assert.deepEqual(regions, ['LOG.md', 'vendor']);
|
|
613
|
+
assert.equal(bare.passedOver, undefined, 'a region reported as incomplete is not also passed over');
|
|
614
|
+
});
|
|
615
|
+
});
|
|
501
616
|
describe('disk counterparts that are not stored', () => {
|
|
502
617
|
test('a binary counterpart keeps the draft and a disk reference that reports a later change', async (t) => {
|
|
503
618
|
const env = new Env(t);
|