@medicine-wheel/memory 0.16.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.
- package/README.md +76 -0
- package/dist/index.d.ts +222 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +240 -0
- package/dist/index.js.map +1 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# @medicine-wheel/memory
|
|
2
|
+
|
|
3
|
+
Asking the wheel's memory, whoever keeps it. The wheel records ceremonies, turns and diary entries. A memory provider (Honcho today, through `@medicine-wheel/honcho`) receives them and reasons over them. A caller asks the **wheel**, never the provider: it names a scope, the wheel turns it into the ceremonies it covers, and every provider is kept inside that reach. Every source in an answer is a wheel record, or is marked as coming from outside the wheel.
|
|
4
|
+
|
|
5
|
+
This package holds what does not depend on the provider. It has no dependencies.
|
|
6
|
+
|
|
7
|
+
## The contract
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
interface MemoryScope { // every field adds ceremonies; the reach is their union
|
|
11
|
+
ceremonies?: string | string[];
|
|
12
|
+
subject_id?: string | string[]; // ceremonies held about a node: a review, a PDE (pde:<uuid>)
|
|
13
|
+
circle_id?: string | string[];
|
|
14
|
+
episode_path?: string | string[];
|
|
15
|
+
participant?: string; // where this person was seated: participant, circle member, facilitator
|
|
16
|
+
exclude_ceremonies?: string[]; // removed last, e.g. a PDE's own ceremony
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface MemoryAnswer {
|
|
20
|
+
provider: string; // 'honcho', or 'wheel' when only the wheel's own records answered
|
|
21
|
+
mode: 'dialectic' | 'search' | 'matched' | 'empty';
|
|
22
|
+
answer?: string; // dialectic only
|
|
23
|
+
sources: MemorySource[];
|
|
24
|
+
reach: { scope; ceremonies: string[]; episodes: string[] };
|
|
25
|
+
note?: string; // why a fallback answered
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface MemorySource {
|
|
29
|
+
provider: string; // who produced this source
|
|
30
|
+
wheel_kind: string; // beat | diary | ceremony | message (outside the wheel)
|
|
31
|
+
wheel_id: string;
|
|
32
|
+
ceremony_id?: string;
|
|
33
|
+
speaker?: string; // a wheel id
|
|
34
|
+
speaker_name?: string;
|
|
35
|
+
excerpt: string; // person ids replaced with names
|
|
36
|
+
at?: string;
|
|
37
|
+
outside_wheel?: boolean;
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
A scope with no field reaches nothing. The whole wheel is never the default.
|
|
42
|
+
|
|
43
|
+
| mode | meaning |
|
|
44
|
+
| --- | --- |
|
|
45
|
+
| `dialectic` | a provider reasoned over the reach |
|
|
46
|
+
| `search` | a provider returned the closest records without reasoning, because it cannot keep its reasoning inside a reach or was not asked to reason |
|
|
47
|
+
| `matched` | no provider answered, and the wheel matched its own records on their words |
|
|
48
|
+
| `empty` | the reach holds nothing, and nothing was asked |
|
|
49
|
+
|
|
50
|
+
## Using it
|
|
51
|
+
|
|
52
|
+
A wheel server builds one memory from its store and its providers:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { createMemory } from '@medicine-wheel/memory';
|
|
56
|
+
import { createHonchoClient, honchoFromEnv, honchoMemoryProvider } from '@medicine-wheel/honcho';
|
|
57
|
+
|
|
58
|
+
const memory = createMemory({
|
|
59
|
+
wheel, // MemoryWheel: ceremonies(), seats(), records(reach), names(ids)
|
|
60
|
+
providers: [honchoMemoryProvider(createHonchoClient(honchoFromEnv()!))],
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
await memory.ask({ question: 'What is still unresolved?', scope: { circle_id: 'circle:…' } });
|
|
64
|
+
await memory.search({ query: 'lantern', scope: { subject_id: 'pde:…', exclude_ceremonies: ['…'] } });
|
|
65
|
+
await memory.about({ person: 'node:human:…', scope: { participant: 'node:human:…' } });
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Providers are tried in order. The first that answers gives the answer, and the wheel's own matches are added after its sources. When every provider fails, the wheel's records answer in `matched` mode with a `note`.
|
|
69
|
+
|
|
70
|
+
Everyone else asks a wheel over HTTP (`POST /api/memory/ask`, `/search`, `/about`, `GET /api/memory`), through `@medicine-wheel/client` (`wheel.memory.ask(…)`), or through the MCP tools `memory_ask`, `memory_search`, `memory_about`, `memory_status`, `memory_conclude` and `memory_resend`.
|
|
71
|
+
|
|
72
|
+
Also exported: `resolveReach` (scope to ceremonies), `matchRecords` and `queryTerms` (the text match), `excerptAround`, `isEmptyScope`.
|
|
73
|
+
|
|
74
|
+
## Who decides who may ask
|
|
75
|
+
|
|
76
|
+
The wheel keeps an answer inside the scope it is given. Deciding who may name which scope stays with the caller. Miadi, for example, builds the scope from the circles a person sits in.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @medicine-wheel/memory — asking the wheel's memory, whoever keeps it.
|
|
3
|
+
*
|
|
4
|
+
* The wheel is canonical: ceremonies, turns (beats) and diary entries are
|
|
5
|
+
* recorded there. A memory provider (Honcho today) receives them and reasons
|
|
6
|
+
* over them. A caller asks the wheel, never the provider: it names a scope, the
|
|
7
|
+
* wheel turns the scope into the ceremonies it covers, and every provider is
|
|
8
|
+
* confined to that reach. Every source in an answer is a wheel record, or is
|
|
9
|
+
* marked as coming from outside the wheel.
|
|
10
|
+
*
|
|
11
|
+
* This package holds what does not depend on who keeps the memory: the
|
|
12
|
+
* contract, the rule that turns a scope into ceremonies, a text match over the
|
|
13
|
+
* wheel's own records (the provider that is always present), and the
|
|
14
|
+
* orchestration a wheel server and any other caller share. It has no
|
|
15
|
+
* dependencies. jgwill/medicine-wheel#149
|
|
16
|
+
*/
|
|
17
|
+
/** One value or several. */
|
|
18
|
+
export type OneOrMany = string | string[];
|
|
19
|
+
/**
|
|
20
|
+
* What a question may reach. Every field adds ceremonies and the reach is their
|
|
21
|
+
* union, less `exclude_ceremonies`. A scope with no field reaches nothing: the
|
|
22
|
+
* whole wheel is never the default.
|
|
23
|
+
*/
|
|
24
|
+
export interface MemoryScope {
|
|
25
|
+
/** Ceremony ids, reached as named. */
|
|
26
|
+
ceremonies?: OneOrMany;
|
|
27
|
+
/** Ceremonies held about these nodes (`CeremonyLog.subject_id`): a review, a PDE. */
|
|
28
|
+
subject_id?: OneOrMany;
|
|
29
|
+
/** Ceremonies held in these circles. */
|
|
30
|
+
circle_id?: OneOrMany;
|
|
31
|
+
/** Ceremonies bound to these chronicle episodes, and diary entries kept against them. */
|
|
32
|
+
episode_path?: OneOrMany;
|
|
33
|
+
/** Ceremonies where this person was seated: a participant, or a member or the facilitator of its circle. */
|
|
34
|
+
participant?: string;
|
|
35
|
+
/** Removed from the reach last, so a PDE's own ceremony is not cited as the answer to its own questions. */
|
|
36
|
+
exclude_ceremonies?: string[];
|
|
37
|
+
}
|
|
38
|
+
/** What a scope resolved to on this wheel. */
|
|
39
|
+
export interface Reach {
|
|
40
|
+
scope: MemoryScope;
|
|
41
|
+
/** Ceremony ids, with the closing records of the ceremonies reached. */
|
|
42
|
+
ceremonies: string[];
|
|
43
|
+
/** Episode paths the scope names: diary entries kept against an episode rather than a ceremony. */
|
|
44
|
+
episodes: string[];
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* `dialectic`: a provider reasoned over the reach. `search`: a provider found
|
|
48
|
+
* the closest records without reasoning (it could not confine its reasoning, or
|
|
49
|
+
* reasoning was not asked for). `matched`: the wheel's own records matched on
|
|
50
|
+
* their words, with no provider. `empty`: the reach holds nothing, and nothing
|
|
51
|
+
* was asked.
|
|
52
|
+
*/
|
|
53
|
+
export type MemoryMode = 'dialectic' | 'search' | 'matched' | 'empty';
|
|
54
|
+
/** One thing an answer rests on. */
|
|
55
|
+
export interface MemorySource {
|
|
56
|
+
/** Who produced this source: `wheel` for the records match, or a provider's name. */
|
|
57
|
+
provider: string;
|
|
58
|
+
/** `beat`, `diary`, `ceremony`, or `message` for a source outside the wheel. */
|
|
59
|
+
wheel_kind: string;
|
|
60
|
+
/** The wheel record's id, or the provider's own id when `outside_wheel`. */
|
|
61
|
+
wheel_id: string;
|
|
62
|
+
/** The ceremony the record belongs to, when it belongs to one. */
|
|
63
|
+
ceremony_id?: string;
|
|
64
|
+
/** Who spoke or wrote it, as a wheel id when known. */
|
|
65
|
+
speaker?: string;
|
|
66
|
+
/** The speaker's name, resolved by the wheel. */
|
|
67
|
+
speaker_name?: string;
|
|
68
|
+
/** The words, shortened around what matched. Wheel person ids are replaced with names. */
|
|
69
|
+
excerpt: string;
|
|
70
|
+
/** When it was recorded. */
|
|
71
|
+
at?: string;
|
|
72
|
+
/** The provider holds it, but it carries no wheel record: it was written into the provider directly. */
|
|
73
|
+
outside_wheel?: boolean;
|
|
74
|
+
}
|
|
75
|
+
export interface MemoryAnswer {
|
|
76
|
+
/** The provider that answered, or `wheel` when only the records match did. */
|
|
77
|
+
provider: string;
|
|
78
|
+
mode: MemoryMode;
|
|
79
|
+
/** A reasoned answer, in `dialectic` mode only. */
|
|
80
|
+
answer?: string;
|
|
81
|
+
sources: MemorySource[];
|
|
82
|
+
reach: Reach;
|
|
83
|
+
/** Why the answer came from a fallback, when it did. */
|
|
84
|
+
note?: string;
|
|
85
|
+
}
|
|
86
|
+
/** A question as a provider receives it: the reach is already resolved. */
|
|
87
|
+
export interface MemoryQuestion {
|
|
88
|
+
query: string;
|
|
89
|
+
reach: Reach;
|
|
90
|
+
/** Whose memory is asked. A provider picks its own default. */
|
|
91
|
+
peer?: string;
|
|
92
|
+
/** For `about`: the wheel id of the person the question is about. */
|
|
93
|
+
about?: string;
|
|
94
|
+
/** `minimal` | `low` | `medium` | `high` | `max`. */
|
|
95
|
+
reasoning_level?: string;
|
|
96
|
+
/** How many sources at most. */
|
|
97
|
+
limit?: number;
|
|
98
|
+
}
|
|
99
|
+
/** A provider's part of an answer; the wheel adds the reach. */
|
|
100
|
+
export type ProviderAnswer = Omit<MemoryAnswer, 'reach'>;
|
|
101
|
+
export interface MemoryProviderStatus {
|
|
102
|
+
provider: string;
|
|
103
|
+
/** Configured and reachable. */
|
|
104
|
+
enabled: boolean;
|
|
105
|
+
/** Can keep its reasoning inside a reach. A provider that cannot is asked for search only. */
|
|
106
|
+
confined?: boolean;
|
|
107
|
+
detail?: Record<string, unknown>;
|
|
108
|
+
error?: string;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Who keeps the memory. Receiving records stays with the wheel's projection on
|
|
112
|
+
* write (the river); a provider here answers questions within a reach.
|
|
113
|
+
*/
|
|
114
|
+
export interface MemoryProvider {
|
|
115
|
+
readonly name: string;
|
|
116
|
+
status(): Promise<MemoryProviderStatus>;
|
|
117
|
+
/** A reasoned answer within the reach, with the sources it drew on. */
|
|
118
|
+
ask(question: MemoryQuestion): Promise<ProviderAnswer>;
|
|
119
|
+
/** The records within the reach closest to the query, with no reasoning. */
|
|
120
|
+
search(question: MemoryQuestion): Promise<ProviderAnswer>;
|
|
121
|
+
/** What the provider holds about one person, within the reach. */
|
|
122
|
+
about?(question: MemoryQuestion & {
|
|
123
|
+
about: string;
|
|
124
|
+
}): Promise<ProviderAnswer>;
|
|
125
|
+
}
|
|
126
|
+
/** The fields of a ceremony the reach rule reads. */
|
|
127
|
+
export interface CeremonyRef {
|
|
128
|
+
id: string;
|
|
129
|
+
subject_id?: string | null;
|
|
130
|
+
circle_id?: string | null;
|
|
131
|
+
/** The episode the ceremony is bound to, already read from its typed field or its legacy research_context. */
|
|
132
|
+
episode_path?: string | null;
|
|
133
|
+
/** Set on a closing record: the ceremony it closes. */
|
|
134
|
+
closes?: string | null;
|
|
135
|
+
participants?: string[];
|
|
136
|
+
}
|
|
137
|
+
/** A person's seat in a circle (member or facilitator). */
|
|
138
|
+
export interface SeatRef {
|
|
139
|
+
person_id: string;
|
|
140
|
+
circle_id: string;
|
|
141
|
+
}
|
|
142
|
+
/** True when the scope names nothing, so it reaches nothing. */
|
|
143
|
+
export declare function isEmptyScope(scope: MemoryScope | undefined | null): boolean;
|
|
144
|
+
/**
|
|
145
|
+
* Turn a scope into the ceremonies it reaches, from the ceremonies this wheel
|
|
146
|
+
* holds. Fields combine as a union. A ceremony named in `ceremonies` that the
|
|
147
|
+
* wheel does not hold is left out. The closing record of a reached ceremony is
|
|
148
|
+
* reached with it, since its learnings belong to that ceremony.
|
|
149
|
+
* `exclude_ceremonies` is applied last, closings included.
|
|
150
|
+
*/
|
|
151
|
+
export declare function resolveReach(scope: MemoryScope, ceremonies: readonly CeremonyRef[], seats?: readonly SeatRef[]): Reach;
|
|
152
|
+
/** A wheel record, flattened to what a text match reads. */
|
|
153
|
+
export interface MemoryRecord {
|
|
154
|
+
wheel_kind: string;
|
|
155
|
+
wheel_id: string;
|
|
156
|
+
ceremony_id?: string;
|
|
157
|
+
speaker?: string;
|
|
158
|
+
text: string;
|
|
159
|
+
at?: string;
|
|
160
|
+
}
|
|
161
|
+
/** The words of a query a match can use: lower case, three letters or more, no stopword. */
|
|
162
|
+
export declare function queryTerms(query: string): string[];
|
|
163
|
+
/** A window of the text around the first term it contains. */
|
|
164
|
+
export declare function excerptAround(text: string, terms: readonly string[], width?: number): string;
|
|
165
|
+
/**
|
|
166
|
+
* Match a query against records on their words. A record scores one point per
|
|
167
|
+
* distinct query term it contains, and two more when it holds the whole query
|
|
168
|
+
* as written. Ties go to the more recent record. Records that match no term are
|
|
169
|
+
* left out.
|
|
170
|
+
*/
|
|
171
|
+
export declare function matchRecords(query: string, records: readonly MemoryRecord[], opts?: {
|
|
172
|
+
limit?: number;
|
|
173
|
+
}): MemorySource[];
|
|
174
|
+
/** What the wheel lends the orchestration: its ceremonies, seats, records and names. */
|
|
175
|
+
export interface MemoryWheel {
|
|
176
|
+
ceremonies(): Promise<CeremonyRef[]>;
|
|
177
|
+
seats(): Promise<SeatRef[]>;
|
|
178
|
+
/** The beats, diary entries and ceremony records within the reach. */
|
|
179
|
+
records(reach: Reach): Promise<MemoryRecord[]>;
|
|
180
|
+
/** Names for wheel ids (people, the wheel itself). Unknown ids are left out. */
|
|
181
|
+
names(ids: string[]): Promise<Record<string, string>>;
|
|
182
|
+
}
|
|
183
|
+
export interface AskInput {
|
|
184
|
+
question: string;
|
|
185
|
+
scope: MemoryScope;
|
|
186
|
+
peer?: string;
|
|
187
|
+
reasoning_level?: string;
|
|
188
|
+
limit?: number;
|
|
189
|
+
}
|
|
190
|
+
export interface SearchInput {
|
|
191
|
+
query: string;
|
|
192
|
+
scope: MemoryScope;
|
|
193
|
+
limit?: number;
|
|
194
|
+
}
|
|
195
|
+
export interface AboutInput {
|
|
196
|
+
/** The wheel id of the person. */
|
|
197
|
+
person: string;
|
|
198
|
+
scope: MemoryScope;
|
|
199
|
+
question?: string;
|
|
200
|
+
limit?: number;
|
|
201
|
+
}
|
|
202
|
+
export interface Memory {
|
|
203
|
+
reach(scope: MemoryScope): Promise<Reach>;
|
|
204
|
+
status(): Promise<{
|
|
205
|
+
providers: MemoryProviderStatus[];
|
|
206
|
+
}>;
|
|
207
|
+
ask(input: AskInput): Promise<MemoryAnswer>;
|
|
208
|
+
search(input: SearchInput): Promise<MemoryAnswer>;
|
|
209
|
+
about(input: AboutInput): Promise<MemoryAnswer>;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* The memory a wheel answers from. Providers are tried in order: the first that
|
|
213
|
+
* answers gives the answer, and when every provider fails the wheel's own
|
|
214
|
+
* records answer (`matched`). The records match always adds its sources, each
|
|
215
|
+
* naming its provider, so an answer can be checked against the wheel even when
|
|
216
|
+
* a provider reasoned it.
|
|
217
|
+
*/
|
|
218
|
+
export declare function createMemory(opts: {
|
|
219
|
+
wheel: MemoryWheel;
|
|
220
|
+
providers?: MemoryProvider[];
|
|
221
|
+
}): Memory;
|
|
222
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAIH,4BAA4B;AAC5B,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,MAAM,EAAE,CAAC;AAE1C;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,sCAAsC;IACtC,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,qFAAqF;IACrF,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB,wCAAwC;IACxC,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,yFAAyF;IACzF,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB,4GAA4G;IAC5G,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4GAA4G;IAC5G,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED,8CAA8C;AAC9C,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,WAAW,CAAC;IACnB,wEAAwE;IACxE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,mGAAmG;IACnG,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;AAEtE,oCAAoC;AACpC,MAAM,WAAW,YAAY;IAC3B,qFAAqF;IACrF,QAAQ,EAAE,MAAM,CAAC;IACjB,gFAAgF;IAChF,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAC;IACjB,kEAAkE;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,uDAAuD;IACvD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,0FAA0F;IAC1F,OAAO,EAAE,MAAM,CAAC;IAChB,4BAA4B;IAC5B,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,wGAAwG;IACxG,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,MAAM,WAAW,YAAY;IAC3B,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,mDAAmD;IACnD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,KAAK,EAAE,KAAK,CAAC;IACb,wDAAwD;IACxD,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,2EAA2E;AAC3E,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,KAAK,CAAC;IACb,+DAA+D;IAC/D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qDAAqD;IACrD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gCAAgC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,gEAAgE;AAChE,MAAM,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;AAEzD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,8FAA8F;IAC9F,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,MAAM,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACxC,uEAAuE;IACvE,GAAG,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IACvD,4EAA4E;IAC5E,MAAM,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;IAC1D,kEAAkE;IAClE,KAAK,CAAC,CAAC,QAAQ,EAAE,cAAc,GAAG;QAAE,KAAK,EAAE,MAAM,CAAA;KAAE,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC/E;AAID,qDAAqD;AACrD,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,8GAA8G;IAC9G,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,uDAAuD;IACvD,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,2DAA2D;AAC3D,MAAM,WAAW,OAAO;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAKD,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAS3E;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,WAAW,EAAE,EAAE,KAAK,GAAE,SAAS,OAAO,EAAO,GAAG,KAAK,CAwB1H;AAID,4DAA4D;AAC5D,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AASD,4FAA4F;AAC5F,wBAAgB,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAGlD;AAID,8DAA8D;AAC9D,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,SAAM,GAAG,MAAM,CAQzF;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,YAAY,EAAE,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,YAAY,EAAE,CAqB3H;AAID,wFAAwF;AACxF,MAAM,WAAW,WAAW;IAC1B,UAAU,IAAI,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;IACrC,KAAK,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;IAC5B,sEAAsE;IACtE,OAAO,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAC/C,gFAAgF;IAChF,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CACvD;AAED,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,WAAW,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,UAAU;IACzB,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAKD,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;IAC1C,MAAM,IAAI,OAAO,CAAC;QAAE,SAAS,EAAE,oBAAoB,EAAE,CAAA;KAAE,CAAC,CAAC;IACzD,GAAG,CAAC,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5C,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;IAClD,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACjD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,SAAS,CAAC,EAAE,cAAc,EAAE,CAAA;CAAE,GAAG,MAAM,CA4H/F"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @medicine-wheel/memory — asking the wheel's memory, whoever keeps it.
|
|
3
|
+
*
|
|
4
|
+
* The wheel is canonical: ceremonies, turns (beats) and diary entries are
|
|
5
|
+
* recorded there. A memory provider (Honcho today) receives them and reasons
|
|
6
|
+
* over them. A caller asks the wheel, never the provider: it names a scope, the
|
|
7
|
+
* wheel turns the scope into the ceremonies it covers, and every provider is
|
|
8
|
+
* confined to that reach. Every source in an answer is a wheel record, or is
|
|
9
|
+
* marked as coming from outside the wheel.
|
|
10
|
+
*
|
|
11
|
+
* This package holds what does not depend on who keeps the memory: the
|
|
12
|
+
* contract, the rule that turns a scope into ceremonies, a text match over the
|
|
13
|
+
* wheel's own records (the provider that is always present), and the
|
|
14
|
+
* orchestration a wheel server and any other caller share. It has no
|
|
15
|
+
* dependencies. jgwill/medicine-wheel#149
|
|
16
|
+
*/
|
|
17
|
+
const list = (value) => (Array.isArray(value) ? value : value === undefined ? [] : [value]).map((v) => String(v).trim()).filter(Boolean);
|
|
18
|
+
/** True when the scope names nothing, so it reaches nothing. */
|
|
19
|
+
export function isEmptyScope(scope) {
|
|
20
|
+
if (!scope)
|
|
21
|
+
return true;
|
|
22
|
+
return (list(scope.ceremonies).length === 0 &&
|
|
23
|
+
list(scope.subject_id).length === 0 &&
|
|
24
|
+
list(scope.circle_id).length === 0 &&
|
|
25
|
+
list(scope.episode_path).length === 0 &&
|
|
26
|
+
!scope.participant?.trim());
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Turn a scope into the ceremonies it reaches, from the ceremonies this wheel
|
|
30
|
+
* holds. Fields combine as a union. A ceremony named in `ceremonies` that the
|
|
31
|
+
* wheel does not hold is left out. The closing record of a reached ceremony is
|
|
32
|
+
* reached with it, since its learnings belong to that ceremony.
|
|
33
|
+
* `exclude_ceremonies` is applied last, closings included.
|
|
34
|
+
*/
|
|
35
|
+
export function resolveReach(scope, ceremonies, seats = []) {
|
|
36
|
+
const named = new Set(list(scope.ceremonies));
|
|
37
|
+
const subjects = new Set(list(scope.subject_id));
|
|
38
|
+
const circles = new Set(list(scope.circle_id));
|
|
39
|
+
const episodes = list(scope.episode_path);
|
|
40
|
+
const episodeSet = new Set(episodes);
|
|
41
|
+
const person = scope.participant?.trim();
|
|
42
|
+
const seated = new Set(person ? seats.filter((s) => s.person_id === person).map((s) => s.circle_id) : []);
|
|
43
|
+
const reached = new Set();
|
|
44
|
+
for (const c of ceremonies) {
|
|
45
|
+
if (named.has(c.id) ||
|
|
46
|
+
(c.subject_id && subjects.has(c.subject_id)) ||
|
|
47
|
+
(c.circle_id && circles.has(c.circle_id)) ||
|
|
48
|
+
(c.episode_path && episodeSet.has(c.episode_path)) ||
|
|
49
|
+
(person && ((c.participants ?? []).includes(person) || (c.circle_id && seated.has(c.circle_id))))) {
|
|
50
|
+
reached.add(c.id);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
for (const c of ceremonies)
|
|
54
|
+
if (c.closes && reached.has(c.closes))
|
|
55
|
+
reached.add(c.id);
|
|
56
|
+
for (const id of scope.exclude_ceremonies ?? [])
|
|
57
|
+
reached.delete(id);
|
|
58
|
+
return { scope, ceremonies: [...reached], episodes };
|
|
59
|
+
}
|
|
60
|
+
const STOPWORDS = new Set(('the and for are but not you all any can had her was one our out has him his how its may new now old see two who did get let put say she too use what when where which while with this that than then them they there their these those from have into just more most much must only other over same some such very will would your about after again also been being before both could does each even ever here just like make many might never often once shall should still through under until upon whom whose why ' +
|
|
61
|
+
'les des une est pas pour que qui dans sur avec par mais comme plus tout tous elle ils elles nous vous leur leurs cette ces son ses sont été être avoir fait quoi quel quelle dont').split(/\s+/));
|
|
62
|
+
/** The words of a query a match can use: lower case, three letters or more, no stopword. */
|
|
63
|
+
export function queryTerms(query) {
|
|
64
|
+
const words = query.toLowerCase().normalize('NFKD').replace(/[̀-ͯ]/g, '').match(/[\p{L}\p{N}]+/gu) ?? [];
|
|
65
|
+
return [...new Set(words.filter((w) => w.length >= 3 && !STOPWORDS.has(w)))];
|
|
66
|
+
}
|
|
67
|
+
const fold = (text) => text.toLowerCase().normalize('NFKD').replace(/[̀-ͯ]/g, '');
|
|
68
|
+
/** A window of the text around the first term it contains. */
|
|
69
|
+
export function excerptAround(text, terms, width = 280) {
|
|
70
|
+
const flat = text.replace(/\s+/g, ' ').trim();
|
|
71
|
+
if (flat.length <= width)
|
|
72
|
+
return flat;
|
|
73
|
+
const folded = fold(flat);
|
|
74
|
+
const hits = terms.map((t) => folded.indexOf(t)).filter((i) => i >= 0);
|
|
75
|
+
const at = hits.length ? Math.min(...hits) : 0;
|
|
76
|
+
const start = Math.max(0, Math.min(at - Math.floor(width / 3), flat.length - width));
|
|
77
|
+
return `${start > 0 ? '…' : ''}${flat.slice(start, start + width).trim()}${start + width < flat.length ? '…' : ''}`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Match a query against records on their words. A record scores one point per
|
|
81
|
+
* distinct query term it contains, and two more when it holds the whole query
|
|
82
|
+
* as written. Ties go to the more recent record. Records that match no term are
|
|
83
|
+
* left out.
|
|
84
|
+
*/
|
|
85
|
+
export function matchRecords(query, records, opts = {}) {
|
|
86
|
+
const terms = queryTerms(query);
|
|
87
|
+
if (terms.length === 0)
|
|
88
|
+
return [];
|
|
89
|
+
const phrase = fold(query.trim());
|
|
90
|
+
const scored = records
|
|
91
|
+
.map((r) => {
|
|
92
|
+
const text = fold(r.text);
|
|
93
|
+
const score = terms.filter((t) => text.includes(t)).length + (phrase.length > 3 && text.includes(phrase) ? 2 : 0);
|
|
94
|
+
return { r, score };
|
|
95
|
+
})
|
|
96
|
+
.filter((s) => s.score > 0)
|
|
97
|
+
.sort((a, b) => b.score - a.score || (b.r.at ?? '').localeCompare(a.r.at ?? ''));
|
|
98
|
+
return scored.slice(0, opts.limit ?? 12).map(({ r }) => ({
|
|
99
|
+
provider: 'wheel',
|
|
100
|
+
wheel_kind: r.wheel_kind,
|
|
101
|
+
wheel_id: r.wheel_id,
|
|
102
|
+
...(r.ceremony_id ? { ceremony_id: r.ceremony_id } : {}),
|
|
103
|
+
...(r.speaker ? { speaker: r.speaker } : {}),
|
|
104
|
+
excerpt: excerptAround(r.text, terms),
|
|
105
|
+
...(r.at ? { at: r.at } : {}),
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
/** Wheel person ids as they appear in projected text, e.g. `node:human:1789710466321:95nnhl`. */
|
|
109
|
+
const PERSON_ID = /node:human:[0-9]+:[a-z0-9]+/g;
|
|
110
|
+
/**
|
|
111
|
+
* The memory a wheel answers from. Providers are tried in order: the first that
|
|
112
|
+
* answers gives the answer, and when every provider fails the wheel's own
|
|
113
|
+
* records answer (`matched`). The records match always adds its sources, each
|
|
114
|
+
* naming its provider, so an answer can be checked against the wheel even when
|
|
115
|
+
* a provider reasoned it.
|
|
116
|
+
*/
|
|
117
|
+
export function createMemory(opts) {
|
|
118
|
+
const { wheel } = opts;
|
|
119
|
+
const providers = opts.providers ?? [];
|
|
120
|
+
async function reach(scope) {
|
|
121
|
+
if (isEmptyScope(scope))
|
|
122
|
+
return { scope: scope ?? {}, ceremonies: [], episodes: [] };
|
|
123
|
+
const [ceremonies, seats] = await Promise.all([wheel.ceremonies(), scope.participant ? wheel.seats() : Promise.resolve([])]);
|
|
124
|
+
return resolveReach(scope, ceremonies, seats);
|
|
125
|
+
}
|
|
126
|
+
const empty = (r) => ({ provider: 'wheel', mode: 'empty', sources: [], reach: r });
|
|
127
|
+
const isEmpty = (r) => r.ceremonies.length === 0 && r.episodes.length === 0;
|
|
128
|
+
async function named(answer) {
|
|
129
|
+
const ids = new Set();
|
|
130
|
+
for (const s of answer.sources) {
|
|
131
|
+
if (s.speaker)
|
|
132
|
+
ids.add(s.speaker);
|
|
133
|
+
for (const m of s.excerpt.match(PERSON_ID) ?? [])
|
|
134
|
+
ids.add(m);
|
|
135
|
+
}
|
|
136
|
+
for (const m of answer.answer?.match(PERSON_ID) ?? [])
|
|
137
|
+
ids.add(m);
|
|
138
|
+
if (ids.size === 0)
|
|
139
|
+
return answer;
|
|
140
|
+
const names = await wheel.names([...ids]).catch(() => ({}));
|
|
141
|
+
const swap = (text) => text.replace(PERSON_ID, (id) => names[id] ?? id);
|
|
142
|
+
return {
|
|
143
|
+
...answer,
|
|
144
|
+
...(answer.answer !== undefined ? { answer: swap(answer.answer) } : {}),
|
|
145
|
+
sources: answer.sources.map((s) => ({
|
|
146
|
+
...s,
|
|
147
|
+
excerpt: swap(s.excerpt),
|
|
148
|
+
...(s.speaker && names[s.speaker] ? { speaker_name: names[s.speaker] } : {}),
|
|
149
|
+
})),
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
/** Provider sources first, then the records match, one source per wheel record. */
|
|
153
|
+
function merge(first, second, limit) {
|
|
154
|
+
const seen = new Set();
|
|
155
|
+
const out = [];
|
|
156
|
+
for (const s of [...first, ...second]) {
|
|
157
|
+
const key = s.outside_wheel ? `${s.provider}:${s.wheel_id}` : s.wheel_id;
|
|
158
|
+
if (seen.has(key))
|
|
159
|
+
continue;
|
|
160
|
+
seen.add(key);
|
|
161
|
+
out.push(s);
|
|
162
|
+
}
|
|
163
|
+
return out.slice(0, limit);
|
|
164
|
+
}
|
|
165
|
+
async function answer(r, matched, limit, ask) {
|
|
166
|
+
const failures = [];
|
|
167
|
+
for (const p of providers) {
|
|
168
|
+
const pending = ask(p);
|
|
169
|
+
if (!pending)
|
|
170
|
+
continue;
|
|
171
|
+
try {
|
|
172
|
+
const got = await pending;
|
|
173
|
+
return named({ ...got, sources: merge(got.sources, matched, limit), reach: r });
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
failures.push(`${p.name}: ${error instanceof Error ? error.message : String(error)}`);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return named({
|
|
180
|
+
provider: 'wheel',
|
|
181
|
+
mode: 'matched',
|
|
182
|
+
sources: matched,
|
|
183
|
+
reach: r,
|
|
184
|
+
...(providers.length === 0
|
|
185
|
+
? { note: 'No memory provider is configured; the wheel matched its own records.' }
|
|
186
|
+
: failures.length
|
|
187
|
+
? { note: `No provider answered (${failures.join('; ')}); the wheel matched its own records.` }
|
|
188
|
+
: {}),
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
return {
|
|
192
|
+
reach,
|
|
193
|
+
async status() {
|
|
194
|
+
const statuses = await Promise.all(providers.map((p) => p.status().catch((error) => ({ provider: p.name, enabled: false, error: error instanceof Error ? error.message : String(error) }))));
|
|
195
|
+
return { providers: [...statuses, { provider: 'wheel', enabled: true, confined: true, detail: { mode: 'matched' } }] };
|
|
196
|
+
},
|
|
197
|
+
async ask(input) {
|
|
198
|
+
const r = await reach(input.scope);
|
|
199
|
+
if (isEmpty(r))
|
|
200
|
+
return empty(r);
|
|
201
|
+
const limit = input.limit ?? 12;
|
|
202
|
+
const matched = matchRecords(input.question, await wheel.records(r), { limit });
|
|
203
|
+
return answer(r, matched, limit, (p) => p.ask({ query: input.question, reach: r, peer: input.peer, reasoning_level: input.reasoning_level, limit }));
|
|
204
|
+
},
|
|
205
|
+
async search(input) {
|
|
206
|
+
const r = await reach(input.scope);
|
|
207
|
+
if (isEmpty(r))
|
|
208
|
+
return empty(r);
|
|
209
|
+
const limit = input.limit ?? 12;
|
|
210
|
+
const matched = matchRecords(input.query, await wheel.records(r), { limit });
|
|
211
|
+
return answer(r, matched, limit, (p) => p.search({ query: input.query, reach: r, limit }));
|
|
212
|
+
},
|
|
213
|
+
async about(input) {
|
|
214
|
+
const r = await reach(input.scope);
|
|
215
|
+
if (isEmpty(r))
|
|
216
|
+
return empty(r);
|
|
217
|
+
const limit = input.limit ?? 12;
|
|
218
|
+
const query = input.question ?? '';
|
|
219
|
+
// From the wheel's own records, only what this person said or wrote: the closest to the
|
|
220
|
+
// question when there is one, else the most recent.
|
|
221
|
+
const theirs = (await wheel.records(r)).filter((rec) => rec.speaker === input.person);
|
|
222
|
+
const matched = query.trim()
|
|
223
|
+
? matchRecords(query, theirs, { limit })
|
|
224
|
+
: [...theirs]
|
|
225
|
+
.sort((a, b) => (b.at ?? '').localeCompare(a.at ?? ''))
|
|
226
|
+
.slice(0, limit)
|
|
227
|
+
.map((rec) => ({
|
|
228
|
+
provider: 'wheel',
|
|
229
|
+
wheel_kind: rec.wheel_kind,
|
|
230
|
+
wheel_id: rec.wheel_id,
|
|
231
|
+
...(rec.ceremony_id ? { ceremony_id: rec.ceremony_id } : {}),
|
|
232
|
+
speaker: rec.speaker,
|
|
233
|
+
excerpt: excerptAround(rec.text, []),
|
|
234
|
+
...(rec.at ? { at: rec.at } : {}),
|
|
235
|
+
}));
|
|
236
|
+
return answer(r, matched, limit, (p) => (p.about ? p.about({ query, reach: r, about: input.person, limit }) : null));
|
|
237
|
+
},
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@medicine-wheel/memory",
|
|
3
|
+
"version": "0.16.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Asking the wheel's memory, whoever keeps it: one contract that names no provider (scope, reach, answer, source, provider), the rule that turns a scope into ceremonies, a text match over the wheel's own records, and the orchestration a wheel server or any caller shares. Zero dependencies.",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.js",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
"scripts": {
|
|
22
|
+
"build": "tsc",
|
|
23
|
+
"dev": "tsc --watch",
|
|
24
|
+
"lint": "tsc --noEmit",
|
|
25
|
+
"clean": "rm -rf dist",
|
|
26
|
+
"prepublishOnly": "npm run clean && npm run build"
|
|
27
|
+
},
|
|
28
|
+
"keywords": [
|
|
29
|
+
"medicine-wheel",
|
|
30
|
+
"memory",
|
|
31
|
+
"ceremony",
|
|
32
|
+
"talking-circle",
|
|
33
|
+
"provider",
|
|
34
|
+
"contract"
|
|
35
|
+
],
|
|
36
|
+
"author": "IAIP Collaborative - Shawinigan, QC",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
"repository": {
|
|
39
|
+
"type": "git",
|
|
40
|
+
"url": "git+https://github.com/jgwill/medicine-wheel.git",
|
|
41
|
+
"directory": "src/memory"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@types/node": "^20.10.0",
|
|
46
|
+
"typescript": "^5.3.0"
|
|
47
|
+
}
|
|
48
|
+
}
|