@framers/agentos 0.11.5 → 0.11.7

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 (25) hide show
  1. package/dist/cognition/emergent/EmergentCapabilityEngine.d.ts +23 -0
  2. package/dist/cognition/emergent/EmergentCapabilityEngine.d.ts.map +1 -1
  3. package/dist/cognition/emergent/EmergentCapabilityEngine.js +218 -64
  4. package/dist/cognition/emergent/EmergentCapabilityEngine.js.map +1 -1
  5. package/dist/cognition/emergent/EmergentToolRegistry.d.ts +41 -5
  6. package/dist/cognition/emergent/EmergentToolRegistry.d.ts.map +1 -1
  7. package/dist/cognition/emergent/EmergentToolRegistry.js +94 -19
  8. package/dist/cognition/emergent/EmergentToolRegistry.js.map +1 -1
  9. package/dist/cognition/emergent/types.d.ts +14 -2
  10. package/dist/cognition/emergent/types.d.ts.map +1 -1
  11. package/dist/cognition/emergent/types.js +10 -0
  12. package/dist/cognition/emergent/types.js.map +1 -1
  13. package/dist/core/llm/providers/implementations/OpenRouterProvider.d.ts.map +1 -1
  14. package/dist/core/llm/providers/implementations/OpenRouterProvider.js +4 -2
  15. package/dist/core/llm/providers/implementations/OpenRouterProvider.js.map +1 -1
  16. package/dist/io/media/images/imageToBuffer.d.ts.map +1 -1
  17. package/dist/io/media/images/imageToBuffer.js +3 -2
  18. package/dist/io/media/images/imageToBuffer.js.map +1 -1
  19. package/dist/io/speech/SpeechProviderResolver.d.ts.map +1 -1
  20. package/dist/io/speech/SpeechProviderResolver.js +13 -12
  21. package/dist/io/speech/SpeechProviderResolver.js.map +1 -1
  22. package/dist/io/speech/SpeechRuntime.d.ts.map +1 -1
  23. package/dist/io/speech/SpeechRuntime.js +16 -8
  24. package/dist/io/speech/SpeechRuntime.js.map +1 -1
  25. package/package.json +1 -1
