@oh-my-pi/pi-mnemopi 18.14.2 → 18.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/dist/types/util/env.d.ts +2 -0
- package/package.json +5 -5
- package/src/core/extraction.ts +7 -26
- package/src/core/local-llm.ts +11 -26
- package/src/util/env.ts +7 -0
package/dist/types/util/env.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ export declare function envOptionalString(name: string, env?: Env): string | und
|
|
|
5
5
|
export declare function envTruthy(name: string, env?: Env): boolean;
|
|
6
6
|
export declare function envDisabled(name: string, env?: Env): boolean;
|
|
7
7
|
export declare function envBool(name: string, defaultValue: boolean, env?: Env): boolean;
|
|
8
|
+
/** Unset or blank → `defaultValue`; otherwise true only for `1`/`true`/`yes`/`on`, so a malformed value disables. */
|
|
9
|
+
export declare function envFlag(name: string, defaultValue: boolean, env?: Env): boolean;
|
|
8
10
|
export declare function envInt(name: string, defaultValue: number, env?: Env): number;
|
|
9
11
|
export declare function envFloat(name: string, defaultValue: number, env?: Env): number;
|
|
10
12
|
export declare function envOneOf<T extends string>(name: string, allowed: readonly T[], defaultValue: T, env?: Env): T;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-mnemopi",
|
|
4
|
-
"version": "18.
|
|
4
|
+
"version": "18.16.0",
|
|
5
5
|
"description": "Local SQLite memory engine for omp agents",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": {
|
|
@@ -42,10 +42,10 @@
|
|
|
42
42
|
"fmt": "oxfmt --no-error-on-unmatched-pattern 'src/**/*.{ts,tsx}' '{test,bench,examples,scripts}/**/*.ts' '*.ts'"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@oh-my-pi/pi-ai": "18.
|
|
46
|
-
"@oh-my-pi/pi-catalog": "18.
|
|
47
|
-
"@oh-my-pi/pi-natives": "18.
|
|
48
|
-
"@oh-my-pi/pi-utils": "18.
|
|
45
|
+
"@oh-my-pi/pi-ai": "18.16.0",
|
|
46
|
+
"@oh-my-pi/pi-catalog": "18.16.0",
|
|
47
|
+
"@oh-my-pi/pi-natives": "18.16.0",
|
|
48
|
+
"@oh-my-pi/pi-utils": "18.16.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"fastembed": "3.0.0",
|
package/src/core/extraction.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { withLoopPhase } from "@oh-my-pi/pi-utils";
|
|
1
|
+
import { isRecord, withLoopPhase } from "@oh-my-pi/pi-utils";
|
|
2
2
|
import { getDiagnostics, safeForLog } from "./extraction/diagnostics";
|
|
3
3
|
import { callHostLlm, getHostLlmBackend } from "./llm-backends";
|
|
4
4
|
import {
|
|
@@ -12,29 +12,14 @@ import {
|
|
|
12
12
|
} from "./local-llm";
|
|
13
13
|
import { getMnemopiRuntimeOptions } from "./runtime-options";
|
|
14
14
|
import { clipToWindow, DEFAULT_INPUT_CHARS } from "./text-window";
|
|
15
|
-
|
|
16
|
-
const TRUE_VALUES: Record<string, true> = { "1": true, true: true, yes: true, on: true };
|
|
17
|
-
|
|
18
|
-
function env(name: string): string {
|
|
19
|
-
return process.env[name] ?? "";
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function envBool(name: string, defaultValue: boolean): boolean {
|
|
23
|
-
const value = env(name).trim().toLowerCase();
|
|
24
|
-
return value === "" ? defaultValue : TRUE_VALUES[value] === true;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function envInt(name: string, defaultValue: number): number {
|
|
28
|
-
const parsed = Number.parseInt(env(name), 10);
|
|
29
|
-
return Number.isFinite(parsed) ? parsed : defaultValue;
|
|
30
|
-
}
|
|
15
|
+
import { envFlag, envInt, envString } from "../util/env";
|
|
31
16
|
|
|
32
17
|
function llmEnabled(): boolean {
|
|
33
|
-
return
|
|
18
|
+
return envFlag("MNEMOPI_LLM_ENABLED", true);
|
|
34
19
|
}
|
|
35
20
|
|
|
36
21
|
function hostLlmEnabled(): boolean {
|
|
37
|
-
return
|
|
22
|
+
return envFlag("MNEMOPI_HOST_LLM_ENABLED", false);
|
|
38
23
|
}
|
|
39
24
|
|
|
40
25
|
function llmMaxTokens(): number {
|
|
@@ -42,7 +27,7 @@ function llmMaxTokens(): number {
|
|
|
42
27
|
}
|
|
43
28
|
|
|
44
29
|
export const EXTRACTION_PROMPT_TEMPLATE =
|
|
45
|
-
|
|
30
|
+
envString("MNEMOPI_EXTRACTION_PROMPT") ||
|
|
46
31
|
`You are an expert structured memory extractor for Mnemopi v3.0+ MEMORIA tables.
|
|
47
32
|
The user message below may be in English, German, Russian, or another language.
|
|
48
33
|
First detect the language, then extract ONLY high-signal, long-term relevant items.
|
|
@@ -159,10 +144,6 @@ function normalizeFactArray(items: unknown, options: FactArrayOptions): string[]
|
|
|
159
144
|
return out;
|
|
160
145
|
}
|
|
161
146
|
|
|
162
|
-
function isRecord(value: unknown): value is Record<string, unknown> {
|
|
163
|
-
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
147
|
function triplePart(value: unknown): string {
|
|
167
148
|
return typeof value === "string" ? normalizeFact(value) : "";
|
|
168
149
|
}
|
|
@@ -341,8 +322,8 @@ async function tryHostExtraction(prompt: string): Promise<[boolean, string | nul
|
|
|
341
322
|
maxTokens: llmMaxTokens(),
|
|
342
323
|
temperature: 0,
|
|
343
324
|
timeout: 15,
|
|
344
|
-
provider:
|
|
345
|
-
model:
|
|
325
|
+
provider: envString("MNEMOPI_HOST_LLM_PROVIDER").trim() || null,
|
|
326
|
+
model: envString("MNEMOPI_HOST_LLM_MODEL").trim() || null,
|
|
346
327
|
});
|
|
347
328
|
const text = typeof raw === "string" ? raw.trim() : "";
|
|
348
329
|
return [true, text === "" ? null : text];
|
package/src/core/local-llm.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
import { ProviderHttpError } from "@oh-my-pi/pi-ai/error";
|
|
12
12
|
import { fetchWithRetry } from "@oh-my-pi/pi-utils";
|
|
13
13
|
import { type CompleteOptions, callHostLlm, getHostLlmBackend } from "./llm-backends";
|
|
14
|
+
import { envFlag, envInt, envString } from "../util/env";
|
|
14
15
|
import {
|
|
15
16
|
getMnemopiRuntimeOptions,
|
|
16
17
|
isPiAiModel,
|
|
@@ -29,12 +30,6 @@ export const DEFAULT_MODEL_REPO =
|
|
|
29
30
|
export const DEFAULT_MODEL_FILE =
|
|
30
31
|
ENV_MODEL_REPO !== "" && ENV_MODEL_FILE !== "" ? ENV_MODEL_FILE : "tinyllama-1.1b-chat-v1.0.Q4_K_M.gguf";
|
|
31
32
|
|
|
32
|
-
const TRUE_VALUES: Record<string, true> = { "1": true, true: true, yes: true, on: true };
|
|
33
|
-
|
|
34
|
-
function env(name: string): string {
|
|
35
|
-
return process.env[name] ?? "";
|
|
36
|
-
}
|
|
37
|
-
|
|
38
33
|
function activeLlmOptions() {
|
|
39
34
|
return getMnemopiRuntimeOptions()?.llm;
|
|
40
35
|
}
|
|
@@ -48,16 +43,6 @@ function activePiAiModel(): Model<Api> | undefined {
|
|
|
48
43
|
return isPiAiModel(model) ? model : undefined;
|
|
49
44
|
}
|
|
50
45
|
|
|
51
|
-
function envBool(name: string, defaultValue: boolean): boolean {
|
|
52
|
-
const value = env(name).trim().toLowerCase();
|
|
53
|
-
return value === "" ? defaultValue : TRUE_VALUES[value] === true;
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
function envInt(name: string, defaultValue: number): number {
|
|
57
|
-
const parsed = Number.parseInt(env(name), 10);
|
|
58
|
-
return Number.isFinite(parsed) ? parsed : defaultValue;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
46
|
function stripTrailingSlash(value: string): string {
|
|
62
47
|
let end = value.length;
|
|
63
48
|
while (end > 0 && value.charCodeAt(end - 1) === 47) {
|
|
@@ -74,7 +59,7 @@ function llmEnabled(): boolean {
|
|
|
74
59
|
if (activeCustomCompletion() !== undefined || activePiAiModel() !== undefined) {
|
|
75
60
|
return true;
|
|
76
61
|
}
|
|
77
|
-
return
|
|
62
|
+
return envFlag("MNEMOPI_LLM_ENABLED", true);
|
|
78
63
|
}
|
|
79
64
|
|
|
80
65
|
function llmMaxTokens(): number {
|
|
@@ -97,7 +82,7 @@ function hostLlmEnabled(): boolean {
|
|
|
97
82
|
if (active?.baseUrl !== undefined || (typeof active?.model === "string" && active.model !== "")) {
|
|
98
83
|
return false;
|
|
99
84
|
}
|
|
100
|
-
return
|
|
85
|
+
return envFlag("MNEMOPI_HOST_LLM_ENABLED", false);
|
|
101
86
|
}
|
|
102
87
|
|
|
103
88
|
function hostLlmContextTokens(): number {
|
|
@@ -109,7 +94,7 @@ function llmBaseUrl(): string {
|
|
|
109
94
|
if (active?.baseUrl !== undefined) {
|
|
110
95
|
return stripTrailingSlash(active.baseUrl);
|
|
111
96
|
}
|
|
112
|
-
return stripTrailingSlash(
|
|
97
|
+
return stripTrailingSlash(envString("MNEMOPI_LLM_BASE_URL"));
|
|
113
98
|
}
|
|
114
99
|
|
|
115
100
|
function llmModelName(): string {
|
|
@@ -117,7 +102,7 @@ function llmModelName(): string {
|
|
|
117
102
|
if (typeof model === "string") {
|
|
118
103
|
return model;
|
|
119
104
|
}
|
|
120
|
-
return
|
|
105
|
+
return envString("MNEMOPI_LLM_MODEL") || "local";
|
|
121
106
|
}
|
|
122
107
|
|
|
123
108
|
function llmApiKey(): ApiKey {
|
|
@@ -125,11 +110,11 @@ function llmApiKey(): ApiKey {
|
|
|
125
110
|
if (active?.apiKey !== undefined) {
|
|
126
111
|
return active.apiKey;
|
|
127
112
|
}
|
|
128
|
-
return
|
|
113
|
+
return envString("MNEMOPI_LLM_API_KEY");
|
|
129
114
|
}
|
|
130
115
|
|
|
131
116
|
function sleepPrompt(): string {
|
|
132
|
-
return
|
|
117
|
+
return envString("MNEMOPI_SLEEP_PROMPT").trim();
|
|
133
118
|
}
|
|
134
119
|
|
|
135
120
|
function memoryLines(memories: readonly string[]): string {
|
|
@@ -248,8 +233,8 @@ async function tryHostLlm(prompt: string, maxTokens: number, temperature: number
|
|
|
248
233
|
maxTokens,
|
|
249
234
|
temperature,
|
|
250
235
|
timeout: 15,
|
|
251
|
-
provider:
|
|
252
|
-
model:
|
|
236
|
+
provider: envString("MNEMOPI_HOST_LLM_PROVIDER").trim() || null,
|
|
237
|
+
model: envString("MNEMOPI_HOST_LLM_MODEL").trim() || null,
|
|
253
238
|
});
|
|
254
239
|
const text = typeof raw === "string" ? raw.trim() : "";
|
|
255
240
|
return [true, text === "" ? null : text];
|
|
@@ -418,7 +403,7 @@ async function summarizeChunk(
|
|
|
418
403
|
return null;
|
|
419
404
|
}
|
|
420
405
|
|
|
421
|
-
if (llmEnabled() && llmBaseUrl() !== "" && !
|
|
406
|
+
if (llmEnabled() && llmBaseUrl() !== "" && !envFlag("MNEMOPI_FORCE_LOCAL", false)) {
|
|
422
407
|
const raw = await callRemoteLlm(prompt, 0.3, options);
|
|
423
408
|
if (raw !== null) {
|
|
424
409
|
const cleaned = cleanOutput(raw);
|
|
@@ -475,7 +460,7 @@ export async function complete(
|
|
|
475
460
|
if (attempted) {
|
|
476
461
|
return hostText;
|
|
477
462
|
}
|
|
478
|
-
if (llmEnabled() && llmBaseUrl() !== "" && !
|
|
463
|
+
if (llmEnabled() && llmBaseUrl() !== "" && !envFlag("MNEMOPI_FORCE_LOCAL", false)) {
|
|
479
464
|
const remote = await callRemoteLlm(prompt, temperature, options);
|
|
480
465
|
return remote === null ? null : cleanOutput(remote) || null;
|
|
481
466
|
}
|
package/src/util/env.ts
CHANGED
|
@@ -36,6 +36,13 @@ export function envBool(name: string, defaultValue: boolean, env: Env = process.
|
|
|
36
36
|
return defaultValue;
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
+
/** Unset or blank → `defaultValue`; otherwise true only for `1`/`true`/`yes`/`on`, so a malformed value disables. */
|
|
40
|
+
export function envFlag(name: string, defaultValue: boolean, env: Env = process.env): boolean {
|
|
41
|
+
const value = env[name]?.trim().toLowerCase();
|
|
42
|
+
if (!value) return defaultValue;
|
|
43
|
+
return TRUE_VALUES[value] === true;
|
|
44
|
+
}
|
|
45
|
+
|
|
39
46
|
export function envInt(name: string, defaultValue: number, env: Env = process.env): number {
|
|
40
47
|
const raw = env[name]?.trim();
|
|
41
48
|
if (!raw) return defaultValue;
|