@x12i/memorix-scoper 2.3.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.
Files changed (45) hide show
  1. package/README.md +1 -1
  2. package/dist/create-scoper.d.ts +23 -17
  3. package/dist/create-scoper.d.ts.map +1 -1
  4. package/dist/create-scoper.js +20 -1
  5. package/dist/create-scoper.js.map +1 -1
  6. package/dist/index.d.ts +2 -0
  7. package/dist/index.d.ts.map +1 -1
  8. package/dist/index.js +1 -0
  9. package/dist/index.js.map +1 -1
  10. package/dist/intent-scope.d.ts +3 -5
  11. package/dist/intent-scope.d.ts.map +1 -1
  12. package/dist/intent-scope.js +4 -97
  13. package/dist/intent-scope.js.map +1 -1
  14. package/dist/mcp-server.d.ts.map +1 -1
  15. package/dist/mcp-server.js +7 -4
  16. package/dist/mcp-server.js.map +1 -1
  17. package/dist/reasoner/ai-dispatcher.d.ts +4 -1
  18. package/dist/reasoner/ai-dispatcher.d.ts.map +1 -1
  19. package/dist/reasoner/ai-dispatcher.js +20 -12
  20. package/dist/reasoner/ai-dispatcher.js.map +1 -1
  21. package/dist/selection/adapter.d.ts +18 -0
  22. package/dist/selection/adapter.d.ts.map +1 -0
  23. package/dist/selection/adapter.js +57 -0
  24. package/dist/selection/adapter.js.map +1 -0
  25. package/dist/selection/cache.d.ts +72 -0
  26. package/dist/selection/cache.d.ts.map +1 -0
  27. package/dist/selection/cache.js +59 -0
  28. package/dist/selection/cache.js.map +1 -0
  29. package/dist/selection/ids.d.ts +4 -0
  30. package/dist/selection/ids.d.ts.map +1 -0
  31. package/dist/selection/ids.js +29 -0
  32. package/dist/selection/ids.js.map +1 -0
  33. package/dist/selection/pick.d.ts +11 -0
  34. package/dist/selection/pick.d.ts.map +1 -0
  35. package/dist/selection/pick.js +77 -0
  36. package/dist/selection/pick.js.map +1 -0
  37. package/dist/selection/run.d.ts +12 -0
  38. package/dist/selection/run.d.ts.map +1 -0
  39. package/dist/selection/run.js +433 -0
  40. package/dist/selection/run.js.map +1 -0
  41. package/dist/selection/types.d.ts +27 -0
  42. package/dist/selection/types.d.ts.map +1 -0
  43. package/dist/selection/types.js +2 -0
  44. package/dist/selection/types.js.map +1 -0
  45. package/package.json +7 -5