@@ -286,6 +286,12 @@ export declare class EmergentCapabilityEngine {
286
286
  * @returns the outcome, or `undefined` when the tool is unknown.
287
287
  */
288
288
  reactivateTool(toolId: string): Promise<LoadedToolOutcome | undefined>;
289
+ /**
290
+ * Run a read of stored rows and the admissions that use it. `readAt` is the
291
+ * point the read started at; an admission adopts only what has not changed
292
+ * since (see `EmergentToolRegistry.adopt`).
293
+ */
294
+ private withRead;
289
295
  private admitRow;
290
296
  /**
291
297
  * The single-row path. Every stored tool goes through it, whether the
@@ -299,6 +305,23 @@ export declare class EmergentCapabilityEngine {
299
305
  */
300
306
  private readmit;
301
307
  private admit;
308
+ /**
309
+ * After the host registered a tool's executable, the registry must still
310
+ * hold that very object. When it does not (the tool was removed, or
311
+ * replaced under its id, while the registration ran), the executor is
312
+ * brought back in line with the registry: the current tool's executable is
313
+ * registered (the old name's taken out first when the name changed), or
314
+ * the stale executable is taken out when the registry holds none. The
315
+ * registry is read again after every registration, so a change during the
316
+ * settlement is settled too, up to three rounds. A registration that fails,
317
+ * or a tool still changing after three rounds, leaves no executable under
318
+ * the name and throws: a tool that cannot be called is reported, never a
319
+ * stale executable left running. Returns the outcome to report, or
320
+ * undefined when the first registration stands.
321
+ */
322
+ private settleRegistration;
323
+ /** Take a tool's executable out of the host, best-effort. */
324
+ private dropExecutable;
302
325
  /**
303
326
  * The library's reason for not running an implementation under the
304
327
  * configuration in force, or `null`. Later steps add their checks here, so
@@ -1 +1 @@
1
- {"version":3,"file":"EmergentCapabilityEngine.d.ts","sourceRoot":"","sources":["../../../src/cognition/emergent/EmergentCapabilityEngine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"EmergentCapabilityEngine.d.ts","sourceRoot":"","sources":["../../../src/cognition/emergent/EmergentCapabilityEngine.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@
13
13
  * After registration the engine tracks usage and auto-promotes tools that
14
14
  * meet the configured `EmergentConfig.promotionThreshold` criteria.
15
15
  */
16
+ import { GMI_INSTANCE_ID_PREFIX } from './types.js';
16
17
  import { parsePersistedSource, parseRowSchemas, parseStoredRequest, requestFromImplementation, sessionFromSource, requestFromSource, sourceFromImplementation, stateSetterFromColumn, toolFromRow, } from './persisted-source.js';
17
18
  import { normalizeAllowlist, toSandboxApis } from './capabilities.js';
18
19
  // ============================================================================
@@ -234,6 +235,7 @@ export class EmergentCapabilityEngine {
234
235
  source: `forged by agent ${context.agentId} during session ${context.sessionId}`,
235
236
  };
236
237
  this.registry.register(tool, 'session');
238
+ const registered = this.registry.generation(toolId);
237
239
  let written;
238
240
  try {
239
241
  written = await this.registry.setState(toolId, 'active', null, {
@@ -246,7 +248,7 @@ export class EmergentCapabilityEngine {
246
248
  // is re-derived from its source at the next load.
247
249
  console.warn(`[agentos:emergent] could not store the request of "${request.name}" (${toolId}):`, error instanceof Error ? error.message : error);
248
250
  }
249
- if (this.registry.wasRemoved(toolId)) {
251
+ if (this.registry.generation(toolId) !== registered) {
250
252
  // Removed while it was being forged: nothing is registered.
251
253
  return { success: false, error: 'the tool was removed while it was being forged' };
252
254
  }
@@ -273,8 +275,12 @@ export class EmergentCapabilityEngine {
273
275
  }
274
276
  this.indexTool(toolId, context.agentId, context.sessionId);
275
277
  if (this.onToolForged) {
278
+ // The object the registry holds (a registration stores a stamped copy;
279
+ // an adoption above stores the object itself), so the settlement
280
+ // below compares like with like.
281
+ const live = this.registry.get(toolId) ?? tool;
276
282
  try {
277
- await this.onToolForged(tool, this.createExecutableTool(tool));
283
+ await this.onToolForged(live, this.createExecutableTool(live));
278
284
  }
279
285
  catch (error) {
280
286
  this.registry.remove(toolId);
@@ -284,6 +290,20 @@ export class EmergentCapabilityEngine {
284
290
  error: error instanceof Error ? error.message : 'Failed to activate forged tool.',
285
291
  };
286
292
  }
293
+ let settled;
294
+ try {
295
+ settled = await this.settleRegistration(live);
296
+ }
297
+ catch (error) {
298
+ return {
299
+ success: false,
300
+ error: error instanceof Error ? error.message : 'the forged tool could not be registered',
301
+ };
302
+ }
303
+ if (settled && settled.reason === 'removed') {
304
+ // Removed while the host was registering it: nothing is registered.
305
+ return { success: false, error: 'the tool was removed while it was being forged' };
306
+ }
287
307
  }
288
308
  return {
289
309
  success: true,
@@ -328,6 +348,11 @@ export class EmergentCapabilityEngine {
328
348
  if (tool.tier !== 'session') {
329
349
  return null;
330
350
  }
351
+ // An owner with the reserved instance-id prefix is never promoted: an
352
+ // agent-tier row with that owner reads as one an earlier release wrote.
353
+ if (tool.createdBy.startsWith(GMI_INSTANCE_ID_PREFIX)) {
354
+ return null;
355
+ }
331
356
  // Check thresholds.
332
357
  const { uses, confidence } = this.config.promotionThreshold;
333
358
  if (tool.usageStats.totalUses < uses || tool.usageStats.confidenceScore < confidence) {
@@ -403,6 +428,17 @@ export class EmergentCapabilityEngine {
403
428
  const removedTools = this.getSessionTools(sessionId);
404
429
  this.registry.cleanupSession(sessionId);
405
430
  this.index.bySession.delete(sessionId);
431
+ for (const tool of removedTools) {
432
+ // The agent index too, so a lookup by agent never names a tool that is gone.
433
+ this.removeIndexedToolEverywhere(tool.id);
434
+ }
435
+ if (this.onToolRemoved) {
436
+ // The executables go with the tools, as removeTool does. A host that
437
+ // cleans up through the orchestrator unregisters the same names; a
438
+ // second unregistration of a name finds nothing to do.
439
+ const unregister = this.onToolRemoved;
440
+ void Promise.allSettled(removedTools.map((tool) => unregister(tool)));
441
+ }
406
442
  return removedTools;
407
443
  }
408
444
  /**
@@ -419,28 +455,34 @@ export class EmergentCapabilityEngine {
419
455
  * @returns what happened, so a host can tell a registered tool from a refused one.
420
456
  */
421
457
  async syncPersistedTool(tool) {
422
- let row = await this.registry.loadRow(tool.id);
423
- if (!row && this.registry.hasStorage()) {
458
+ const existing = await this.registry.loadRow(tool.id);
459
+ if (!existing && this.registry.hasStorage()) {
424
460
  // No stored row yet: the host hydrates from its own store. The row is
425
461
  // written as it was before loading went through the stored row, so the
426
462
  // tool's uses are recorded and the next load finds it.
427
463
  await this.registry.writeToolRow(tool);
428
- row = await this.registry.loadRow(tool.id);
429
464
  }
430
- if (row) {
431
- // With source persistence off the row holds a redacted record; the
432
- // implementation the host supplied is what runs then.
433
- return this.admitRow(row, { sourceFallback: sourceFromImplementation(tool.implementation) });
434
- }
435
- const stored = await this.registry.readState(tool.id);
436
- return this.admit({
437
- toolId: tool.id,
438
- name: tool.name,
439
- source: sourceFromImplementation(tool.implementation),
440
- stored,
441
- requestStored: stored?.request != null,
442
- legacyActive: tool.isActive ?? true,
443
- buildTool: () => tool,
465
+ // The row is read for the admission after any write above, so the write
466
+ // is not a change the admission's read missed.
467
+ return this.withRead(async (readAt) => {
468
+ const row = await this.registry.loadRow(tool.id);
469
+ if (row) {
470
+ // With source persistence off the row holds a redacted record; the
471
+ // implementation the host supplied is what runs then.
472
+ return this.admitRow(row, { readAt, sourceFallback: sourceFromImplementation(tool.implementation) });
473
+ }
474
+ const stored = await this.registry.readState(tool.id);
475
+ return this.admit({
476
+ toolId: tool.id,
477
+ name: tool.name,
478
+ source: sourceFromImplementation(tool.implementation),
479
+ stored,
480
+ requestStored: stored?.request != null,
481
+ legacyActive: tool.isActive ?? true,
482
+ tier: tool.tier,
483
+ createdBy: tool.createdBy,
484
+ buildTool: () => tool,
485
+ }, { readAt });
444
486
  });
445
487
  }
446
488
  /**
@@ -493,19 +535,24 @@ export class EmergentCapabilityEngine {
493
535
  throw new Error("selector_required: loadPersistedTools({ tiers: ['session'] }) needs the sessionId whose tools to load; " +
494
536
  "a session's tools are private to it.");
495
537
  }
496
- const rows = await this.registry.loadRows(tiers, { agentId, sessionId });
497
538
  const outcomes = [];
498
539
  const failed = [];
499
- for (const row of rows) {
500
- try {
501
- outcomes.push(await this.admitRow(row));
502
- }
503
- catch (error) {
504
- const message = error instanceof Error ? error.message : String(error);
505
- failed.push({ toolId: row.id, name: row.name, error: message });
506
- console.warn(`[agentos:emergent] stored tool "${row.name}" (${row.id}) did not load: ${message}`);
540
+ // One read for the rows and their admissions: a tool that changes in this
541
+ // process after the rows were read (a removal, a registration) is read
542
+ // again before it is adopted.
543
+ await this.withRead(async (readAt) => {
544
+ const rows = await this.registry.loadRows(tiers, { agentId, sessionId });
545
+ for (const row of rows) {
546
+ try {
547
+ outcomes.push(await this.admitRow(row, { readAt }));
548
+ }
549
+ catch (error) {
550
+ const message = error instanceof Error ? error.message : String(error);
551
+ failed.push({ toolId: row.id, name: row.name, error: message });
552
+ console.warn(`[agentos:emergent] stored tool "${row.name}" (${row.id}) did not load: ${message}`);
553
+ }
507
554
  }
508
- }
555
+ });
509
556
  for (const outcome of outcomes) {
510
557
  if (outcome.state === 'active')
511
558
  continue;
@@ -579,24 +626,42 @@ export class EmergentCapabilityEngine {
579
626
  * @returns the outcome, or `undefined` when the tool is unknown.
580
627
  */
581
628
  async reactivateTool(toolId) {
582
- const row = await this.registry.loadRow(toolId);
583
- if (row) {
584
- return this.admitRow(row, { force: true });
629
+ return this.withRead(async (readAt) => {
630
+ const row = await this.registry.loadRow(toolId);
631
+ if (row) {
632
+ return this.admitRow(row, { force: true, readAt });
633
+ }
634
+ const tool = this.registry.get(toolId);
635
+ if (!tool) {
636
+ return undefined;
637
+ }
638
+ const held = this.registry.getState(toolId);
639
+ return this.admit({
640
+ toolId,
641
+ name: tool.name,
642
+ source: sourceFromImplementation(tool.implementation),
643
+ stored: held,
644
+ requestStored: held?.request != null,
645
+ legacyActive: true,
646
+ tier: tool.tier,
647
+ createdBy: tool.createdBy,
648
+ buildTool: () => tool,
649
+ }, { force: true, readAt });
650
+ });
651
+ }
652
+ /**
653
+ * Run a read of stored rows and the admissions that use it. `readAt` is the
654
+ * point the read started at; an admission adopts only what has not changed
655
+ * since (see `EmergentToolRegistry.adopt`).
656
+ */
657
+ async withRead(read) {
658
+ const readAt = this.registry.beginRead();
659
+ try {
660
+ return await read(readAt);
585
661
  }
586
- const tool = this.registry.get(toolId);
587
- if (!tool) {
588
- return undefined;
662
+ finally {
663
+ this.registry.endRead();
589
664
  }
590
- const held = this.registry.getState(toolId);
591
- return this.admit({
592
- toolId,
593
- name: tool.name,
594
- source: sourceFromImplementation(tool.implementation),
595
- stored: held,
596
- requestStored: held?.request != null,
597
- legacyActive: true,
598
- buildTool: () => tool,
599
- }, { force: true });
600
665
  }
601
666
  admitRow(row, options = {}) {
602
667
  const stored = row.state
@@ -632,6 +697,8 @@ export class EmergentCapabilityEngine {
632
697
  requestStored: row.request_json != null,
633
698
  legacyActive: !(row.is_active === 0 || row.is_active === false),
634
699
  flagSynced: row.flag_synced == null ? undefined : !(row.flag_synced === 0 || row.flag_synced === false),
700
+ tier: row.tier,
701
+ createdBy: row.created_by_agent,
635
702
  buildTool: (implementation) => toolFromRow(row, implementation),
636
703
  }, options);
637
704
  }
@@ -649,12 +716,17 @@ export class EmergentCapabilityEngine {
649
716
  const { toolId, name } = candidate;
650
717
  const depth = options.readmitted ?? 0;
651
718
  if (depth < 2) {
652
- const fresh = await this.registry.loadRow(toolId);
653
- if (fresh) {
654
- return this.admitRow(fresh, { ...options, readmitted: depth + 1 });
655
- }
656
- await this.unregisterIfLive(toolId);
657
- return { toolId, name, state: 'demoted', reason: 'removed' };
719
+ // The tool's queued writes and deletes land first, so the row read next
720
+ // is the one they leave.
721
+ await this.registry.settled(toolId);
722
+ return this.withRead(async (readAt) => {
723
+ const fresh = await this.registry.loadRow(toolId);
724
+ if (fresh) {
725
+ return this.admitRow(fresh, { ...options, readmitted: depth + 1, readAt });
726
+ }
727
+ await this.unregisterIfLive(toolId);
728
+ return { toolId, name, state: 'demoted', reason: 'removed' };
729
+ });
658
730
  }
659
731
  // Nothing is written; the tool is held off here until the next load.
660
732
  this.holdStored(toolId, {
@@ -670,6 +742,9 @@ export class EmergentCapabilityEngine {
670
742
  }
671
743
  async admit(candidate, options = {}) {
672
744
  const { toolId, name, source, stored, requestStored } = candidate;
745
+ // The point after which a change makes what this admission holds stale:
746
+ // where its row was read, or, for a caller that did not say, now.
747
+ const readAt = options.readAt ?? this.registry.generation(toolId);
673
748
  let legacyActive = candidate.legacyActive;
674
749
  // A row whose last state write did not finish its flag write: finish it
675
750
  // first, so the flag reads what the state row says before anything is
@@ -756,6 +831,14 @@ export class EmergentCapabilityEngine {
756
831
  allowlist: source.format === 'code-with-list' ? granted.filter((api) => listed.allowlist.includes(api)) : granted,
757
832
  };
758
833
  }
834
+ // 3a. An agent-tier row from an earlier release is owned by the forging
835
+ // GMI instance's id, which no persona can match, so no caller could
836
+ // ever pass the owner check: it loads suspended rather than running
837
+ // for everyone. Forging the tool again under the persona is the way
838
+ // back; `reactivateTool` goes through this same path.
839
+ if (!refusal && candidate.tier === 'agent' && candidate.createdBy.startsWith(GMI_INSTANCE_ID_PREFIX)) {
840
+ refusal = 'legacy_owner';
841
+ }
759
842
  if (implementation && !refusal) {
760
843
  refusal = this.refusalFor(implementation);
761
844
  }
@@ -852,10 +935,22 @@ export class EmergentCapabilityEngine {
852
935
  setBy: 'library',
853
936
  at: Date.now(),
854
937
  request,
855
- });
938
+ }, readAt);
856
939
  if (!adopted) {
857
- // Removed in this process while the row was being admitted.
858
- return { toolId, name, state: 'demoted', reason: 'removed' };
940
+ // The tool changed in this process after its row was read (removed,
941
+ // replaced under its id, written again), or a removal of it is still
942
+ // deleting its rows: what this admission holds may be stale. With
943
+ // storage the row is read again once the tool's queued writes have run;
944
+ // without, the registry's own record is the answer.
945
+ if (this.registry.hasStorage()) {
946
+ return this.readmit(candidate, options);
947
+ }
948
+ const current = this.registry.get(toolId);
949
+ if (!current) {
950
+ return { toolId, name, state: 'demoted', reason: 'removed' };
951
+ }
952
+ const held = this.registry.getState(toolId);
953
+ return { toolId, name: current.name, state: held?.state ?? 'active', reason: held?.reason ?? null };
859
954
  }
860
955
  this.indexTool(tool.id, tool.createdBy, this.extractSessionId(tool.source) ?? `persisted:${tool.id}`);
861
956
  if (this.onToolForged) {
@@ -870,17 +965,75 @@ export class EmergentCapabilityEngine {
870
965
  this.removeIndexedToolEverywhere(toolId);
871
966
  throw error;
872
967
  }
873
- if (this.registry.wasRemoved(toolId)) {
874
- // Removed while the host was registering it: the registration goes.
875
- if (this.onToolRemoved) {
876
- await this.onToolRemoved(tool);
877
- }
878
- this.removeIndexedToolEverywhere(toolId);
879
- return { toolId, name, state: 'demoted', reason: 'removed' };
968
+ const settled = await this.settleRegistration(tool);
969
+ if (settled) {
970
+ return settled;
880
971
  }
881
972
  }
882
973
  return { toolId, name, state: 'active', reason: null };
883
974
  }
975
+ /**
976
+ * After the host registered a tool's executable, the registry must still
977
+ * hold that very object. When it does not (the tool was removed, or
978
+ * replaced under its id, while the registration ran), the executor is
979
+ * brought back in line with the registry: the current tool's executable is
980
+ * registered (the old name's taken out first when the name changed), or
981
+ * the stale executable is taken out when the registry holds none. The
982
+ * registry is read again after every registration, so a change during the
983
+ * settlement is settled too, up to three rounds. A registration that fails,
984
+ * or a tool still changing after three rounds, leaves no executable under
985
+ * the name and throws: a tool that cannot be called is reported, never a
986
+ * stale executable left running. Returns the outcome to report, or
987
+ * undefined when the first registration stands.
988
+ */
989
+ async settleRegistration(tool) {
990
+ let registered = tool;
991
+ for (let round = 0; round < 3; round += 1) {
992
+ const current = this.registry.get(tool.id);
993
+ if (current === registered) {
994
+ if (round === 0) {
995
+ return undefined;
996
+ }
997
+ if (!current) {
998
+ this.removeIndexedToolEverywhere(tool.id);
999
+ return { toolId: tool.id, name: tool.name, state: 'demoted', reason: 'removed' };
1000
+ }
1001
+ const held = this.registry.getState(tool.id);
1002
+ return { toolId: tool.id, name: current.name, state: held?.state ?? 'active', reason: held?.reason ?? null };
1003
+ }
1004
+ try {
1005
+ if (registered && (!current || current.name !== registered.name) && this.onToolRemoved) {
1006
+ await this.onToolRemoved(registered);
1007
+ }
1008
+ if (current && this.onToolForged) {
1009
+ await this.onToolForged(current, this.createExecutableTool(current));
1010
+ }
1011
+ registered = current;
1012
+ }
1013
+ catch (error) {
1014
+ const message = error instanceof Error ? error.message : String(error);
1015
+ await this.dropExecutable(registered ?? current ?? tool);
1016
+ if (!this.registry.get(tool.id)) {
1017
+ this.removeIndexedToolEverywhere(tool.id);
1018
+ }
1019
+ throw new Error(`the executable of "${tool.name}" (${tool.id}) could not be brought in line with the registry: ${message}`);
1020
+ }
1021
+ }
1022
+ await this.dropExecutable(registered ?? tool);
1023
+ throw new Error(`the executable of "${tool.name}" (${tool.id}) could not be settled: the tool kept changing while it was registered`);
1024
+ }
1025
+ /** Take a tool's executable out of the host, best-effort. */
1026
+ async dropExecutable(tool) {
1027
+ if (!this.onToolRemoved) {
1028
+ return;
1029
+ }
1030
+ try {
1031
+ await this.onToolRemoved(tool);
1032
+ }
1033
+ catch (error) {
1034
+ console.warn(`[agentos:emergent] could not take out the executable of "${tool.name}" (${tool.id}):`, error instanceof Error ? error.message : error);
1035
+ }
1036
+ }
884
1037
  /**
885
1038
  * The library's reason for not running an implementation under the
886
1039
  * configuration in force, or `null`. Later steps add their checks here, so
@@ -1064,11 +1217,12 @@ export class EmergentCapabilityEngine {
1064
1217
  // The owner is the persona that forged the tool, compared as it was
1065
1218
  // stored ('unknown' for a caller without one). A row from an earlier
1066
1219
  // release holds the forging GMI instance's id instead, which no
1067
- // persona can match: such a tool runs for any caller of the host that
1068
- // loaded it by that id, as it did before this change.
1220
+ // persona can match; the loader suspends such a row (`legacy_owner`),
1221
+ // and a call to one held in memory is refused here like any other
1222
+ // owner mismatch.
1069
1223
  const owner = current.createdBy;
1070
1224
  const caller = context.personaId ?? 'unknown';
1071
- if (current.tier === 'agent' && !owner.startsWith('gmi-instance-') && caller !== owner) {
1225
+ if (current.tier === 'agent' && caller !== owner) {
1072
1226
  return {
1073
1227
  success: false,
1074
1228
  error: `Emergent tool "${tool.name}" belongs to agent ${owner}; it is not callable as ${caller}.`,