agenr 2.1.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.
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Runtime slot-policy classes used by claim-centric read surfaces.
3
+ */
4
+ type ClaimSlotPolicy = "exclusive" | "multivalued";
5
+ /**
6
+ * Data-driven slot-policy overrides keyed by canonical claim-key attribute head.
7
+ */
8
+ interface ClaimSlotPolicyConfig {
9
+ /** Optional attribute-head policy overrides such as `integration -> exclusive`. */
10
+ attributeHeads?: Readonly<Record<string, ClaimSlotPolicy>>;
11
+ }
12
+
13
+ export type { ClaimSlotPolicyConfig as C, ClaimSlotPolicy as a };
package/dist/cli.js CHANGED
@@ -4,6 +4,12 @@ import {
4
4
  computeProcedureRevisionHash,
5
5
  computeProcedureSourceHash
6
6
  } from "./chunk-ZYADFKX3.js";
7
+ import {
8
+ deriveOpenClawSessionIdFromFilePath,
9
+ openClawTranscriptParser,
10
+ parseTuiSessionKey,
11
+ readOpenClawSessionsStore
12
+ } from "./chunk-TBFAARM5.js";
7
13
  import {
8
14
  applyClaimExtractionResultToEntry,
9
15
  backfillEpisodeEmbeddings,
@@ -12,8 +18,7 @@ import {
12
18
  computeContentHash,
13
19
  computeNormContentHash,
14
20
  createEpisodeIngestPlan,
15
- createOpenClawRepository,
16
- deriveOpenClawSessionIdFromFilePath,
21
+ createMemoryRepository,
17
22
  describeSupersessionRuleFailure,
18
23
  detectClaimKeyEntityFamilyCandidates,
19
24
  detectClaimKeySingletonAliasCandidates,
@@ -21,17 +26,14 @@ import {
21
26
  evaluateClaimKeySupport,
22
27
  executeEpisodeIngestPlan,
23
28
  normalizeGroundingTags,
24
- openClawTranscriptParser,
25
- parseTuiSessionKey,
26
29
  prepareEpisodeIngest,
27
30
  previewClaimKeyExtraction,
28
- readOpenClawSessionsStore,
29
31
  runBatchClaimExtraction,
30
32
  storeEntriesDetailed,
31
33
  tokenizeGroundingText,
32
34
  validateEntriesWithIndexes,
33
35
  validateSupersessionRules
34
- } from "./chunk-DGV6D6Q3.js";
36
+ } from "./chunk-LAXNNWHM.js";
35
37
  import {
36
38
  DEFAULT_CLAIM_EXTRACTION_CONCURRENCY,
37
39
  DEFAULT_SURGEON_CONTEXT_LIMIT,
@@ -98,7 +100,7 @@ import {
98
100
  updateEntry,
99
101
  validateTemporalValidityRange,
100
102
  writeConfig
101
- } from "./chunk-7TDALVPY.js";
103
+ } from "./chunk-ELR2HSVC.js";
102
104
  import {
103
105
  compactClaimKey,
104
106
  describeClaimKeyNormalizationFailure,
@@ -109,7 +111,7 @@ import {
109
111
  normalizeClaimKeySegment,
110
112
  recall,
111
113
  resolveClaimSlotPolicy
112
- } from "./chunk-6T5RXGIR.js";
114
+ } from "./chunk-5LADPJ4C.js";
113
115
 
114
116
  // src/cli/main.ts
115
117
  import { Command } from "commander";
@@ -4007,7 +4009,7 @@ function parseConcurrency(value) {
4007
4009
  }
4008
4010
 
4009
4011
  // src/cli/commands/setup.ts
4010
- import { getModels } from "@mariozechner/pi-ai";
4012
+ import { getModels } from "@earendil-works/pi-ai";
4011
4013
 
4012
4014
  // src/cli/ui.ts
4013
4015
  import os from "os";
@@ -5088,7 +5090,7 @@ async function runSetupCore2(options = {}) {
5088
5090
  }
5089
5091
 
5090
5092
  // src/cli/commands/init/cost-estimator.ts
5091
- import { getModels as getModels2 } from "@mariozechner/pi-ai";
5093
+ import { getModels as getModels2 } from "@earendil-works/pi-ai";
5092
5094
  var CHARS_PER_TOKEN2 = 4;
5093
5095
  var EFFECTIVE_CONTENT_RATIO = 0.1;
5094
5096
  var OUTPUT_TOKEN_RATIO = 0.1;
@@ -5904,7 +5906,7 @@ import { InvalidArgumentError as InvalidArgumentError5, Option as Option4 } from
5904
5906
  import { randomUUID as randomUUID11 } from "crypto";
5905
5907
  import { mkdir as mkdir2, writeFile } from "fs/promises";
5906
5908
  import path20 from "path";
5907
- import { getModel } from "@mariozechner/pi-ai";
5909
+ import { getModel } from "@earendil-works/pi-ai";
5908
5910
 
5909
5911
  // src/adapters/db/surgeon-run-log.ts
5910
5912
  import { randomUUID as randomUUID2 } from "crypto";
@@ -7392,7 +7394,7 @@ function createSurgeonPort(executor) {
7392
7394
  import { randomUUID as randomUUID9 } from "crypto";
7393
7395
  import fs10 from "fs";
7394
7396
  import path15 from "path";
7395
- import { runAgentLoop } from "@mariozechner/pi-agent-core";
7397
+ import { runAgentLoop } from "@earendil-works/pi-agent-core";
7396
7398
 
7397
7399
  // src/core/surgeon/domain/run-presets.ts
7398
7400
  var AUTONOMOUS_SURGEON_SEQUENCE = ["claim_key_quality", "proposal_resolution", "supersession", "retirement"];
@@ -15652,7 +15654,7 @@ import { InvalidArgumentError as InvalidArgumentError6, Option as Option5 } from
15652
15654
  import { copyFile, mkdir as mkdir3 } from "fs/promises";
15653
15655
  import path21 from "path";
15654
15656
  import { fileURLToPath as fileURLToPath3 } from "url";
15655
- import { getModel as getModel2 } from "@mariozechner/pi-ai";
15657
+ import { getModel as getModel2 } from "@earendil-works/pi-ai";
15656
15658
  var DEFAULT_SURGEON_PROVIDER = "openai";
15657
15659
  var DEFAULT_SURGEON_MODEL = "gpt-5.4-mini";
15658
15660
  var getModelWithStrings = getModel2;
@@ -16814,8 +16816,8 @@ function formatPassContextSummary(event) {
16814
16816
  // src/cli/commands/trace.ts
16815
16817
  import { Option as Option6 } from "commander";
16816
16818
 
16817
- // src/app/openclaw/inspect.ts
16818
- async function loadOpenClawEntryTraceRuntime(input) {
16819
+ // src/app/memory/inspect.ts
16820
+ async function loadEntryTraceRuntime(input) {
16819
16821
  const selector = normalizeTraceSelector(input);
16820
16822
  const configPathOverride = normalizeOptionalString13(input.env?.AGENR_CONFIG_PATH);
16821
16823
  const config = readConfig({
@@ -16824,7 +16826,7 @@ async function loadOpenClawEntryTraceRuntime(input) {
16824
16826
  });
16825
16827
  const dbPath = normalizeOptionalString13(input.dbPath) ?? normalizeOptionalString13(input.env?.AGENR_DB_PATH) ?? resolveDbPath(config);
16826
16828
  const database = await createDatabase(dbPath);
16827
- const repository = createOpenClawRepository(database);
16829
+ const repository = createMemoryRepository(database);
16828
16830
  try {
16829
16831
  const entryId = await resolveTraceEntryId(repository, selector);
16830
16832
  const trace = await repository.getEntryTrace(entryId);
@@ -16876,7 +16878,7 @@ function normalizeOptionalString13(value) {
16876
16878
  function registerTraceCommand(program2) {
16877
16879
  program2.command("trace").description("Inspect one entry's provenance and claim-family lineage").addOption(new Option6("--id <id>", "Entry id to inspect")).addOption(new Option6("--subject <text>", "Subject text to resolve when the id is unknown")).option("--last", "Inspect the most recently created entry").option("--json", "Emit structured JSON output").action(async (options) => {
16878
16880
  try {
16879
- const trace = await loadOpenClawEntryTraceRuntime({
16881
+ const trace = await loadEntryTraceRuntime({
16880
16882
  id: options.id,
16881
16883
  subject: options.subject,
16882
16884
  last: options.last === true,
@@ -1,17 +1,6 @@
1
- import { E as EntryType, C as CrossEncoderPort, a as Expiry, R as RecallInput, b as RecallPorts, c as RecallOutput } from '../../ports-Nj5nd2Ri.js';
2
- export { D as DEFAULT_NEIGHBORHOOD_BUDGET, d as DEFAULT_SEEDED_RERANK_WEIGHT, e as DEFAULT_STRONG_SEED_SCORE_GAP, f as DEFAULT_STRONG_SEED_TOP_N, g as EntityAttributeKind, h as EntityAttributeQueryShape, i as EntryFilters, j as EntryNeighborhoodRequest, F as FtsCandidate, N as NeighborhoodFamily, k as RecallCandidateEntry, l as RecallRankingProfile, S as SeededRerankCandidate, m as SeededRerankOptions, V as VectorCandidate, s as seededRerank, n as selectStrongSeeds, o as sharesEntryLineage, p as sharesEpisodeLineage, q as sharesProcedureLineage } from '../../ports-Nj5nd2Ri.js';
3
-
4
- /**
5
- * Runtime slot-policy classes used by claim-centric read surfaces.
6
- */
7
- type ClaimSlotPolicy = "exclusive" | "multivalued";
8
- /**
9
- * Data-driven slot-policy overrides keyed by canonical claim-key attribute head.
10
- */
11
- interface ClaimSlotPolicyConfig {
12
- /** Optional attribute-head policy overrides such as `integration -> exclusive`. */
13
- attributeHeads?: Readonly<Record<string, ClaimSlotPolicy>>;
14
- }
1
+ import { E as EntryType, C as CrossEncoderPort, a as Expiry, R as RecallInput, b as RecallPorts, c as RecallOutput } from '../../ports-CpzWESmZ.js';
2
+ export { D as DEFAULT_NEIGHBORHOOD_BUDGET, d as DEFAULT_SEEDED_RERANK_WEIGHT, e as DEFAULT_STRONG_SEED_SCORE_GAP, f as DEFAULT_STRONG_SEED_TOP_N, g as EntityAttributeKind, h as EntityAttributeQueryShape, i as EntryFilters, j as EntryNeighborhoodRequest, F as FtsCandidate, N as NeighborhoodFamily, k as RecallCandidateEntry, l as RecallRankingProfile, S as SeededRerankCandidate, m as SeededRerankOptions, V as VectorCandidate, s as seededRerank, n as selectStrongSeeds, o as sharesEntryLineage, p as sharesEpisodeLineage, q as sharesProcedureLineage } from '../../ports-CpzWESmZ.js';
3
+ import { C as ClaimSlotPolicyConfig } from '../../claim-slot-policy-CdrW_1l4.js';
15
4
 
16
5
  /**
17
6
  * Stable reason emitted when recall returns no final results.
@@ -353,6 +342,7 @@ declare const DEFAULT_CROSS_ENCODER_TOP_K = 10;
353
342
  * letting prior shaping stages shape the final order.
354
343
  */
355
344
  declare const DEFAULT_CROSS_ENCODER_ALPHA = 0.6;
345
+
356
346
  /**
357
347
  * One input candidate for the cross-encoder rerank helper.
358
348
  *
@@ -549,6 +539,7 @@ declare const DEFAULT_MMR_LAMBDA = 0.7;
549
539
  * `droppedDuplicateCount` counter; it does not affect the MMR ordering.
550
540
  */
551
541
  declare const NEAR_DUPLICATE_SIMILARITY = 0.95;
542
+
552
543
  /**
553
544
  * Input candidate consumed by the MMR helper.
554
545
  */
@@ -28,7 +28,7 @@ import {
28
28
  sharesEpisodeLineage,
29
29
  sharesProcedureLineage,
30
30
  tokenize
31
- } from "../../chunk-6T5RXGIR.js";
31
+ } from "../../chunk-5LADPJ4C.js";
32
32
  export {
33
33
  DEFAULT_CROSS_ENCODER_ALPHA,
34
34
  DEFAULT_CROSS_ENCODER_TOP_K,
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-MJIB6J5S.js";
2
+ import "./chunk-P5SB75FK.js";
3
3
  import "./chunk-ZYADFKX3.js";
4
- import "./chunk-IMQIJPIP.js";
5
- import "./chunk-7TDALVPY.js";
6
- import "./chunk-6T5RXGIR.js";
4
+ import "./chunk-GELCEVFA.js";
5
+ import "./chunk-575MUIW5.js";
6
+ import "./chunk-ELR2HSVC.js";
7
+ import "./chunk-5LADPJ4C.js";
@@ -1,6 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import "./chunk-MJIB6J5S.js";
2
+ import "./chunk-P5SB75FK.js";
3
3
  import "./chunk-ZYADFKX3.js";
4
- import "./chunk-IMQIJPIP.js";
5
- import "./chunk-7TDALVPY.js";
6
- import "./chunk-6T5RXGIR.js";
4
+ import "./chunk-GELCEVFA.js";
5
+ import "./chunk-575MUIW5.js";
6
+ import "./chunk-ELR2HSVC.js";
7
+ import "./chunk-5LADPJ4C.js";
@@ -34,7 +34,7 @@ type ClaimKeySource = (typeof CLAIM_KEY_SOURCES)[number];
34
34
  */
35
35
  type ClaimSupportMode = (typeof CLAIM_SUPPORT_MODES)[number];
36
36
  /** Ordered list of supported episode sources. */
37
- declare const EPISODE_SOURCES: readonly ["openclaw", "codex", "cli", "synthesis"];
37
+ declare const EPISODE_SOURCES: readonly ["openclaw", "skeln", "codex", "cli", "synthesis"];
38
38
  /** Ordered list of supported episode activity levels. */
39
39
  declare const EPISODE_ACTIVITY_LEVELS: readonly ["substantial", "minimal", "none"];
40
40
  /** Ordered list of supported procedure step kinds. */
@@ -106,6 +106,30 @@ interface Entry extends ClaimKeyLifecycleMetadata {
106
106
  created_at: string;
107
107
  updated_at: string;
108
108
  }
109
+ /**
110
+ * Mutable entry fields supported by direct update paths.
111
+ *
112
+ * Claim-key lifecycle updates are replacement-style, not merge-style. When any
113
+ * lifecycle field is mutated, callers must provide one complete validated
114
+ * lifecycle payload for the target claim key. Partial lifecycle patches are
115
+ * rejected at the persistence boundary.
116
+ */
117
+ interface EntryUpdateInput {
118
+ importance?: Entry["importance"];
119
+ expiry?: Entry["expiry"];
120
+ claim_key?: Entry["claim_key"];
121
+ claim_key_raw?: Entry["claim_key_raw"];
122
+ claim_key_status?: Entry["claim_key_status"];
123
+ claim_key_source?: Entry["claim_key_source"];
124
+ claim_key_confidence?: Entry["claim_key_confidence"];
125
+ claim_key_rationale?: Entry["claim_key_rationale"];
126
+ claim_support_source_kind?: Entry["claim_support_source_kind"];
127
+ claim_support_locator?: Entry["claim_support_locator"];
128
+ claim_support_observed_at?: Entry["claim_support_observed_at"];
129
+ claim_support_mode?: Entry["claim_support_mode"];
130
+ valid_from?: Entry["valid_from"];
131
+ valid_to?: Entry["valid_to"];
132
+ }
109
133
  /**
110
134
  * Canonical stored episodic-memory record.
111
135
  */
@@ -359,6 +383,65 @@ interface ParsedTranscript {
359
383
  warnings: string[];
360
384
  }
361
385
 
386
+ /**
387
+ * Aggregate active corpus counts for one entity prefix.
388
+ */
389
+ interface ClaimKeyEntityPrefixStats {
390
+ entityPrefix: string;
391
+ activeEntryCount: number;
392
+ trustedEntryCount: number;
393
+ tentativeEntryCount: number;
394
+ unresolvedEntryCount: number;
395
+ legacyEntryCount: number;
396
+ deterministicRepairEntryCount: number;
397
+ manualEntryCount: number;
398
+ modelEntryCount: number;
399
+ jsonRetryEntryCount: number;
400
+ surgeonFamilyReuseEntryCount: number;
401
+ }
402
+
403
+ /**
404
+ * Write-time episode payload before adapter-managed identity and lifecycle fields are applied.
405
+ */
406
+ interface EpisodeInput {
407
+ source: EpisodeSource;
408
+ sourceId?: string;
409
+ sourceRef?: string;
410
+ transcriptHash?: string;
411
+ summaryHash?: string;
412
+ agentId?: string;
413
+ surface?: string;
414
+ startedAt: string;
415
+ endedAt?: string;
416
+ summary: string;
417
+ tags?: string[];
418
+ activityLevel?: EpisodeActivityLevel;
419
+ userId?: string;
420
+ project?: string;
421
+ genModel?: string;
422
+ genVersion?: string;
423
+ messageCount?: number;
424
+ embedding?: number[];
425
+ }
426
+ /**
427
+ * Calendar-aware temporal constraint used by future episode retrieval.
428
+ */
429
+ interface TemporalWindow {
430
+ kind: "interval" | "anchor" | "open_start" | "open_end";
431
+ start?: Date;
432
+ end?: Date;
433
+ anchor?: Date;
434
+ radiusDays?: number;
435
+ source: "explicit" | "inferred";
436
+ }
437
+ /**
438
+ * Upsert outcome returned by episode persistence adapters.
439
+ */
440
+ interface EpisodeUpsertResult {
441
+ episode: Episode;
442
+ action: "inserted" | "updated" | "unchanged";
443
+ }
444
+
362
445
  /**
363
446
  * Internal ranking profiles that adjust recall scoring for specific query intents.
364
447
  */
@@ -538,6 +621,7 @@ declare const DEFAULT_STRONG_SEED_SCORE_GAP = 0.05;
538
621
  * trust suppression.
539
622
  */
540
623
  declare const DEFAULT_SEEDED_RERANK_WEIGHT = 0.03;
624
+
541
625
  /** Shared shape used by all seededRerank callers. */
542
626
  interface SeededRerankCandidate {
543
627
  /** Stable identifier used to detect the seed itself and skip rerank. */
@@ -624,6 +708,119 @@ declare function sharesEpisodeLineage(candidate: Episode, seed: Episode): boolea
624
708
  */
625
709
  declare function sharesProcedureLineage(candidate: Procedure, seed: Procedure): boolean;
626
710
 
711
+ /**
712
+ * Storage contract for persisting, updating, and querying knowledge entries.
713
+ */
714
+ interface DatabasePort {
715
+ /** Insert a new entry with its embedding. */
716
+ insertEntry(entry: Entry, embedding: number[], contentHash: string): Promise<string>;
717
+ /** Drop expensive indexes and triggers before a bulk write phase begins. */
718
+ prepareForBulkWrites(): Promise<void>;
719
+ /** Rebuild expensive indexes and triggers after a bulk write phase ends. */
720
+ finalizeBulkWrites(): Promise<void>;
721
+ /** Get entries by IDs. */
722
+ getEntries(ids: string[]): Promise<Entry[]>;
723
+ /** Get a single entry by ID. */
724
+ getEntry(id: string): Promise<Entry | null>;
725
+ /** Check if content hashes already exist. Returns the set of existing hashes. */
726
+ findExistingHashes(hashes: string[]): Promise<Set<string>>;
727
+ /** Check if normalized content hashes already exist. Returns the set of existing hashes. */
728
+ findExistingNormHashes(hashes: string[]): Promise<Set<string>>;
729
+ /** Mark an entry as retired. */
730
+ retireEntry(id: string, reason?: string): Promise<boolean>;
731
+ /** Supersede an active entry, linking it to the new entry that replaces it. */
732
+ supersedeEntry(oldId: string, newId: string, kind?: string, reason?: string): Promise<boolean>;
733
+ /** Find active entries with the given claim key. */
734
+ findActiveEntriesByClaimKey(claimKey: string): Promise<Entry[]>;
735
+ /** Get distinct entity prefixes from existing claim keys. */
736
+ getDistinctClaimKeyPrefixes(): Promise<string[]>;
737
+ /** Get bounded full claim-key examples ordered for extraction hinting. */
738
+ getClaimKeyExamples?(limit?: number): Promise<string[]>;
739
+ /** Get active per-prefix claim-key counts for conservative alias-family handling. */
740
+ getClaimKeyEntityPrefixStats?(): Promise<ClaimKeyEntityPrefixStats[]>;
741
+ /** Update entry fields (importance, expiry, and temporal metadata). */
742
+ updateEntry(id: string, fields: EntryUpdateInput): Promise<boolean>;
743
+ /** Check if a file has been ingested (by path + hash). */
744
+ getIngestLogEntry(filePath: string): Promise<{
745
+ fileHash: string;
746
+ ingestedAt: string;
747
+ } | null>;
748
+ /** Record that a file was ingested. */
749
+ insertIngestLogEntry(filePath: string, fileHash: string, entryCount: number): Promise<void>;
750
+ /** Initialize the database schema. */
751
+ init(): Promise<void>;
752
+ /** Close the database connection. */
753
+ close(): Promise<void>;
754
+ }
755
+ /**
756
+ * Storage contract for persisting and querying episodic memory records.
757
+ */
758
+ interface EpisodeDatabasePort {
759
+ /** Get one episode by its stable `(source, sourceId)` identity. */
760
+ getEpisodeBySourceId(source: EpisodeSource, sourceId: string): Promise<Episode | null>;
761
+ /** Get one episode by fallback `(source, transcriptHash)` identity. */
762
+ getEpisodeByTranscriptHash(source: EpisodeSource, transcriptHash: string): Promise<Episode | null>;
763
+ /** Insert or update an episode using `summaryHash` change detection. */
764
+ upsertEpisode(input: EpisodeInput): Promise<EpisodeUpsertResult>;
765
+ /** List non-retired episodes whose time range overlaps the requested window. */
766
+ listEpisodesByTimeWindow(window: TemporalWindow, limit?: number): Promise<Episode[]>;
767
+ /** Find episodes by vector similarity to a query embedding. */
768
+ episodeVectorSearch(params: {
769
+ embedding: number[];
770
+ limit: number;
771
+ }): Promise<Array<{
772
+ episode: Episode;
773
+ vectorSim: number;
774
+ }>>;
775
+ /** List non-retired episodes that still need embeddings. */
776
+ listEpisodesWithoutEmbeddings(limit?: number): Promise<Episode[]>;
777
+ /** Update only the embedding payload for an existing episode row. */
778
+ updateEpisodeEmbedding(id: string, embedding: number[]): Promise<void>;
779
+ }
780
+ /**
781
+ * Storage contract for persisting and querying procedural-memory revisions.
782
+ */
783
+ interface ProcedureDatabasePort {
784
+ /** Insert or update one procedure revision row. */
785
+ upsertProcedure(procedure: Procedure): Promise<Procedure>;
786
+ /** Get one active procedure by primary key. */
787
+ getProcedure(id: string): Promise<Procedure | null>;
788
+ /** Hydrate active procedures by ID while preserving caller order. */
789
+ hydrateProcedures(ids: string[]): Promise<Procedure[]>;
790
+ /** Get the currently active procedure revision for one stable key. */
791
+ findActiveProcedureByKey(procedureKey: string): Promise<Procedure | null>;
792
+ /** Find procedures by vector similarity to a query embedding. */
793
+ procedureVectorSearch(params: {
794
+ embedding: number[];
795
+ limit: number;
796
+ }): Promise<Array<{
797
+ procedure: Procedure;
798
+ vectorSim: number;
799
+ }>>;
800
+ /** Find procedures by lexical search over the procedure FTS index. */
801
+ procedureFtsSearch(params: {
802
+ text: string;
803
+ limit: number;
804
+ }): Promise<Array<{
805
+ procedure: Procedure;
806
+ rank: number;
807
+ }>>;
808
+ /** List active procedures that still need embeddings. */
809
+ listProceduresWithoutEmbeddings(limit?: number): Promise<Procedure[]>;
810
+ /** Update only the embedding payload for an existing procedure row. */
811
+ updateProcedureEmbedding(id: string, embedding: number[]): Promise<void>;
812
+ /** Mark one active procedure revision as retired. */
813
+ retireProcedure(id: string, reason?: string): Promise<boolean>;
814
+ /** Supersede one active procedure revision with a new revision. */
815
+ supersedeProcedure(oldId: string, newId: string, reason?: string): Promise<boolean>;
816
+ }
817
+ /**
818
+ * Embedding provider contract used by core ranking and storage flows.
819
+ */
820
+ interface EmbeddingPort {
821
+ /** Compute embeddings for one or more texts. */
822
+ embed(texts: string[]): Promise<number[][]>;
823
+ }
627
824
  /**
628
825
  * Query-time retrieval contract used by the v1 recall pipeline.
629
826
  */
@@ -669,6 +866,15 @@ interface RecallPorts {
669
866
  */
670
867
  crossEncoder?: CrossEncoderPort;
671
868
  }
869
+ /**
870
+ * LLM provider contract for free-form and structured completions.
871
+ */
872
+ interface LlmPort {
873
+ /** Generate a completion from a system prompt and user message. */
874
+ complete(systemPrompt: string, userMessage: string): Promise<string>;
875
+ /** Generate a structured completion (JSON output). */
876
+ completeJson<T>(systemPrompt: string, userMessage: string): Promise<T>;
877
+ }
672
878
  /**
673
879
  * One passage handed to the cross-encoder for relevance scoring.
674
880
  */
@@ -716,4 +922,4 @@ interface TranscriptPort {
716
922
  }): Promise<ParsedTranscript>;
717
923
  }
718
924
 
719
- export { type CrossEncoderPort as C, DEFAULT_NEIGHBORHOOD_BUDGET as D, type EntryType as E, type FtsCandidate as F, type NeighborhoodFamily as N, type ParsedTranscript as P, type RecallInput as R, type SeededRerankCandidate as S, type TranscriptPort as T, type VectorCandidate as V, type Expiry as a, type RecallPorts as b, type RecallOutput as c, DEFAULT_SEEDED_RERANK_WEIGHT as d, DEFAULT_STRONG_SEED_SCORE_GAP as e, DEFAULT_STRONG_SEED_TOP_N as f, type EntityAttributeKind as g, type EntityAttributeQueryShape as h, type EntryFilters as i, type EntryNeighborhoodRequest as j, type RecallCandidateEntry as k, type RecallRankingProfile as l, type SeededRerankOptions as m, selectStrongSeeds as n, sharesEntryLineage as o, sharesEpisodeLineage as p, sharesProcedureLineage as q, seededRerank as s };
925
+ export { type CrossEncoderPort as C, DEFAULT_NEIGHBORHOOD_BUDGET as D, type EntryType as E, type FtsCandidate as F, type LlmPort as L, type NeighborhoodFamily as N, type ParsedTranscript as P, type RecallInput as R, type SeededRerankCandidate as S, type TranscriptPort as T, type VectorCandidate as V, type Expiry as a, type RecallPorts as b, type RecallOutput as c, DEFAULT_SEEDED_RERANK_WEIGHT as d, DEFAULT_STRONG_SEED_SCORE_GAP as e, DEFAULT_STRONG_SEED_TOP_N as f, type EntityAttributeKind as g, type EntityAttributeQueryShape as h, type EntryFilters as i, type EntryNeighborhoodRequest as j, type RecallCandidateEntry as k, type RecallRankingProfile as l, type SeededRerankOptions as m, selectStrongSeeds as n, sharesEntryLineage as o, sharesEpisodeLineage as p, sharesProcedureLineage as q, type ProcedureDatabasePort as r, seededRerank as s, type Entry as t, type DatabasePort as u, type EpisodeDatabasePort as v, type EmbeddingPort as w };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agenr",
3
- "version": "2.1.0",
3
+ "version": "3.0.0",
4
4
  "description": "Agent memory - local-first knowledge infrastructure for AI agents",
5
5
  "type": "module",
6
6
  "bin": {
@@ -15,8 +15,8 @@
15
15
  "dependencies": {
16
16
  "@clack/prompts": "^1.1.0",
17
17
  "@libsql/client": "^0.17.2",
18
- "@mariozechner/pi-agent-core": "^0.63.1",
19
- "@mariozechner/pi-ai": "^0.63.2",
18
+ "@earendil-works/pi-agent-core": "^0.78.0",
19
+ "@earendil-works/pi-ai": "^0.78.0",
20
20
  "@sinclair/typebox": "^0.34.0",
21
21
  "chalk": "^5.6.2",
22
22
  "commander": "^14.0.3",
@@ -26,6 +26,8 @@
26
26
  "devDependencies": {
27
27
  "@eslint/js": "^10.0.1",
28
28
  "@types/node": "^25.5.0",
29
+ "skeln": "file:../skeln",
30
+ "typebox": "^1.1.38",
29
31
  "eslint": "^10.1.0",
30
32
  "eslint-plugin-jsdoc": "^62.8.1",
31
33
  "globals": "^17.4.0",
@@ -42,10 +44,10 @@
42
44
  "scripts": {
43
45
  "build": "pnpm run build:root && pnpm run build:plugin",
44
46
  "build:root": "tsup",
45
- "build:plugin": "pnpm --filter @agenr/agenr-plugin build",
47
+ "build:plugin": "pnpm --filter @agenr/agenr-plugin build && pnpm --filter @agenr/skeln-plugin build",
46
48
  "build:debug": "pnpm run build:root:debug && pnpm run build:plugin:debug",
47
49
  "build:root:debug": "tsup --sourcemap",
48
- "build:plugin:debug": "pnpm --filter @agenr/agenr-plugin build:debug",
50
+ "build:plugin:debug": "pnpm --filter @agenr/agenr-plugin build:debug && pnpm --filter @agenr/skeln-plugin build:debug",
49
51
  "dev": "tsup --watch",
50
52
  "internal:eval-server": "pnpm run build:root && node dist/internal-eval-server.js",
51
53
  "internal:recall-eval-server": "pnpm run internal:eval-server",
File without changes