@dsh-agentic-roleplay/state 0.1.1 → 0.2.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 +7 -1
- package/lib/index.d.ts +70 -5
- package/lib/index.js +223 -46
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -66,7 +66,7 @@ The package owns how a story is remembered, not only where it is stored:
|
|
|
66
66
|
- `session.records(scope)` reads the records back in the same wire format.
|
|
67
67
|
- `session.recall({ characterId, situation, turn, policy })` is what a character is reminded of: events it took in and things it believes, by who the situation mentions, shared words and tags, importance and story-time recency; with `policy.flaky` the older and less important are told as faded or vague, or are gone. Age is elapsed story time from `session.clock`, never turn count; an unimportant event has a six-story-day half-life. It counts what it brings back as recalled, which makes it last longer.
|
|
68
68
|
- `session.recallStored(query, { queryVector? })` adds the session's search index to the cues: texts that match the situation by words and, with the vector of the situation, by meaning. `session.searchEvents({ text, vector?, fromTurn, toTurn, minImportance, limit })` finds what happened by the same two searches, merged by reciprocal rank.
|
|
69
|
-
- `session.recallRanked(query, signal, { queryVector? })` is the call for anything that reminds a character of something: `recall`, ranked by meaning when a plugin has registered a ranker with `roleplayState.rankMemories(ranker)` (an embedding model, a reranker; see `docs/capabilities.md`). `session.recallCandidates(query)` gives what could be recalled, with the text to match, for a ranker.
|
|
69
|
+
- `session.recallRanked(query, signal, { queryVector? })` is the call for anything that reminds a character of something: `recall`, ranked by meaning when a plugin has registered a ranker with `roleplayState.rankMemories(ranker)` (an embedding model, a reranker; see `docs/capabilities.md`). `session.recallCandidates(query)` gives what could be recalled, with the text to match, for a ranker. With `explain: true` in the query each recalled thing carries `why`: the cues of the moment (people named, words shared, place), what each search scored it, how much it matters, how long ago it was, how much of it is left in mind and what it was ranked by.
|
|
70
70
|
- `session.knowledge` is the closed-world awareness graph for locations, items and directed exits (`learn`, `knows`, `get`, `list`, `forget`). Directional relationships are the corresponding character-to-character edges. Awareness grants identity only, not current state or whereabouts. `session.planKnownMove` plans through only a character's known places and exits; `planMove` remains the authoritative world planner.
|
|
71
71
|
- `session.factions`, `factionStates`, `factionMemberships`, `factionRelationships` and `factionIntents` store persistent organisations separately from characters that act in scenes. Membership is many-to-many; relationships involving factions are directional and double as closed-world awareness edges.
|
|
72
72
|
- `roleplayState.bind(resolver)` tells the tools which roleplay session an agent works in (the plugin that runs the agents supplies it, with the turn being played and the memory policy).
|
|
@@ -153,6 +153,12 @@ once released: a change is a new entry in `src/sqlite/schema.ts`, and a test
|
|
|
153
153
|
pins the migrations of each release. A database from a newer version is refused
|
|
154
154
|
rather than damaged.
|
|
155
155
|
|
|
156
|
+
Before a file that is behind the latest schema is upgraded, it must pass SQLite's
|
|
157
|
+
quick integrity check (a damaged file is refused with `CorruptDataError`, untouched)
|
|
158
|
+
and a copy of it as it was is written to `migration-backups/schema-<version>.sqlite`
|
|
159
|
+
beside the database, once per old version. `migrationBackupPath(location, version)`
|
|
160
|
+
says where.
|
|
161
|
+
|
|
156
162
|
## Errors
|
|
157
163
|
|
|
158
164
|
| Error | When |
|
package/lib/index.d.ts
CHANGED
|
@@ -2502,6 +2502,16 @@ interface MemoryPolicy {
|
|
|
2502
2502
|
* reranker judges, and it also gives importance and recency something to choose between. At least 1.
|
|
2503
2503
|
*/
|
|
2504
2504
|
overRetrieve?: number;
|
|
2505
|
+
/**
|
|
2506
|
+
* How many more things come to mind because they are strongly tied to what the moment recalled (the same people together with the same
|
|
2507
|
+
* place or tags) and matter enough. 0 or absent: none.
|
|
2508
|
+
*/
|
|
2509
|
+
associate?: number;
|
|
2510
|
+
/**
|
|
2511
|
+
* How much a memory that says what one already chosen says counts against it, from 0 (the best by score, repeats
|
|
2512
|
+
* included) to 1 (only what adds something new): maximal marginal relevance over the pool. 0 or absent: none.
|
|
2513
|
+
*/
|
|
2514
|
+
diversity?: number;
|
|
2505
2515
|
}
|
|
2506
2516
|
declare const DEFAULT_MEMORY_POLICY: MemoryPolicy;
|
|
2507
2517
|
/** How much of a memory is left: what the character is told of it. */
|
|
@@ -2519,6 +2529,38 @@ interface Recalled {
|
|
|
2519
2529
|
kind: 'perception' | 'memory';
|
|
2520
2530
|
id: number;
|
|
2521
2531
|
};
|
|
2532
|
+
/** It did not match the moment itself: it came to mind with something that did ({@link MemoryPolicy.associate}). */
|
|
2533
|
+
linked?: true;
|
|
2534
|
+
/** Why it came back, when the query asked to be told ({@link RecallQuery.explain}). */
|
|
2535
|
+
why?: RecallWhy;
|
|
2536
|
+
}
|
|
2537
|
+
/** What made one thing come back, for finding out why a character was or was not reminded of something. */
|
|
2538
|
+
interface RecallWhy {
|
|
2539
|
+
/** What the cues of the moment gave, in the units of a cue: people named (a name counts 3, more for social weight), words and tags shared (at most 6), being where it happened. */
|
|
2540
|
+
cues: {
|
|
2541
|
+
people: number;
|
|
2542
|
+
words: number;
|
|
2543
|
+
place: number;
|
|
2544
|
+
};
|
|
2545
|
+
/** What each search scored it, from 0 to 1; absent when that search did not run or did not find it. */
|
|
2546
|
+
lexical?: number;
|
|
2547
|
+
dense?: number;
|
|
2548
|
+
rerank?: number;
|
|
2549
|
+
/** What it counted for in the end: the fused retrieval score, blended with the reranker's when there was one. */
|
|
2550
|
+
relevance: number;
|
|
2551
|
+
importance: number;
|
|
2552
|
+
/** How long ago it was in story days; 0 when the story has no clock. */
|
|
2553
|
+
ageDays: number;
|
|
2554
|
+
/** How much of it is left in mind, from 1 to 0, when memories fade. */
|
|
2555
|
+
retention?: number;
|
|
2556
|
+
/** What it was ranked by, together with how much it matters and how recent it is. */
|
|
2557
|
+
score: number;
|
|
2558
|
+
/** For something that came to mind with another: what it shares with the closest of the things recalled for the moment. */
|
|
2559
|
+
linked?: {
|
|
2560
|
+
people: number;
|
|
2561
|
+
tags: number;
|
|
2562
|
+
place: boolean;
|
|
2563
|
+
};
|
|
2522
2564
|
}
|
|
2523
2565
|
interface RecallQuery {
|
|
2524
2566
|
characterId: CharacterId;
|
|
@@ -2530,6 +2572,10 @@ interface RecallQuery {
|
|
|
2530
2572
|
locationId?: number;
|
|
2531
2573
|
turn: number;
|
|
2532
2574
|
policy: MemoryPolicy;
|
|
2575
|
+
/** Say why each thing came back ({@link Recalled.why}). */
|
|
2576
|
+
explain?: boolean;
|
|
2577
|
+
/** Only what involves or is about one of these people comes back: "what do I know about her", which a name in the words would not reliably find. */
|
|
2578
|
+
about?: readonly CharacterId[];
|
|
2533
2579
|
}
|
|
2534
2580
|
/** What recall reads: the events a character took in and what it believes. */
|
|
2535
2581
|
interface RecallSource {
|
|
@@ -2556,14 +2602,22 @@ declare function clarityAt(value: number, importance: number): Clarity | undefin
|
|
|
2556
2602
|
declare function tokens(text: string): Set<string>;
|
|
2557
2603
|
/** The characters a text mentions by name or alias. */
|
|
2558
2604
|
declare function mentioned(text: string, characters: readonly Character[]): Set<number>;
|
|
2605
|
+
/** What ties a candidate to others: the people it involves (other than the one remembering), its tags and where it happened. */
|
|
2606
|
+
interface Links {
|
|
2607
|
+
people: readonly number[];
|
|
2608
|
+
tags: readonly string[];
|
|
2609
|
+
place?: number;
|
|
2610
|
+
}
|
|
2559
2611
|
interface Candidate {
|
|
2560
2612
|
key: string;
|
|
2561
|
-
|
|
2613
|
+
links: Links;
|
|
2614
|
+
recalled: Omit<Recalled, 'clarity' | 'text' | 'why'> & {
|
|
2562
2615
|
clear: string;
|
|
2563
2616
|
faded: string;
|
|
2564
2617
|
vague: string;
|
|
2565
2618
|
};
|
|
2566
2619
|
relevance: number;
|
|
2620
|
+
cues: RecallWhy['cues'];
|
|
2567
2621
|
importance: number;
|
|
2568
2622
|
ageDays: number;
|
|
2569
2623
|
recalls: number;
|
|
@@ -2592,7 +2646,7 @@ interface RecallEvidence {
|
|
|
2592
2646
|
rerank?: ReadonlyMap<string, number>;
|
|
2593
2647
|
}
|
|
2594
2648
|
/** Everything the character could be reminded of, for a caller that ranks by meaning (an embedding, a reranker) before asking for the recall. */
|
|
2595
|
-
declare function recallCandidates(source: RecallSource, query: Pick<RecallQuery, 'characterId' | 'characters' | 'situation' | 'turn' | 'locationId'>): RecallCandidate[];
|
|
2649
|
+
declare function recallCandidates(source: RecallSource, query: Pick<RecallQuery, 'characterId' | 'characters' | 'situation' | 'turn' | 'locationId' | 'about'>): RecallCandidate[];
|
|
2596
2650
|
/** Fuse scores from 0 to 1 into one, per key: the weighted average over the searches that ran (those with any score above 0). */
|
|
2597
2651
|
declare function fuseScores(searches: readonly {
|
|
2598
2652
|
weight: number;
|
|
@@ -2602,11 +2656,18 @@ interface PoolEntry {
|
|
|
2602
2656
|
candidate: Candidate;
|
|
2603
2657
|
/** How well retrieval alone matches the moment, from 0 to 1. */
|
|
2604
2658
|
fused: number;
|
|
2659
|
+
/** What each search scored it, when it was found by it. */
|
|
2660
|
+
found: {
|
|
2661
|
+
lexical?: number;
|
|
2662
|
+
dense?: number;
|
|
2663
|
+
};
|
|
2605
2664
|
}
|
|
2606
2665
|
/** What retrieval over-retrieved for one recall, waiting for a reranker's judgement and the final choice. */
|
|
2607
2666
|
interface RecallPool {
|
|
2608
2667
|
entries: readonly PoolEntry[];
|
|
2609
|
-
|
|
2668
|
+
/** What retrieval left out, which an association may still bring to mind. */
|
|
2669
|
+
others: readonly Candidate[];
|
|
2670
|
+
query: Pick<RecallQuery, 'policy' | 'explain'>;
|
|
2610
2671
|
}
|
|
2611
2672
|
/**
|
|
2612
2673
|
* The first stage of reminding a character of what the moment calls to mind: retrieve, by the cues
|
|
@@ -2619,7 +2680,7 @@ declare function recallPool(source: RecallSource, query: RecallQuery, evidence?:
|
|
|
2619
2680
|
/** What a reranker is asked to judge: every candidate of the pool, with the text it would be recalled by. */
|
|
2620
2681
|
declare function poolCandidates(pool: RecallPool): RecallCandidate[];
|
|
2621
2682
|
/**
|
|
2622
|
-
* The last stage: choose the `policy.recall` best of the pool. With a reranker's judgement each
|
|
2683
|
+
* The last stage: choose the `policy.recall` best of the pool, spread by `policy.diversity`. With a reranker's judgement each
|
|
2623
2684
|
* candidate's relevance is mostly that (a candidate it left out counts as 0), and the rest is what
|
|
2624
2685
|
* retrieval found; without, it is what retrieval found.
|
|
2625
2686
|
*/
|
|
@@ -2963,6 +3024,10 @@ declare function createSessionStore(location: string, session: NewSession, optio
|
|
|
2963
3024
|
* @throws {SchemaError} when the file is not a session database, or is from a newer version.
|
|
2964
3025
|
*/
|
|
2965
3026
|
declare function openSessionStore(location: string, options?: StoreOptions): SessionStore;
|
|
3027
|
+
/** Folder, beside the database, holding the copies made before a schema upgrade. */
|
|
3028
|
+
declare const MIGRATION_BACKUP_FOLDER = "migration-backups";
|
|
3029
|
+
/** Where the copy of a database as it was at schema `version` is kept. */
|
|
3030
|
+
declare function migrationBackupPath(location: string, version: number): string;
|
|
2966
3031
|
//#endregion
|
|
2967
3032
|
//#region src/sessions.d.ts
|
|
2968
3033
|
declare const SESSION_DATABASE_FILE = "session.sqlite";
|
|
@@ -3308,5 +3373,5 @@ type LintTarget = Pick<RecordsTarget, 'characters' | 'locations' | 'placements'
|
|
|
3308
3373
|
*/
|
|
3309
3374
|
declare function lintWorld(target: LintTarget): LintFinding[];
|
|
3310
3375
|
//#endregion
|
|
3311
|
-
export { ACCURACIES, Accuracy, type Agenda, type AgendaEngagement, type AgendaOptions, type AgentLink, type AgentResolver, type Announcement, type BeliefEdit, CHARACTER_CONTROLS, CHARACTER_KINDS, CHARACTER_ROLES, CHARACTER_TIERS, CLOCK_MODES, COMPARISONS, CONSOLIDATION_KINDS, CONTAINER_STATES, Character, CharacterControl, CharacterDefinition, CharacterFilter, CharacterId, CharacterIntent, CharacterKind, CharacterMemory, CharacterMemoryPatch, type CharacterMove, CharacterPatch, type CharacterRepository, CharacterRole, CharacterSpeech, CharacterStart, CharacterState, CharacterStatePatch, type CharacterStateRepository, CharacterTier, type Clarity, type Clock, ClockMode, ClockState, Comparison, Config, ConflictError, ConsolidationItem, ConsolidationItemId, ConsolidationKind, type ConsolidationRepository, ContainerSpec, ContainerState, CorruptDataError, DAY, DAY_PARTS, DEFAULT_MEMORY_POLICY, DEFAULT_SLOTS, type DayPart, EMOTION_VARIABLES, ENGAGEMENT_GRACE, ENGAGEMENT_STATUSES, EXIT_STATES, type EditChecker, type EditResult, EmbeddingIndexInfo, EmotionStart, EmotionVector, Engagement, EngagementFilter, EngagementId, EngagementPatch, EngagementStatus, EntityKnowledge, type EventEdit, EventId, type EventRepository, Exit, type ExitChange, ExitDefinition, ExitId, ExitOpener, ExitPatch, ExitState, Faction, FactionDefinition, FactionId, FactionIntent, type FactionIntentRepository, FactionMembership, FactionMembershipDefinition, type FactionMembershipRepository, FactionPatch, FactionRelationship, FactionRelationshipDefinition, type FactionRelationshipRepository, type FactionRepository, FactionState, FactionStatePatch, type FactionStateRepository, type FiredTrigger, HOUR, Holder, Holding, IMPORTANCE_MAX, IMPORTANCE_MIN, INTENT_HORIZONS, INTENT_STATUSES, INTENT_TYPES, ITEM_ACTIONS, Intent, IntentFilter, IntentHorizon, IntentId, IntentPatch, type IntentRepository, IntentStatus, IntentType, InvalidEditError, InvalidMoveError, InvalidValueError, Item, type ItemAction, type ItemChange, type ItemChangeSpec, type ItemContext, ItemDefinition, type ItemEditSpec, type ItemEffect, ItemId, ItemPatch, type ItemPlan, type ItemRepository, JsonValue, KNOWLEDGE_KINDS, KnowledgeDefinition, KnowledgeKind, type KnowledgeRepository, type KnownMoveContext, LORE_KINDS, LORE_SUBJECT_KINDS, type LintFinding, type LintSeverity, type LintTarget, type LocalTime, Location, LocationDefinition, LocationFeature, LocationId, LocationPatch, type LocationRepository, Lore, LoreDefinition, LoreId, LoreKind, LorePatch, LoreSubject, LoreSubjectDefinition, LoreSubjectKind, MAX_LOCATION_FEATURES, MAX_ROUTINE_WINDOWS, MAX_SHOWN, MAX_TRIGGERS, MAX_VARIABLES, MEMBERSHIP_STATUSES, MEMORY_KINDS, MINUTE, MembershipPatch, MembershipStatus, MemoryId, MemoryKind, type MemoryPolicy, type MemoryRepository, type MetadataRepository, Move, type MoveContext, MovePlan, type NewBelief, NewCharacter, NewCharacterMemory, type NewCharacterSpec, NewCharacterState, NewEngagement, type NewEvent, NewExit, type NewExitBetween, type NewExit$1 as NewExitEdit, NewFaction, NewFactionState, NewItem, type NewItemSpec, NewLocation, NewLore, NewPerception, type NewPlace, NewPlacement, NewRelationship, NewSession, NewStoryEvent, NewSummary, NewTriggerNote, NotFoundError, type Occurrence, type OpenOptions, PERCEPTION_MODES, PLACEABLE_KINDS, PLOT_NUDGE_MODES, PLOT_STATUSES, PendingCommit, type PendingCommitRepository, PendingEmbedding, type PerceivedBy, PerceivedEvent, Perception, type PerceptionAddition, type PerceptionEdit, PerceptionId, PerceptionMode, PerceptionPatch, type PlaceEdit, PlaceableKind, Placement, type PlacementRepository, PlotDefinition, PlotDevelopment, PlotNudgeMode, PlotProgress, PlotStatus, RECALL_ITEM_KINDS, type RankedGoal, type RecallCandidate, type RecallEvidence, RecallHit, type RecallIndexRepository, RecallItemKind, type RecallPool, type RecallQuery, type RecallSearch, type RecallSource, type Recalled, type RecordsEdit, type RecordsScope, type RecordsTarget, type RecordsView, Relationship, RelationshipDefinition, RelationshipId, RelationshipPatch, type RelationshipRepository, type RelationshipRetraction, type RelationshipSet, RoleplayState, RoutineDefinition, RoutineWindow, type RunResult, LATEST_VERSION as SCHEMA_VERSION, SECOND, SESSION_DATABASE_FILE, SLOT_ID, SUMMARY_LEVELS, SchemaError, type SemanticRanker, type Session, type SessionInit, type SessionListing, SessionMetadata, type SessionStore, type ShownVariable, Slot, type SlotRepository, SocialSubjectKind, type SqlDatabase, type SqlDriver, type SqlValue, StateError, type StatePatch, type StoreOptions, StoredRoutineWindow, StoredVariable, StoryEvent, StoryEventFilter, StoryEventPatch, StoryThread, Summary, SummaryId, SummaryLevel, type SummaryRepository, THREAD_STATUSES, TIME_CHANGE_KINDS, TRIGGER_NOTE_KINDS, TRIGGER_STATUSES, ThreadId, type ThreadRepository, ThreadStatus, TimeChange, TimeChangeFilter, TimeChangeKind, Trigger, TriggerAnnouncement, TriggerAudience, type TriggerClock, TriggerCondition, TriggerDefinition, TriggerEffect, TriggerId, TriggerNote, TriggerNoteKind, type TriggerRun, type TriggerRunOptions, TriggerStatus, VARIABLE_KEY, VARIABLE_KINDS, VARIABLE_SUBJECTS, VARIABLE_VISIBILITIES, VISUAL_SUBJECT_KINDS, type VariableAudience, VariableBand, type VariableChangeSpec, type VariableContext, VariableDefinition, VariableDefinitionInput, type VariableEffect, VariableKind, type VariablePlan, VariableSubject, VariableValue, VariableVisibility, type VectorSearch, type VectorSupport, VisualIdentity, VisualIdentityInput, VisualIdentityPatch, type VisualIdentityRepository, VisualSubjectKind, WEEKDAY_NAMES, WorldReference, addLocalDays, agendaAt, announcements, apply, applyItemPlan, applyRecordsEdit, audienceIds, catchUpPlan, changeItem, changeVariable, characterKey, clarityAt, clockTime, conditionHolds, createCharacterTools, createSession, createSessionStore, createTools, dayPart, deleteSession, denseScore, describeDuration, describeHolder, describeInstant, describeValue, finishRecall, fuseScores, inAudience, inWindow, isSessionId, isTimeZone, itemKey, jitter, judgedStatements, lapseNotes, lintWorld, listSessions, localIso, localTime, locationKey, mentioned, moveCharacter, name, nextOccurrence, nextTimeOfDay, nodeSqliteDriver, occurrenceAt, openSession, openSessionStore, overlap, parseInstant, parseRecordsEdit, parseTimeOfDay, parseTriggerDefinition, planItemChange, planKnownMove, planMove, planVariableChange, poolCandidates, rankGoals, readRecords, readTriggerDefinition, recall, recallCandidates, recallPool, recordsEditSchema, retention, runTriggers, seededRoll, sessionDatabase, sessionFolder, shownVariables, subjectOf, systemClock, systemTimeZone, tokens, triggerReferenceProblems, valueIssue, zonedInstant };
|
|
3376
|
+
export { ACCURACIES, Accuracy, type Agenda, type AgendaEngagement, type AgendaOptions, type AgentLink, type AgentResolver, type Announcement, type BeliefEdit, CHARACTER_CONTROLS, CHARACTER_KINDS, CHARACTER_ROLES, CHARACTER_TIERS, CLOCK_MODES, COMPARISONS, CONSOLIDATION_KINDS, CONTAINER_STATES, Character, CharacterControl, CharacterDefinition, CharacterFilter, CharacterId, CharacterIntent, CharacterKind, CharacterMemory, CharacterMemoryPatch, type CharacterMove, CharacterPatch, type CharacterRepository, CharacterRole, CharacterSpeech, CharacterStart, CharacterState, CharacterStatePatch, type CharacterStateRepository, CharacterTier, type Clarity, type Clock, ClockMode, ClockState, Comparison, Config, ConflictError, ConsolidationItem, ConsolidationItemId, ConsolidationKind, type ConsolidationRepository, ContainerSpec, ContainerState, CorruptDataError, DAY, DAY_PARTS, DEFAULT_MEMORY_POLICY, DEFAULT_SLOTS, type DayPart, EMOTION_VARIABLES, ENGAGEMENT_GRACE, ENGAGEMENT_STATUSES, EXIT_STATES, type EditChecker, type EditResult, EmbeddingIndexInfo, EmotionStart, EmotionVector, Engagement, EngagementFilter, EngagementId, EngagementPatch, EngagementStatus, EntityKnowledge, type EventEdit, EventId, type EventRepository, Exit, type ExitChange, ExitDefinition, ExitId, ExitOpener, ExitPatch, ExitState, Faction, FactionDefinition, FactionId, FactionIntent, type FactionIntentRepository, FactionMembership, FactionMembershipDefinition, type FactionMembershipRepository, FactionPatch, FactionRelationship, FactionRelationshipDefinition, type FactionRelationshipRepository, type FactionRepository, FactionState, FactionStatePatch, type FactionStateRepository, type FiredTrigger, HOUR, Holder, Holding, IMPORTANCE_MAX, IMPORTANCE_MIN, INTENT_HORIZONS, INTENT_STATUSES, INTENT_TYPES, ITEM_ACTIONS, Intent, IntentFilter, IntentHorizon, IntentId, IntentPatch, type IntentRepository, IntentStatus, IntentType, InvalidEditError, InvalidMoveError, InvalidValueError, Item, type ItemAction, type ItemChange, type ItemChangeSpec, type ItemContext, ItemDefinition, type ItemEditSpec, type ItemEffect, ItemId, ItemPatch, type ItemPlan, type ItemRepository, JsonValue, KNOWLEDGE_KINDS, KnowledgeDefinition, KnowledgeKind, type KnowledgeRepository, type KnownMoveContext, LORE_KINDS, LORE_SUBJECT_KINDS, type LintFinding, type LintSeverity, type LintTarget, type LocalTime, Location, LocationDefinition, LocationFeature, LocationId, LocationPatch, type LocationRepository, Lore, LoreDefinition, LoreId, LoreKind, LorePatch, LoreSubject, LoreSubjectDefinition, LoreSubjectKind, MAX_LOCATION_FEATURES, MAX_ROUTINE_WINDOWS, MAX_SHOWN, MAX_TRIGGERS, MAX_VARIABLES, MEMBERSHIP_STATUSES, MEMORY_KINDS, MIGRATION_BACKUP_FOLDER, MINUTE, MembershipPatch, MembershipStatus, MemoryId, MemoryKind, type MemoryPolicy, type MemoryRepository, type MetadataRepository, Move, type MoveContext, MovePlan, type NewBelief, NewCharacter, NewCharacterMemory, type NewCharacterSpec, NewCharacterState, NewEngagement, type NewEvent, NewExit, type NewExitBetween, type NewExit$1 as NewExitEdit, NewFaction, NewFactionState, NewItem, type NewItemSpec, NewLocation, NewLore, NewPerception, type NewPlace, NewPlacement, NewRelationship, NewSession, NewStoryEvent, NewSummary, NewTriggerNote, NotFoundError, type Occurrence, type OpenOptions, PERCEPTION_MODES, PLACEABLE_KINDS, PLOT_NUDGE_MODES, PLOT_STATUSES, PendingCommit, type PendingCommitRepository, PendingEmbedding, type PerceivedBy, PerceivedEvent, Perception, type PerceptionAddition, type PerceptionEdit, PerceptionId, PerceptionMode, PerceptionPatch, type PlaceEdit, PlaceableKind, Placement, type PlacementRepository, PlotDefinition, PlotDevelopment, PlotNudgeMode, PlotProgress, PlotStatus, RECALL_ITEM_KINDS, type RankedGoal, type RecallCandidate, type RecallEvidence, RecallHit, type RecallIndexRepository, RecallItemKind, type RecallPool, type RecallQuery, type RecallSearch, type RecallSource, type RecallWhy, type Recalled, type RecordsEdit, type RecordsScope, type RecordsTarget, type RecordsView, Relationship, RelationshipDefinition, RelationshipId, RelationshipPatch, type RelationshipRepository, type RelationshipRetraction, type RelationshipSet, RoleplayState, RoutineDefinition, RoutineWindow, type RunResult, LATEST_VERSION as SCHEMA_VERSION, SECOND, SESSION_DATABASE_FILE, SLOT_ID, SUMMARY_LEVELS, SchemaError, type SemanticRanker, type Session, type SessionInit, type SessionListing, SessionMetadata, type SessionStore, type ShownVariable, Slot, type SlotRepository, SocialSubjectKind, type SqlDatabase, type SqlDriver, type SqlValue, StateError, type StatePatch, type StoreOptions, StoredRoutineWindow, StoredVariable, StoryEvent, StoryEventFilter, StoryEventPatch, StoryThread, Summary, SummaryId, SummaryLevel, type SummaryRepository, THREAD_STATUSES, TIME_CHANGE_KINDS, TRIGGER_NOTE_KINDS, TRIGGER_STATUSES, ThreadId, type ThreadRepository, ThreadStatus, TimeChange, TimeChangeFilter, TimeChangeKind, Trigger, TriggerAnnouncement, TriggerAudience, type TriggerClock, TriggerCondition, TriggerDefinition, TriggerEffect, TriggerId, TriggerNote, TriggerNoteKind, type TriggerRun, type TriggerRunOptions, TriggerStatus, VARIABLE_KEY, VARIABLE_KINDS, VARIABLE_SUBJECTS, VARIABLE_VISIBILITIES, VISUAL_SUBJECT_KINDS, type VariableAudience, VariableBand, type VariableChangeSpec, type VariableContext, VariableDefinition, VariableDefinitionInput, type VariableEffect, VariableKind, type VariablePlan, VariableSubject, VariableValue, VariableVisibility, type VectorSearch, type VectorSupport, VisualIdentity, VisualIdentityInput, VisualIdentityPatch, type VisualIdentityRepository, VisualSubjectKind, WEEKDAY_NAMES, WorldReference, addLocalDays, agendaAt, announcements, apply, applyItemPlan, applyRecordsEdit, audienceIds, catchUpPlan, changeItem, changeVariable, characterKey, clarityAt, clockTime, conditionHolds, createCharacterTools, createSession, createSessionStore, createTools, dayPart, deleteSession, denseScore, describeDuration, describeHolder, describeInstant, describeValue, finishRecall, fuseScores, inAudience, inWindow, isSessionId, isTimeZone, itemKey, jitter, judgedStatements, lapseNotes, lintWorld, listSessions, localIso, localTime, locationKey, mentioned, migrationBackupPath, moveCharacter, name, nextOccurrence, nextTimeOfDay, nodeSqliteDriver, occurrenceAt, openSession, openSessionStore, overlap, parseInstant, parseRecordsEdit, parseTimeOfDay, parseTriggerDefinition, planItemChange, planKnownMove, planMove, planVariableChange, poolCandidates, rankGoals, readRecords, readTriggerDefinition, recall, recallCandidates, recallPool, recordsEditSchema, retention, runTriggers, seededRoll, sessionDatabase, sessionFolder, shownVariables, subjectOf, systemClock, systemTimeZone, tokens, triggerReferenceProblems, valueIssue, zonedInstant };
|
|
3312
3377
|
//# sourceMappingURL=index.d.ts.map
|
package/lib/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { createRequire } from "node:module";
|
|
2
2
|
import { DatabaseSync } from "node:sqlite";
|
|
3
|
-
import { join, resolve } from "node:path";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
4
|
import { Service } from "@deepseek-ai/cordis";
|
|
5
5
|
import z from "@deepseek-ai/schemastery";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
@@ -1922,9 +1922,15 @@ function describeValue(def, value) {
|
|
|
1922
1922
|
const band = def.bands.find((candidate) => value <= candidate.upTo) ?? def.bands.at(-1);
|
|
1923
1923
|
return band === void 0 ? shortNumber(value) : `${band.label} (${shortNumber(value)})`;
|
|
1924
1924
|
}
|
|
1925
|
+
/** A variable written by its name or in other letter case ("Valence" for `valence`), when exactly one variable has that name or key. */
|
|
1926
|
+
function namedVariable(variables, written) {
|
|
1927
|
+
const wanted = written.trim().normalize("NFKC").toLowerCase();
|
|
1928
|
+
const found = wanted === "" ? [] : variables.defs().filter((def) => def.key.normalize("NFKC").toLowerCase() === wanted || def.name.normalize("NFKC").toLowerCase() === wanted);
|
|
1929
|
+
return found.length === 1 ? found[0] : void 0;
|
|
1930
|
+
}
|
|
1925
1931
|
/** Whether a change can be made, and what it would come to. Nothing is changed. */
|
|
1926
1932
|
function planVariableChange(context, spec) {
|
|
1927
|
-
const def = context.variables.def(spec.variable);
|
|
1933
|
+
const def = context.variables.def(spec.variable) ?? namedVariable(context.variables, spec.variable);
|
|
1928
1934
|
if (def === void 0) return {
|
|
1929
1935
|
ok: false,
|
|
1930
1936
|
problems: [`there is no variable "${spec.variable}" (list_variables shows them)`]
|
|
@@ -5210,7 +5216,9 @@ const DAY$1 = 864e5;
|
|
|
5210
5216
|
const DEFAULT_MEMORY_POLICY = {
|
|
5211
5217
|
flaky: true,
|
|
5212
5218
|
recall: 12,
|
|
5213
|
-
overRetrieve: 4
|
|
5219
|
+
overRetrieve: 4,
|
|
5220
|
+
associate: 2,
|
|
5221
|
+
diversity: .3
|
|
5214
5222
|
};
|
|
5215
5223
|
/** Story days for the memory of an unimportant event to halve; each step of importance doubles it. */
|
|
5216
5224
|
const HALF_LIFE_DAYS = 6;
|
|
@@ -5341,7 +5349,7 @@ const DENSE_RANGE = .5;
|
|
|
5341
5349
|
const denseScore = (similarity) => Math.min(1, Math.max(0, (similarity - DENSE_FLOOR) / DENSE_RANGE));
|
|
5342
5350
|
/** Being where something happened calls it to mind, about as much as sharing two words with it. */
|
|
5343
5351
|
const PLACE_CUE = 2;
|
|
5344
|
-
function gather(source, { characterId, characters, situation, locationId }) {
|
|
5352
|
+
function gather(source, { characterId, characters, situation, locationId, about }) {
|
|
5345
5353
|
const names = new Map(characters.map((character) => [character.id, character.name]));
|
|
5346
5354
|
const peers = mentioned(situation, characters);
|
|
5347
5355
|
peers.delete(characterId);
|
|
@@ -5359,24 +5367,46 @@ function gather(source, { characterId, characters, situation, locationId }) {
|
|
|
5359
5367
|
}
|
|
5360
5368
|
const atTurn = (eventTurn) => turns.get(eventTurn) ?? start;
|
|
5361
5369
|
const ageDays = (at) => now === void 0 || at === void 0 ? 0 : Math.max(0, now - at) / DAY$1;
|
|
5362
|
-
|
|
5370
|
+
const concerns = (ids) => about === void 0 || about.length === 0 || ids.some((id) => about.includes(id));
|
|
5371
|
+
return [...source.events.perceivedBy(characterId).filter((seen) => concerns(seen.event.involves)).map((seen) => {
|
|
5363
5372
|
const at = rounds.get(`${seen.event.turn}:${seen.event.round}`) ?? atTurn(seen.event.turn);
|
|
5373
|
+
const cue = {
|
|
5374
|
+
people: peopleCue(seen.event.involves),
|
|
5375
|
+
words: overlap(cues, `${seen.perception.content} ${seen.event.text}`, seen.event.tags),
|
|
5376
|
+
place: locationId !== void 0 && seen.event.locationId === locationId ? PLACE_CUE : 0
|
|
5377
|
+
};
|
|
5364
5378
|
return {
|
|
5365
5379
|
key: `p:${seen.perception.id}`,
|
|
5380
|
+
links: {
|
|
5381
|
+
people: seen.event.involves.filter((id) => id !== characterId),
|
|
5382
|
+
tags: seen.event.tags.map((tag) => tag.toLowerCase()),
|
|
5383
|
+
...seen.event.locationId === void 0 ? {} : { place: seen.event.locationId }
|
|
5384
|
+
},
|
|
5366
5385
|
recalled: describeEvent(seen, names, at),
|
|
5367
|
-
|
|
5386
|
+
cues: cue,
|
|
5387
|
+
relevance: cue.people + cue.words + cue.place,
|
|
5368
5388
|
importance: seen.event.importance,
|
|
5369
5389
|
ageDays: ageDays(at),
|
|
5370
5390
|
recalls: seen.perception.recalls,
|
|
5371
5391
|
seed: seen.perception.id,
|
|
5372
5392
|
durability: 1
|
|
5373
5393
|
};
|
|
5374
|
-
}), ...source.memories.list(characterId).map((belief) => {
|
|
5394
|
+
}), ...source.memories.list(characterId).filter((belief) => concerns(belief.about)).map((belief) => {
|
|
5375
5395
|
const at = atTurn(belief.turn);
|
|
5396
|
+
const cue = {
|
|
5397
|
+
people: peopleCue(belief.about),
|
|
5398
|
+
words: overlap(cues, belief.text, []),
|
|
5399
|
+
place: 0
|
|
5400
|
+
};
|
|
5376
5401
|
return {
|
|
5377
5402
|
key: `m:${belief.id}`,
|
|
5403
|
+
links: {
|
|
5404
|
+
people: belief.about.filter((id) => id !== characterId),
|
|
5405
|
+
tags: []
|
|
5406
|
+
},
|
|
5378
5407
|
recalled: describeBelief(belief, at),
|
|
5379
|
-
|
|
5408
|
+
cues: cue,
|
|
5409
|
+
relevance: cue.people + cue.words,
|
|
5380
5410
|
importance: belief.importance,
|
|
5381
5411
|
ageDays: ageDays(at),
|
|
5382
5412
|
recalls: belief.recalls,
|
|
@@ -5405,20 +5435,25 @@ function fuseScores(searches) {
|
|
|
5405
5435
|
/** How well a candidate stands once its relevance is known: what the moment calls to mind, how much it matters and how recent it is. */
|
|
5406
5436
|
function judged(candidate, relevance, policy) {
|
|
5407
5437
|
let clarity = "clear";
|
|
5408
|
-
|
|
5409
|
-
|
|
5410
|
-
|
|
5411
|
-
|
|
5412
|
-
|
|
5413
|
-
|
|
5414
|
-
|
|
5415
|
-
|
|
5438
|
+
let kept;
|
|
5439
|
+
if (policy.flaky) {
|
|
5440
|
+
kept = retention({
|
|
5441
|
+
ageDays: candidate.ageDays,
|
|
5442
|
+
importance: candidate.importance,
|
|
5443
|
+
recalls: candidate.recalls,
|
|
5444
|
+
seed: candidate.seed,
|
|
5445
|
+
durability: candidate.durability,
|
|
5446
|
+
cue: relevance >= CUE_RELEVANCE
|
|
5447
|
+
});
|
|
5448
|
+
clarity = clarityAt(kept, candidate.importance);
|
|
5449
|
+
}
|
|
5416
5450
|
if (clarity === void 0) return void 0;
|
|
5417
5451
|
const score = RELEVANCE_SCALE * relevance + .6 * candidate.importance + 2 / (1 + Math.max(0, candidate.ageDays)) + (clarity === "vague" ? -1 : 0);
|
|
5418
5452
|
return {
|
|
5419
5453
|
clarity,
|
|
5420
5454
|
score,
|
|
5421
|
-
text: candidate.recalled[clarity === "clear" ? "clear" : clarity === "faded" ? "faded" : "vague"]
|
|
5455
|
+
text: candidate.recalled[clarity === "clear" ? "clear" : clarity === "faded" ? "faded" : "vague"],
|
|
5456
|
+
...kept === void 0 ? {} : { retention: kept }
|
|
5422
5457
|
};
|
|
5423
5458
|
}
|
|
5424
5459
|
/**
|
|
@@ -5429,7 +5464,7 @@ function judged(candidate, relevance, policy) {
|
|
|
5429
5464
|
* is, and not what has faded from memory altogether). A reranker may then judge that pool.
|
|
5430
5465
|
*/
|
|
5431
5466
|
function recallPool(source, query, evidence = {}) {
|
|
5432
|
-
const { policy } = query;
|
|
5467
|
+
const { policy, explain } = query;
|
|
5433
5468
|
const candidates = gather(source, query);
|
|
5434
5469
|
const fused = fuseScores([
|
|
5435
5470
|
{
|
|
@@ -5446,18 +5481,28 @@ function recallPool(source, query, evidence = {}) {
|
|
|
5446
5481
|
}
|
|
5447
5482
|
]);
|
|
5448
5483
|
const width = Math.min(MAX_POOL, Math.max(policy.recall, Math.ceil(policy.recall * Math.max(1, policy.overRetrieve ?? 1))));
|
|
5484
|
+
const entries = candidates.map((candidate) => ({
|
|
5485
|
+
candidate,
|
|
5486
|
+
fused: fused.get(candidate.key) ?? 0,
|
|
5487
|
+
found: {
|
|
5488
|
+
...evidence.lexical?.get(candidate.key) === void 0 ? {} : { lexical: evidence.lexical.get(candidate.key) },
|
|
5489
|
+
...evidence.dense?.get(candidate.key) === void 0 ? {} : { dense: evidence.dense.get(candidate.key) }
|
|
5490
|
+
}
|
|
5491
|
+
})).flatMap((entry) => {
|
|
5492
|
+
const standing = judged(entry.candidate, entry.fused, policy);
|
|
5493
|
+
return standing === void 0 ? [] : [{
|
|
5494
|
+
entry,
|
|
5495
|
+
score: standing.score
|
|
5496
|
+
}];
|
|
5497
|
+
}).sort((a, b) => b.score - a.score || b.entry.candidate.recalled.turn - a.entry.candidate.recalled.turn).map(({ entry }) => entry).slice(0, width);
|
|
5498
|
+
const kept = new Set(entries.map((entry) => entry.candidate.key));
|
|
5449
5499
|
return {
|
|
5450
|
-
entries
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
|
|
5456
|
-
entry,
|
|
5457
|
-
score: standing.score
|
|
5458
|
-
}];
|
|
5459
|
-
}).sort((a, b) => b.score - a.score || b.entry.candidate.recalled.turn - a.entry.candidate.recalled.turn).slice(0, width).map(({ entry }) => entry),
|
|
5460
|
-
query: { policy }
|
|
5500
|
+
entries,
|
|
5501
|
+
others: candidates.filter((candidate) => !kept.has(candidate.key)),
|
|
5502
|
+
query: {
|
|
5503
|
+
policy,
|
|
5504
|
+
...explain === true ? { explain } : {}
|
|
5505
|
+
}
|
|
5461
5506
|
};
|
|
5462
5507
|
}
|
|
5463
5508
|
/** What a reranker is asked to judge: every candidate of the pool, with the text it would be recalled by. */
|
|
@@ -5469,26 +5514,129 @@ function poolCandidates(pool) {
|
|
|
5469
5514
|
importance: candidate.importance
|
|
5470
5515
|
}));
|
|
5471
5516
|
}
|
|
5517
|
+
/** Two things are tied by the same people, the same tags and the same place; this is how strongly (people count most, tags and place add a little). */
|
|
5518
|
+
function tie(a, b) {
|
|
5519
|
+
const people = a.people.filter((id) => b.people.includes(id)).length;
|
|
5520
|
+
const tags = a.tags.filter((tag) => b.tags.includes(tag)).length;
|
|
5521
|
+
const place = a.place !== void 0 && a.place === b.place;
|
|
5522
|
+
return {
|
|
5523
|
+
strength: 2 * Math.min(people, 2) + Math.min(tags, 2) + (place ? 1 : 0),
|
|
5524
|
+
people,
|
|
5525
|
+
tags,
|
|
5526
|
+
place
|
|
5527
|
+
};
|
|
5528
|
+
}
|
|
5529
|
+
/** The least a tie has to be for one thing to bring the other to mind. */
|
|
5530
|
+
const STRONG_TIE = 3;
|
|
5531
|
+
/** What does not matter much is not brought back by association. */
|
|
5532
|
+
const ASSOCIABLE_IMPORTANCE = 3;
|
|
5533
|
+
/** How much two texts say the same, from 0 to 1: the share of their words (or pairs of characters) they have in common. */
|
|
5534
|
+
function resemblance(a, b) {
|
|
5535
|
+
if (a.size === 0 || b.size === 0) return 0;
|
|
5536
|
+
let shared = 0;
|
|
5537
|
+
for (const word of a) if (b.has(word)) shared++;
|
|
5538
|
+
return shared / (a.size + b.size - shared);
|
|
5539
|
+
}
|
|
5540
|
+
/**
|
|
5541
|
+
* Choose `count` of the ranked entries by maximal marginal relevance: each pick is the one with the best score
|
|
5542
|
+
* discounted by how much it resembles what is already chosen, so that three memories of the same moment do not
|
|
5543
|
+
* crowd out one of another. `diversity` 0 keeps the ranking as it is.
|
|
5544
|
+
*/
|
|
5545
|
+
function diversified(ranked, count, diversity) {
|
|
5546
|
+
const weight = Math.min(1, Math.max(0, diversity));
|
|
5547
|
+
if (weight === 0 || ranked.length <= 1) return ranked.slice(0, count);
|
|
5548
|
+
const top = Math.max(...ranked.map((entry) => entry.score), Number.EPSILON);
|
|
5549
|
+
const words = new Map(ranked.map((entry) => [entry, tokens(entry.candidate.recalled.clear)]));
|
|
5550
|
+
const left = [...ranked];
|
|
5551
|
+
const chosen = [];
|
|
5552
|
+
while (chosen.length < count && left.length > 0) {
|
|
5553
|
+
let best = 0;
|
|
5554
|
+
let bestValue = -Infinity;
|
|
5555
|
+
left.forEach((entry, index) => {
|
|
5556
|
+
const repeat = Math.max(0, ...chosen.map((picked) => resemblance(words.get(entry), words.get(picked))));
|
|
5557
|
+
const value = (1 - weight) * Math.max(0, entry.score) / top - weight * repeat;
|
|
5558
|
+
if (value > bestValue) {
|
|
5559
|
+
best = index;
|
|
5560
|
+
bestValue = value;
|
|
5561
|
+
}
|
|
5562
|
+
});
|
|
5563
|
+
chosen.push(left.splice(best, 1)[0]);
|
|
5564
|
+
}
|
|
5565
|
+
return chosen;
|
|
5566
|
+
}
|
|
5472
5567
|
/**
|
|
5473
|
-
* The last stage: choose the `policy.recall` best of the pool. With a reranker's judgement each
|
|
5568
|
+
* The last stage: choose the `policy.recall` best of the pool, spread by `policy.diversity`. With a reranker's judgement each
|
|
5474
5569
|
* candidate's relevance is mostly that (a candidate it left out counts as 0), and the rest is what
|
|
5475
5570
|
* retrieval found; without, it is what retrieval found.
|
|
5476
5571
|
*/
|
|
5477
5572
|
function finishRecall(pool, rerank) {
|
|
5478
5573
|
const { policy } = pool.query;
|
|
5479
|
-
|
|
5480
|
-
const
|
|
5481
|
-
|
|
5574
|
+
const standing = pool.entries.flatMap(({ candidate, fused, found }) => {
|
|
5575
|
+
const relevance = rerank === void 0 ? fused : RERANK_BLEND * Math.min(1, Math.max(0, rerank.get(candidate.key) ?? 0)) + .30000000000000004 * fused;
|
|
5576
|
+
const judgement = judged(candidate, relevance, policy);
|
|
5577
|
+
if (judgement === void 0) return [];
|
|
5578
|
+
const why = pool.query.explain === true ? {
|
|
5579
|
+
cues: candidate.cues,
|
|
5580
|
+
...found,
|
|
5581
|
+
...rerank === void 0 ? {} : { rerank: rerank.get(candidate.key) ?? 0 },
|
|
5582
|
+
relevance,
|
|
5583
|
+
importance: candidate.importance,
|
|
5584
|
+
ageDays: candidate.ageDays,
|
|
5585
|
+
...judgement.retention === void 0 ? {} : { retention: judgement.retention },
|
|
5586
|
+
score: judgement.score
|
|
5587
|
+
} : void 0;
|
|
5588
|
+
return [{
|
|
5482
5589
|
candidate,
|
|
5483
|
-
|
|
5590
|
+
relevance,
|
|
5591
|
+
...judgement,
|
|
5592
|
+
why
|
|
5484
5593
|
}];
|
|
5485
|
-
}).sort((a, b) => b.score - a.score || b.candidate.recalled.turn - a.candidate.recalled.turn)
|
|
5594
|
+
}).sort((a, b) => b.score - a.score || b.candidate.recalled.turn - a.candidate.recalled.turn);
|
|
5595
|
+
const chosen = diversified(standing, policy.recall, policy.diversity ?? 0);
|
|
5596
|
+
const result = chosen.map(({ candidate, clarity, text, why }) => ({
|
|
5486
5597
|
clarity,
|
|
5487
5598
|
text,
|
|
5488
5599
|
turn: candidate.recalled.turn,
|
|
5489
5600
|
...candidate.recalled.at === void 0 ? {} : { at: candidate.recalled.at },
|
|
5490
|
-
source: candidate.recalled.source
|
|
5601
|
+
source: candidate.recalled.source,
|
|
5602
|
+
...why === void 0 ? {} : { why }
|
|
5491
5603
|
}));
|
|
5604
|
+
const anchors = chosen.filter((entry) => entry.relevance >= CUE_RELEVANCE);
|
|
5605
|
+
const wanted = anchors.length === 0 ? 0 : Math.max(0, policy.associate ?? 0);
|
|
5606
|
+
if (wanted > 0) {
|
|
5607
|
+
const taken = new Set(chosen.map((entry) => entry.candidate.key));
|
|
5608
|
+
const tied = [...standing.filter((entry) => !chosen.includes(entry)).map((entry) => entry.candidate), ...pool.others].filter((candidate) => !taken.has(candidate.key) && candidate.importance >= ASSOCIABLE_IMPORTANCE).flatMap((candidate) => {
|
|
5609
|
+
const best = anchors.map((anchor) => tie(anchor.candidate.links, candidate.links)).sort((a, b) => b.strength - a.strength)[0];
|
|
5610
|
+
const judgement = best === void 0 || best.strength < STRONG_TIE ? void 0 : judged(candidate, 0, policy);
|
|
5611
|
+
return best === void 0 || judgement === void 0 || judgement.clarity === "vague" ? [] : [{
|
|
5612
|
+
candidate,
|
|
5613
|
+
best,
|
|
5614
|
+
judgement
|
|
5615
|
+
}];
|
|
5616
|
+
}).sort((a, b) => b.best.strength - a.best.strength || b.candidate.importance - a.candidate.importance || b.candidate.recalled.turn - a.candidate.recalled.turn).slice(0, wanted);
|
|
5617
|
+
for (const { candidate, best, judgement } of tied) result.push({
|
|
5618
|
+
clarity: judgement.clarity,
|
|
5619
|
+
text: judgement.text,
|
|
5620
|
+
turn: candidate.recalled.turn,
|
|
5621
|
+
...candidate.recalled.at === void 0 ? {} : { at: candidate.recalled.at },
|
|
5622
|
+
source: candidate.recalled.source,
|
|
5623
|
+
linked: true,
|
|
5624
|
+
...pool.query.explain === true ? { why: {
|
|
5625
|
+
cues: candidate.cues,
|
|
5626
|
+
relevance: 0,
|
|
5627
|
+
importance: candidate.importance,
|
|
5628
|
+
ageDays: candidate.ageDays,
|
|
5629
|
+
...judgement.retention === void 0 ? {} : { retention: judgement.retention },
|
|
5630
|
+
score: judgement.score,
|
|
5631
|
+
linked: {
|
|
5632
|
+
people: best.people,
|
|
5633
|
+
tags: best.tags,
|
|
5634
|
+
place: best.place
|
|
5635
|
+
}
|
|
5636
|
+
} } : {}
|
|
5637
|
+
});
|
|
5638
|
+
}
|
|
5639
|
+
return result.sort((a, b) => a.turn - b.turn);
|
|
5492
5640
|
}
|
|
5493
5641
|
/** Remind a character of what the moment calls to mind, in one call: {@link recallPool}, then {@link finishRecall} with the `rerank` evidence if there is any. */
|
|
5494
5642
|
function recall(source, query, evidence = {}) {
|
|
@@ -9169,6 +9317,7 @@ function openSessionStore(location, options = {}) {
|
|
|
9169
9317
|
try {
|
|
9170
9318
|
const state = inspect(db);
|
|
9171
9319
|
if (state.version === 0 || state.applicationId !== 1146245971) throw new SchemaError(`${location} is not a session database`);
|
|
9320
|
+
if (state.version < LATEST_VERSION && location !== ":memory:") backUpBeforeMigrating(db, location, state.version);
|
|
9172
9321
|
migrate(db);
|
|
9173
9322
|
return new SqliteSessionStore(db, options.clock ?? systemClock, vectors);
|
|
9174
9323
|
} catch (error) {
|
|
@@ -9176,6 +9325,24 @@ function openSessionStore(location, options = {}) {
|
|
|
9176
9325
|
throw error;
|
|
9177
9326
|
}
|
|
9178
9327
|
}
|
|
9328
|
+
/** Folder, beside the database, holding the copies made before a schema upgrade. */
|
|
9329
|
+
const MIGRATION_BACKUP_FOLDER = "migration-backups";
|
|
9330
|
+
/** Where the copy of a database as it was at schema `version` is kept. */
|
|
9331
|
+
function migrationBackupPath(location, version) {
|
|
9332
|
+
return join(dirname(location), MIGRATION_BACKUP_FOLDER, `schema-${version}.sqlite`);
|
|
9333
|
+
}
|
|
9334
|
+
/**
|
|
9335
|
+
* A released session cannot be rebuilt, so an upgrade starts from a copy that passed the integrity check; one copy per old version is kept.
|
|
9336
|
+
* @throws {CorruptDataError} when the database is damaged, before anything is changed.
|
|
9337
|
+
*/
|
|
9338
|
+
function backUpBeforeMigrating(db, location, version) {
|
|
9339
|
+
const check = db.get("PRAGMA quick_check")?.quick_check;
|
|
9340
|
+
if (check !== "ok") throw new CorruptDataError(`${location} failed its integrity check, so it was not upgraded: ${check ?? "no result"}`);
|
|
9341
|
+
const target = migrationBackupPath(location, version);
|
|
9342
|
+
if (existsSync(target)) return;
|
|
9343
|
+
mkdirSync(dirname(target), { recursive: true });
|
|
9344
|
+
db.run("VACUUM INTO ?", [target]);
|
|
9345
|
+
}
|
|
9179
9346
|
//#endregion
|
|
9180
9347
|
//#region src/sessions.ts
|
|
9181
9348
|
const SESSION_DATABASE_FILE = "session.sqlite";
|
|
@@ -11192,11 +11359,17 @@ function createCharacterTools(link, characterId) {
|
|
|
11192
11359
|
defineTool({
|
|
11193
11360
|
name: "recall_my_memories",
|
|
11194
11361
|
description: "Ask yourself what you remember about something: a person, an object, a place or an earlier moment. You get your own version of it, what you took in yourself and what you believe, and what has faded comes back as hazy or not at all. Use it only when you need a memory that the situation does not already give you.",
|
|
11195
|
-
parameters: {
|
|
11196
|
-
|
|
11197
|
-
|
|
11198
|
-
|
|
11199
|
-
|
|
11362
|
+
parameters: {
|
|
11363
|
+
about: {
|
|
11364
|
+
type: "string",
|
|
11365
|
+
required: true,
|
|
11366
|
+
description: "What to remember: a name, an object, a topic or a short description of the moment."
|
|
11367
|
+
},
|
|
11368
|
+
person: {
|
|
11369
|
+
type: "string",
|
|
11370
|
+
description: "Only what concerns this person (a name or alias you know): everything you remember of them."
|
|
11371
|
+
}
|
|
11372
|
+
},
|
|
11200
11373
|
output: {
|
|
11201
11374
|
schema: {
|
|
11202
11375
|
type: "array",
|
|
@@ -11221,20 +11394,24 @@ function createCharacterTools(link, characterId) {
|
|
|
11221
11394
|
},
|
|
11222
11395
|
render: (_args, value) => [{
|
|
11223
11396
|
type: "text",
|
|
11224
|
-
text: value.length === 0 ? "You do not remember anything about that." : value.map((entry) => `- (${entry.clarity === "clear" ? "" : entry.clarity === "faded" ? "the details are fuzzy" : "you barely remember"}) ${entry.text}`.replace("- () ", "- ")).join("\n")
|
|
11397
|
+
text: value.length === 0 ? "You do not remember anything about that, and there is nothing more to find: go on with what you know." : value.map((entry) => `- (${entry.clarity === "clear" ? "" : entry.clarity === "faded" ? "the details are fuzzy" : "you barely remember"}) ${entry.text}`.replace("- () ", "- ")).join("\n")
|
|
11225
11398
|
}]
|
|
11226
11399
|
},
|
|
11227
11400
|
isConcurrencySafe: () => false,
|
|
11228
11401
|
async execute(args, exec) {
|
|
11229
11402
|
const agent = link();
|
|
11230
11403
|
const { session, turn, policy } = agent;
|
|
11404
|
+
const who = args.person === void 0 || args.person.trim() === "" ? [] : [...mentioned(args.person, session.characters.list())].filter((id) => id !== characterId);
|
|
11405
|
+
if (args.person !== void 0 && args.person.trim() !== "" && who.length === 0) return [];
|
|
11406
|
+
const situation = who.length === 0 ? args.about : `${args.about} ${args.person}`;
|
|
11231
11407
|
return (await session.recallRanked({
|
|
11232
11408
|
characterId,
|
|
11233
|
-
situation
|
|
11409
|
+
situation,
|
|
11234
11410
|
turn,
|
|
11235
11411
|
policy,
|
|
11412
|
+
...who.length === 0 ? {} : { about: who },
|
|
11236
11413
|
...placeOf(session, characterId)
|
|
11237
|
-
}, exec.signal, await vectorOf(agent,
|
|
11414
|
+
}, exec.signal, await vectorOf(agent, situation, exec.signal))).map((entry) => ({
|
|
11238
11415
|
clarity: entry.clarity,
|
|
11239
11416
|
turn: entry.turn,
|
|
11240
11417
|
text: entry.text
|
|
@@ -11272,7 +11449,7 @@ function createCharacterTools(link, characterId) {
|
|
|
11272
11449
|
},
|
|
11273
11450
|
render: (_args, value) => [{
|
|
11274
11451
|
type: "text",
|
|
11275
|
-
text: value.length === 0 ? "You know of nothing matching that." : value.map((entry) => `- ${entry.kind}: ${entry.name}
|
|
11452
|
+
text: value.length === 0 ? "You know of nothing matching that." : value.map((entry) => `- ${entry.kind}: ${entry.name}`).join("\n")
|
|
11276
11453
|
}]
|
|
11277
11454
|
},
|
|
11278
11455
|
isConcurrencySafe: () => true,
|
|
@@ -11383,6 +11560,6 @@ function createCharacterTools(link, characterId) {
|
|
|
11383
11560
|
];
|
|
11384
11561
|
}
|
|
11385
11562
|
//#endregion
|
|
11386
|
-
export { ACCURACIES, CHARACTER_CONTROLS, CHARACTER_KINDS, CHARACTER_ROLES, CHARACTER_TIERS, CLOCK_MODES, COMPARISONS, CONSOLIDATION_KINDS, CONTAINER_STATES, Config, ConflictError, CorruptDataError, DAY, DAY_PARTS, DEFAULT_MEMORY_POLICY, DEFAULT_SLOTS, EMOTION_VARIABLES, ENGAGEMENT_GRACE, ENGAGEMENT_STATUSES, EXIT_STATES, HOUR, IMPORTANCE_MAX, IMPORTANCE_MIN, INTENT_HORIZONS, INTENT_STATUSES, INTENT_TYPES, ITEM_ACTIONS, InvalidEditError, InvalidMoveError, InvalidValueError, KNOWLEDGE_KINDS, LORE_KINDS, LORE_SUBJECT_KINDS, MAX_LOCATION_FEATURES, MAX_ROUTINE_WINDOWS, MAX_SHOWN, MAX_TRIGGERS, MAX_VARIABLES, MEMBERSHIP_STATUSES, MEMORY_KINDS, MINUTE, NotFoundError, PERCEPTION_MODES, PLACEABLE_KINDS, PLOT_NUDGE_MODES, PLOT_STATUSES, RECALL_ITEM_KINDS, RoleplayState, LATEST_VERSION as SCHEMA_VERSION, SECOND, SESSION_DATABASE_FILE, SLOT_ID, SUMMARY_LEVELS, SchemaError, StateError, THREAD_STATUSES, TIME_CHANGE_KINDS, TRIGGER_NOTE_KINDS, TRIGGER_STATUSES, VARIABLE_KEY, VARIABLE_KINDS, VARIABLE_SUBJECTS, VARIABLE_VISIBILITIES, VISUAL_SUBJECT_KINDS, WEEKDAY_NAMES, addLocalDays, agendaAt, announcements, apply, applyItemPlan, applyRecordsEdit, audienceIds, catchUpPlan, changeItem, changeVariable, characterKey, clarityAt, clockTime, conditionHolds, createCharacterTools, createSession, createSessionStore, createTools, dayPart, deleteSession, denseScore, describeDuration, describeHolder, describeInstant, describeValue, finishRecall, fuseScores, inAudience, inWindow, isSessionId, isTimeZone, itemKey, jitter, judgedStatements, lapseNotes, lintWorld, listSessions, localIso, localTime, locationKey, mentioned, moveCharacter, name, nextOccurrence, nextTimeOfDay, nodeSqliteDriver, occurrenceAt, openSession, openSessionStore, overlap, parseInstant, parseRecordsEdit, parseTimeOfDay, parseTriggerDefinition, planItemChange, planKnownMove, planMove, planVariableChange, poolCandidates, rankGoals, readRecords, readTriggerDefinition, recall, recallCandidates, recallPool, recordsEditSchema, retention, runTriggers, seededRoll, sessionDatabase, sessionFolder, shownVariables, subjectOf, systemClock, systemTimeZone, tokens, triggerReferenceProblems, valueIssue, zonedInstant };
|
|
11563
|
+
export { ACCURACIES, CHARACTER_CONTROLS, CHARACTER_KINDS, CHARACTER_ROLES, CHARACTER_TIERS, CLOCK_MODES, COMPARISONS, CONSOLIDATION_KINDS, CONTAINER_STATES, Config, ConflictError, CorruptDataError, DAY, DAY_PARTS, DEFAULT_MEMORY_POLICY, DEFAULT_SLOTS, EMOTION_VARIABLES, ENGAGEMENT_GRACE, ENGAGEMENT_STATUSES, EXIT_STATES, HOUR, IMPORTANCE_MAX, IMPORTANCE_MIN, INTENT_HORIZONS, INTENT_STATUSES, INTENT_TYPES, ITEM_ACTIONS, InvalidEditError, InvalidMoveError, InvalidValueError, KNOWLEDGE_KINDS, LORE_KINDS, LORE_SUBJECT_KINDS, MAX_LOCATION_FEATURES, MAX_ROUTINE_WINDOWS, MAX_SHOWN, MAX_TRIGGERS, MAX_VARIABLES, MEMBERSHIP_STATUSES, MEMORY_KINDS, MIGRATION_BACKUP_FOLDER, MINUTE, NotFoundError, PERCEPTION_MODES, PLACEABLE_KINDS, PLOT_NUDGE_MODES, PLOT_STATUSES, RECALL_ITEM_KINDS, RoleplayState, LATEST_VERSION as SCHEMA_VERSION, SECOND, SESSION_DATABASE_FILE, SLOT_ID, SUMMARY_LEVELS, SchemaError, StateError, THREAD_STATUSES, TIME_CHANGE_KINDS, TRIGGER_NOTE_KINDS, TRIGGER_STATUSES, VARIABLE_KEY, VARIABLE_KINDS, VARIABLE_SUBJECTS, VARIABLE_VISIBILITIES, VISUAL_SUBJECT_KINDS, WEEKDAY_NAMES, addLocalDays, agendaAt, announcements, apply, applyItemPlan, applyRecordsEdit, audienceIds, catchUpPlan, changeItem, changeVariable, characterKey, clarityAt, clockTime, conditionHolds, createCharacterTools, createSession, createSessionStore, createTools, dayPart, deleteSession, denseScore, describeDuration, describeHolder, describeInstant, describeValue, finishRecall, fuseScores, inAudience, inWindow, isSessionId, isTimeZone, itemKey, jitter, judgedStatements, lapseNotes, lintWorld, listSessions, localIso, localTime, locationKey, mentioned, migrationBackupPath, moveCharacter, name, nextOccurrence, nextTimeOfDay, nodeSqliteDriver, occurrenceAt, openSession, openSessionStore, overlap, parseInstant, parseRecordsEdit, parseTimeOfDay, parseTriggerDefinition, planItemChange, planKnownMove, planMove, planVariableChange, poolCandidates, rankGoals, readRecords, readTriggerDefinition, recall, recallCandidates, recallPool, recordsEditSchema, retention, runTriggers, seededRoll, sessionDatabase, sessionFolder, shownVariables, subjectOf, systemClock, systemTimeZone, tokens, triggerReferenceProblems, valueIssue, zonedInstant };
|
|
11387
11564
|
|
|
11388
11565
|
//# sourceMappingURL=index.js.map
|