@noetic-tools/core 2.5.0 → 3.0.0

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.
@@ -1,3 +1,4 @@
1
+ import { storageGetMany } from '@noetic-tools/memory';
1
2
  import { createMessage, extractAssistantText, trackUsage } from '@noetic-tools/types';
2
3
  import { z } from 'zod';
3
4
  import { cosineSimilarity } from './cosine-similarity.js';
@@ -13,10 +14,12 @@ async function getLabelVectors(embed, labels, ref) {
13
14
  if (ref.storage) {
14
15
  const storage = ref.storage;
15
16
  const keys = labels.map(hashLabel);
16
- const fetched = await Promise.all(keys.map((k) => storage.get(k)));
17
+ // One batch read where the adapter supports it, a parallel `get` sweep where
18
+ // it does not — either way, not one round trip per label.
19
+ const cached = await storageGetMany(storage, keys);
17
20
  const missingIndices = [];
18
- for (let i = 0; i < fetched.length; i++) {
19
- if (!fetched[i]) {
21
+ for (let i = 0; i < keys.length; i++) {
22
+ if (!cached.has(keys[i])) {
20
23
  missingIndices.push(i);
21
24
  }
22
25
  }
@@ -29,8 +32,8 @@ async function getLabelVectors(embed, labels, ref) {
29
32
  }
30
33
  const results = new Array(labels.length);
31
34
  let freshIndex = 0;
32
- for (let i = 0; i < fetched.length; i++) {
33
- results[i] = fetched[i] ?? freshEmbeddings[freshIndex++];
35
+ for (let i = 0; i < keys.length; i++) {
36
+ results[i] = cached.get(keys[i]) ?? freshEmbeddings[freshIndex++];
34
37
  }
35
38
  return results;
36
39
  }
package/dist/index.d.ts CHANGED
@@ -68,7 +68,7 @@ export type { DurableTaskState, FactExtractor, FactSearcher, HistoryWindowConfig
68
68
  /** @public */
69
69
  /** @public */
70
70
  /** @public */
71
- export { durableTaskState, fileReference, findFunctionCall, historyWindow, observationalMemory, PlanPhase, planMemory, staticContent, steering, stripUnresolvedToolCalls, temporalMemory, toolMemoryLayer, workingMemory, } from '@noetic-tools/memory';
71
+ export { durableTaskState, fileReference, findFunctionCall, historyWindow, observationalMemory, PlanPhase, planMemory, staticContent, steering, storageGetMany, stripUnresolvedToolCalls, temporalMemory, toolMemoryLayer, workingMemory, } from '@noetic-tools/memory';
72
72
  /** @public */
73
73
  export { createMessage, estimateTokens } from '@noetic-tools/types';
74
74
  /** @public */
package/dist/index.js CHANGED
@@ -58,7 +58,7 @@ export { execute } from './interpreter/execute.js';
58
58
  /** @public */
59
59
  /** @public */
60
60
  /** @public */
61
- export { durableTaskState, fileReference, findFunctionCall, historyWindow, observationalMemory, PlanPhase, planMemory, staticContent, steering, stripUnresolvedToolCalls, temporalMemory, toolMemoryLayer, workingMemory, } from '@noetic-tools/memory';
61
+ export { durableTaskState, fileReference, findFunctionCall, historyWindow, observationalMemory, PlanPhase, planMemory, staticContent, steering, storageGetMany, stripUnresolvedToolCalls, temporalMemory, toolMemoryLayer, workingMemory, } from '@noetic-tools/memory';
62
62
  //#endregion
63
63
  //#region Message Utilities
64
64
  /** @public */
@@ -11,6 +11,7 @@
11
11
  * into the single `execution:<id>:snapshot` key would rewrite a growing blob on every
12
12
  * step — O(n²) bytes over a run.
13
13
  */
14
+ import { storageGetMany } from '@noetic-tools/memory';
14
15
  import { z } from 'zod';
15
16
  /** @public One completed step, keyed by its execution path. */
16
17
  export const StepLedgerEntrySchema = z.object({
@@ -38,10 +39,15 @@ export function createStepLedgerStore(opts) {
38
39
  },
39
40
  load: async (executionId) => {
40
41
  const keys = await storage.list(stepLedgerPrefix(executionId));
42
+ /* One batch read, not one round trip per completed step. Recovery is the
43
+ * moment a network-backed adapter can least afford an N+1. */
44
+ const entries = await storageGetMany(storage, keys);
41
45
  const byPath = new Map();
46
+ // Walk `keys`, not the map: `seqKey`'s zero-padding makes `list()` order
47
+ // dispatch order, and a later entry at a path must win over an earlier one.
42
48
  for (const key of keys) {
43
- const raw = await storage.get(key);
44
- if (raw === null || raw === undefined) {
49
+ const raw = entries.get(key);
50
+ if (raw === undefined) {
45
51
  continue;
46
52
  }
47
53
  const parsed = StepLedgerEntrySchema.safeParse(raw);
@@ -28,6 +28,17 @@ export function createInMemoryStorage() {
28
28
  ...store.keys(),
29
29
  ].filter((k) => k.startsWith(prefix));
30
30
  },
31
+ async getMany(keys) {
32
+ const found = new Map();
33
+ for (const key of keys) {
34
+ const val = store.get(key);
35
+ if (val === undefined) {
36
+ continue;
37
+ }
38
+ found.set(key, frameworkCast(val));
39
+ }
40
+ return found;
41
+ },
31
42
  };
32
43
  }
33
44
  //#endregion
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@noetic-tools/core",
3
- "version": "2.5.0",
3
+ "version": "3.0.0",
4
4
  "type": "module",
5
5
  "description": "Step primitives, interpreter, runtime, and memory layer contract for Noetic agents.",
6
6
  "license": "Apache-2.0",
@@ -66,8 +66,8 @@
66
66
  }
67
67
  },
68
68
  "dependencies": {
69
- "@noetic-tools/memory": "^1.1.0",
70
- "@noetic-tools/types": "^1.4.0",
69
+ "@noetic-tools/memory": "^2.0.0",
70
+ "@noetic-tools/types": "^2.0.0",
71
71
  "@openrouter/agent": "^0.6.0",
72
72
  "zod": "^4.0.0"
73
73
  },