@@ -0,0 +1,57 @@
1
+ import { createDecisionDispatcher, resolveDefaultDecisionSku, } from "@x12i/decision-dispatcher";
2
+ import { ScoperError } from "@x12i/memorix-scoper-contracts";
3
+ /**
4
+ * Inputs for one step. `model` is the pagx spec, not the SKU, and is left unset.
5
+ * `@x12i/decision-dispatcher@1.0.0` rejects a missing spec. This call stays without
6
+ * one until a dispatcher build fills that default. `sku.model` is not copied here.
7
+ */
8
+ export function decisionRequestFrom(input) {
9
+ return {
10
+ inputs: {
11
+ step: input.step,
12
+ intent: input.intent,
13
+ objectType: input.objectType,
14
+ ...(input.contentType ? { contentType: input.contentType } : {}),
15
+ ...(input.field ? { field: input.field } : {}),
16
+ candidates: input.candidates,
17
+ ...(input.values !== undefined ? { values: input.values } : {}),
18
+ },
19
+ context: `${input.intent.title} (${input.intent.objectType})`,
20
+ };
21
+ }
22
+ /**
23
+ * In-process decision dispatcher. Shares the host's ai-dispatcher.
24
+ * The judgment SKU is `resolveDefaultDecisionSku()` (live registry, else the
25
+ * JSON shipped in decision-models). No profile pin, no role pin, no registry env.
26
+ */
27
+ export async function createScopeDecider(dispatcher) {
28
+ const sku = await resolveDefaultDecisionSku();
29
+ const decisions = createDecisionDispatcher({
30
+ dispatcher,
31
+ cache: false,
32
+ pagx: { autoInstall: false },
33
+ defaults: { provider: sku.provider, model: sku.model },
34
+ });
35
+ return {
36
+ async decide(input) {
37
+ const request = decisionRequestFrom(input);
38
+ try {
39
+ const answer = await decisions.decide(request);
40
+ const decision = answer.decision && typeof answer.decision === "object" && !Array.isArray(answer.decision)
41
+ ? answer.decision
42
+ : {};
43
+ return { decision, value: answer.value };
44
+ }
45
+ catch (err) {
46
+ if (err instanceof ScoperError)
47
+ throw err;
48
+ const code = err && typeof err === "object" && "code" in err ? String(err.code) : "";
49
+ const message = err instanceof Error ? err.message : String(err);
50
+ throw new ScoperError("UPSTREAM_UNAVAILABLE", message, {
51
+ ...(code ? { details: { code } } : {}),
52
+ });
53
+ }
54
+ },
55
+ };
56
+ }
57
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/selection/adapter.ts"],"names":[],"mappings":"AACA,OAAO,EACL,wBAAwB,EACxB,yBAAyB,GAE1B,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAG7D;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CAAC,KAAyB;IAI3D,OAAO;QACL,MAAM,EAAE;YACN,IAAI,EAAE,KAAK,CAAC,IAAI;YAChB,MAAM,EAAE,KAAK,CAAC,MAAM;YACpB,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,GAAG,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAChE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9C,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,GAAG,CAAC,KAAK,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAChE;QACD,OAAO,EAAE,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,KAAK,KAAK,CAAC,MAAM,CAAC,UAAU,GAAG;KAC9D,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,UAAwB;IAC/D,MAAM,GAAG,GAAG,MAAM,yBAAyB,EAAE,CAAC;IAC9C,MAAM,SAAS,GAAG,wBAAwB,CAAC;QACzC,UAAU;QACV,KAAK,EAAE,KAAK;QACZ,IAAI,EAAE,EAAE,WAAW,EAAE,KAAK,EAAE;QAC5B,QAAQ,EAAE,EAAE,QAAQ,EAAE,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE;KACvD,CAAC,CAAC;IACH,OAAO;QACL,KAAK,CAAC,MAAM,CAAC,KAAK;YAChB,MAAM,OAAO,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;YAC3C,IAAI,CAAC;gBACH,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC,OAA0B,CAAC,CAAC;gBAClE,MAAM,QAAQ,GACZ,MAAM,CAAC,QAAQ,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC;oBACvF,CAAC,CAAC,MAAM,CAAC,QAAQ;oBACjB,CAAC,CAAC,EAAE,CAAC;gBACT,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC;YAC3C,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,IAAI,GAAG,YAAY,WAAW;oBAAE,MAAM,GAAG,CAAC;gBAC1C,MAAM,IAAI,GACR,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC,MAAM,CAAE,GAAyB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjG,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBACjE,MAAM,IAAI,WAAW,CAAC,sBAAsB,EAAE,OAAO,EAAE;oBACrD,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;iBACvC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,72 @@
1
+ import type { ScopeSelection } from "@x12i/memorix-scoper-contracts";
2
+ import type { ScopeIntent } from "@x12i/memorix-scoper-contracts";
3
+ export declare const DEFAULT_ADDRESS_TTL_MS: number;
4
+ export declare const DEFAULT_RECORD_TTL_MS: number;
5
+ export declare const DEFAULT_TEXT_TTL_MS: number;
6
+ export interface ShownRevision {
7
+ /** `*` is the record's root revision. Any other value is a content type that was shown. */
8
+ contentType: string;
9
+ revision: string | number | null;
10
+ }
11
+ export interface AddressCacheEntry {
12
+ selection: ScopeSelection;
13
+ fingerprint: string;
14
+ objectTypeIds: string[];
15
+ }
16
+ export interface RecordCacheEntry {
17
+ selection: ScopeSelection;
18
+ revisions: ShownRevision[];
19
+ }
20
+ export interface TextCacheEntry {
21
+ selection: ScopeSelection;
22
+ fingerprint: string;
23
+ objectTypeIds: string[];
24
+ /** Leading content type the first-tier ids were listed from. */
25
+ contentType?: string;
26
+ revisions: Array<{
27
+ recordId: string;
28
+ revision: string | number | null;
29
+ }>;
30
+ }
31
+ export interface SelectionCacheConfig {
32
+ addressTtlMs?: number;
33
+ recordTtlMs?: number;
34
+ textTtlMs?: number;
35
+ now?: () => number;
36
+ }
37
+ export interface SelectionCaches {
38
+ address: TtlMap<AddressCacheEntry>;
39
+ record: TtlMap<RecordCacheEntry>;
40
+ text: TtlMap<TextCacheEntry>;
41
+ }
42
+ export declare class TtlMap<T> {
43
+ private readonly ttlMs;
44
+ private readonly now;
45
+ private readonly entries;
46
+ constructor(ttlMs: number, now: () => number);
47
+ get(key: string): T | undefined;
48
+ set(key: string, value: T): void;
49
+ }
50
+ /** Three maps. A hit does not call the decision dispatcher. `redo` skips the read. */
51
+ export declare function createSelectionCaches(config?: SelectionCacheConfig): SelectionCaches;
52
+ export declare function addressCacheKey(input: {
53
+ orgId: string;
54
+ agentIds: readonly string[];
55
+ intent: ScopeIntent;
56
+ objectType: string;
57
+ }): string;
58
+ export declare function recordCacheKey(input: {
59
+ orgId: string;
60
+ agentIds: readonly string[];
61
+ intent: ScopeIntent;
62
+ objectType: string;
63
+ recordId: string;
64
+ }): string;
65
+ export declare function textCacheKey(input: {
66
+ orgId: string;
67
+ agentIds: readonly string[];
68
+ intent: ScopeIntent;
69
+ objectType: string;
70
+ text: string;
71
+ }): string;
72
+ //# sourceMappingURL=cache.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.d.ts","sourceRoot":"","sources":["../../src/selection/cache.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AACrE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gCAAgC,CAAC;AAGlE,eAAO,MAAM,sBAAsB,QAAsB,CAAC;AAC1D,eAAO,MAAM,qBAAqB,QAAiB,CAAC;AACpD,eAAO,MAAM,mBAAmB,QAAiB,CAAC;AAElD,MAAM,WAAW,aAAa;IAC5B,2FAA2F;IAC3F,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,cAAc,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,cAAc,CAAC;IAC1B,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,cAAc,CAAC;IAC1B,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,gEAAgE;IAChE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,KAAK,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC;CAC1E;AAED,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC,iBAAiB,CAAC,CAAC;IACnC,MAAM,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;CAC9B;AAED,qBAAa,MAAM,CAAC,CAAC;IAIjB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,GAAG;IAJtB,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsD;gBAG3D,KAAK,EAAE,MAAM,EACb,GAAG,EAAE,MAAM,MAAM;IAGpC,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,GAAG,SAAS;IAU/B,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;CAGjC;AAUD,sFAAsF;AACtF,wBAAgB,qBAAqB,CAAC,MAAM,GAAE,oBAAyB,GAAG,eAAe,CAgBxF;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,MAAM,CAOT;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB,GAAG,MAAM,CAET;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IAC5B,MAAM,EAAE,WAAW,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,MAAM,CAET"}
@@ -0,0 +1,59 @@
1
+ import { stableHash } from "@x12i/memorix-scoper-sdk";
2
+ export const DEFAULT_ADDRESS_TTL_MS = 24 * 60 * 60 * 1000;
3
+ export const DEFAULT_RECORD_TTL_MS = 60 * 60 * 1000;
4
+ export const DEFAULT_TEXT_TTL_MS = 10 * 60 * 1000;
5
+ export class TtlMap {
6
+ ttlMs;
7
+ now;
8
+ entries = new Map();
9
+ constructor(ttlMs, now) {
10
+ this.ttlMs = ttlMs;
11
+ this.now = now;
12
+ }
13
+ get(key) {
14
+ const hit = this.entries.get(key);
15
+ if (!hit)
16
+ return undefined;
17
+ if (hit.expiresAt <= this.now()) {
18
+ this.entries.delete(key);
19
+ return undefined;
20
+ }
21
+ return hit.value;
22
+ }
23
+ set(key, value) {
24
+ this.entries.set(key, { value, expiresAt: this.now() + this.ttlMs });
25
+ }
26
+ }
27
+ function ttlFromEnv(name, fallback, override) {
28
+ if (override !== undefined && Number.isFinite(override) && override >= 0)
29
+ return override;
30
+ const raw = process.env[name];
31
+ if (!raw)
32
+ return fallback;
33
+ const parsed = Number(raw);
34
+ return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
35
+ }
36
+ /** Three maps. A hit does not call the decision dispatcher. `redo` skips the read. */
37
+ export function createSelectionCaches(config = {}) {
38
+ const now = config.now ?? (() => Date.now());
39
+ return {
40
+ address: new TtlMap(ttlFromEnv("SCOPER_SCOPE_ADDRESS_TTL_MS", DEFAULT_ADDRESS_TTL_MS, config.addressTtlMs), now),
41
+ record: new TtlMap(ttlFromEnv("SCOPER_SCOPE_RECORD_TTL_MS", DEFAULT_RECORD_TTL_MS, config.recordTtlMs), now),
42
+ text: new TtlMap(ttlFromEnv("SCOPER_SCOPE_TEXT_TTL_MS", DEFAULT_TEXT_TTL_MS, config.textTtlMs), now),
43
+ };
44
+ }
45
+ export function addressCacheKey(input) {
46
+ return [
47
+ input.orgId,
48
+ [...input.agentIds].sort().join(","),
49
+ stableHash(input.intent),
50
+ input.objectType,
51
+ ].join("\n");
52
+ }
53
+ export function recordCacheKey(input) {
54
+ return `${addressCacheKey(input)}\n${input.recordId}`;
55
+ }
56
+ export function textCacheKey(input) {
57
+ return `${addressCacheKey(input)}\n${stableHash(input.text)}`;
58
+ }
59
+ //# sourceMappingURL=cache.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cache.js","sourceRoot":"","sources":["../../src/selection/cache.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ /** Same cap as connected source refs on a subject-data read. */
2
+ export declare const MAX_RELATION_IDS = 16;
3
+ export declare function relationRecordIds(value: unknown): string[];
4
+ //# sourceMappingURL=ids.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ids.d.ts","sourceRoot":"","sources":["../../src/selection/ids.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,eAAO,MAAM,gBAAgB,KAAK,CAAC;AAEnC,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,CAoB1D"}
@@ -0,0 +1,29 @@
1
+ /** Same cap as connected source refs on a subject-data read. */
2
+ export const MAX_RELATION_IDS = 16;
3
+ export function relationRecordIds(value) {
4
+ const ids = [];
5
+ const push = (item) => {
6
+ if (ids.length >= MAX_RELATION_IDS)
7
+ return;
8
+ let raw = item;
9
+ if (item && typeof item === "object" && !Array.isArray(item)) {
10
+ const record = item;
11
+ raw = record.recordId ?? record.id;
12
+ }
13
+ if (typeof raw !== "string")
14
+ return;
15
+ const id = raw.trim();
16
+ if (!id || ids.includes(id))
17
+ return;
18
+ ids.push(id);
19
+ };
20
+ if (Array.isArray(value)) {
21
+ for (const item of value)
22
+ push(item);
23
+ }
24
+ else {
25
+ push(value);
26
+ }
27
+ return ids;
28
+ }
29
+ //# sourceMappingURL=ids.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ids.js","sourceRoot":"","sources":["../../src/selection/ids.ts"],"names":[],"mappings":"AAAA,gEAAgE;AAChE,MAAM,CAAC,MAAM,gBAAgB,GAAG,EAAE,CAAC;AAEnC,MAAM,UAAU,iBAAiB,CAAC,KAAc;IAC9C,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,MAAM,IAAI,GAAG,CAAC,IAAa,EAAE,EAAE;QAC7B,IAAI,GAAG,CAAC,MAAM,IAAI,gBAAgB;YAAE,OAAO;QAC3C,IAAI,GAAG,GAAY,IAAI,CAAC;QACxB,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7D,MAAM,MAAM,GAAG,IAA+B,CAAC;YAC/C,GAAG,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,EAAE,CAAC;QACrC,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO;QACpC,MAAM,EAAE,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,EAAE,IAAI,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YAAE,OAAO;QACpC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,CAAC,CAAC;IACF,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,IAAI,IAAI,KAAK;YAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACvC,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,KAAK,CAAC,CAAC;IACd,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,11 @@
1
+ import type { ScopeDecider } from "./types.js";
2
+ /** Ids a candidate list offers, in candidate order. */
3
+ export declare function candidateIds(candidates: unknown): string[];
4
+ /**
5
+ * Keep ids that were candidates. Anything else is dropped and named in `warnings`.
6
+ * Order follows the decision. `answer.value` is not read.
7
+ */
8
+ export declare function keepPicked(decision: Record<string, unknown> | undefined, allowed: readonly string[], warnings: string[], step: string): string[];
9
+ /** A decider that keeps every candidate. For tests and hosts that want the whole menu. */
10
+ export declare function selectAllDecider(): ScopeDecider;
11
+ //# sourceMappingURL=pick.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pick.d.ts","sourceRoot":"","sources":["../../src/selection/pick.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAsB,MAAM,YAAY,CAAC;AA0BnE,uDAAuD;AACvD,wBAAgB,YAAY,CAAC,UAAU,EAAE,OAAO,GAAG,MAAM,EAAE,CAQ1D;AAgBD;;;GAGG;AACH,wBAAgB,UAAU,CACxB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC7C,OAAO,EAAE,SAAS,MAAM,EAAE,EAC1B,QAAQ,EAAE,MAAM,EAAE,EAClB,IAAI,EAAE,MAAM,GACX,MAAM,EAAE,CAWV;AAED,0FAA0F;AAC1F,wBAAgB,gBAAgB,IAAI,YAAY,CAM/C"}
@@ -0,0 +1,77 @@
1
+ const DECISION_LIST_KEYS = [
2
+ "selected",
3
+ "contentTypes",
4
+ "properties",
5
+ "fields",
6
+ "recordIds",
7
+ "ids",
8
+ "paths",
9
+ ];
10
+ function idOf(item) {
11
+ if (typeof item === "string") {
12
+ const id = item.trim();
13
+ return id || null;
14
+ }
15
+ if (!item || typeof item !== "object" || Array.isArray(item))
16
+ return null;
17
+ const record = item;
18
+ for (const key of ["id", "path", "field", "recordId"]) {
19
+ const value = record[key];
20
+ if (typeof value === "string" && value.trim())
21
+ return value.trim();
22
+ }
23
+ return null;
24
+ }
25
+ /** Ids a candidate list offers, in candidate order. */
26
+ export function candidateIds(candidates) {
27
+ if (!Array.isArray(candidates))
28
+ return [];
29
+ const ids = [];
30
+ for (const item of candidates) {
31
+ const id = idOf(item);
32
+ if (id && !ids.includes(id))
33
+ ids.push(id);
34
+ }
35
+ return ids;
36
+ }
37
+ function stringsFromDecision(decision) {
38
+ for (const key of DECISION_LIST_KEYS) {
39
+ const value = decision[key];
40
+ if (!Array.isArray(value))
41
+ continue;
42
+ const ids = [];
43
+ for (const item of value) {
44
+ const id = idOf(item);
45
+ if (id && !ids.includes(id))
46
+ ids.push(id);
47
+ }
48
+ return ids;
49
+ }
50
+ return [];
51
+ }
52
+ /**
53
+ * Keep ids that were candidates. Anything else is dropped and named in `warnings`.
54
+ * Order follows the decision. `answer.value` is not read.
55
+ */
56
+ export function keepPicked(decision, allowed, warnings, step) {
57
+ const allow = new Set(allowed);
58
+ const kept = [];
59
+ for (const id of stringsFromDecision(decision ?? {})) {
60
+ if (!allow.has(id)) {
61
+ warnings.push(`${step}: dropped "${id}" because it is not a candidate.`);
62
+ continue;
63
+ }
64
+ if (!kept.includes(id))
65
+ kept.push(id);
66
+ }
67
+ return kept;
68
+ }
69
+ /** A decider that keeps every candidate. For tests and hosts that want the whole menu. */
70
+ export function selectAllDecider() {
71
+ return {
72
+ async decide(input) {
73
+ return { decision: { selected: candidateIds(input.candidates) } };
74
+ },
75
+ };
76
+ }
77
+ //# sourceMappingURL=pick.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pick.js","sourceRoot":"","sources":["../../src/selection/pick.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type IntentScopeRequest, type ScopeIntent, type ScopeSelection, type TrustedExecutionContext } from "@x12i/memorix-scoper-contracts";
2
+ import type { MemorixScoperClient } from "@x12i/memorix-scoper-sdk";
3
+ import { type SelectionCaches } from "./cache.js";
4
+ import type { ScopeDecider } from "./types.js";
5
+ export interface ScopeSelectionDeps {
6
+ sdk: MemorixScoperClient;
7
+ intents?: Record<string, ScopeIntent>;
8
+ decisions: ScopeDecider;
9
+ caches: SelectionCaches;
10
+ }
11
+ export declare function runScopeSelection(request: IntentScopeRequest, context: TrustedExecutionContext, deps: ScopeSelectionDeps): Promise<ScopeSelection>;
12
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/selection/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAML,KAAK,kBAAkB,EACvB,KAAK,WAAW,EAChB,KAAK,cAAc,EACnB,KAAK,uBAAuB,EAC7B,MAAM,gCAAgC,CAAC;AAUxC,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0BAA0B,CAAC;AAEpE,OAAO,EAML,KAAK,eAAe,EAGrB,MAAM,YAAY,CAAC;AAEpB,OAAO,KAAK,EAAE,YAAY,EAA2C,MAAM,YAAY,CAAC;AAIxF,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,mBAAmB,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACtC,SAAS,EAAE,YAAY,CAAC;IACxB,MAAM,EAAE,eAAe,CAAC;CACzB;AAuND,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,EAAE,uBAAuB,EAChC,IAAI,EAAE,kBAAkB,GACvB,OAAO,CAAC,cAAc,CAAC,CA0SzB"}