pi-beyin 0.1.8 → 0.1.10

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 CHANGED
@@ -26,6 +26,26 @@ text found in notes, imported transcripts or tool output.
26
26
 
27
27
  The extensions without a vault are no-ops; `context` and `damitma` have nothing to read.
28
28
 
29
+ ## Who this is for
30
+
31
+ - You already use a **beyin vault** — a directory with `beyin.py` that brings its own installer and updater.
32
+ - You run **pi** and want that vault wired into pi.
33
+ - You have **CommandCode** access if you want Jev and the advisor tools. Without it, context injection,
34
+ the receipt reminder and the distillation offer still work; only scoring and the `beyin_jev_*` tools
35
+ stay inert.
36
+
37
+ With CommandCode, install the official provider so Jev can reuse its key instead of a separate secret:
38
+
39
+ ```bash
40
+ pi install npm:@commandcode/pi-commandcode-provider
41
+ ```
42
+
43
+ Otherwise put `CMD_API_KEY=...` in `~/.config/beyin/jev-commandcode.env` (or export it).
44
+
45
+ The harness patch only knows the code shapes it was written against. On an unfamiliar vault it prints
46
+ warnings, leaves the files untouched (fail-soft) and `receipt --harness pi` stays unavailable until the
47
+ patterns match — nothing breaks, the work is just labelled with another harness.
48
+
29
49
  ## Install
30
50
 
31
51
  ```bash
@@ -50,7 +70,9 @@ the context twice.
50
70
 
51
71
  Environment: `BEYIN_VAULT`, `BEYIN_PYTHON`, `BEYIN_HOOK_CONFIG`, `BEYIN_DAMITMA_CONFIG`,
52
72
  `BEYIN_JEV_CONFIG`, `BEYIN_CONTEXT_CHARS`, `BEYIN_REMINDERS=0`, `BEYIN_INCLUDE_VAULT=1`,
53
- `BEYIN_DAMITMA=0`, `BEYIN_JEV=0`, `BEYIN_DISABLE=1`, `BEYIN_DEBUG=1`, `BEYIN_PI_PATCH`,
73
+ `BEYIN_DAMITMA=0`, `BEYIN_JEV=0`, `BEYIN_DISABLE=1`, `BEYIN_DEBUG=1`, `BEYIN_PI_PATCH`, `BEYIN_LANG` (`tr`
74
+ by default; `en` switches the injected notices and command descriptions to English — the
75
+ `beyin_jev_*` tool schema text is still Turkish),
54
76
  `BEYIN_JEV_MODEL`, `BEYIN_JEV_API_KEY` / `CMD_API_KEY` / `COMMAND_CODE_API_KEY`,
55
77
  `BEYIN_FORCE_REMINDER=1`.
56
78
 
@@ -43,6 +43,8 @@ const REMINDERS = process.env.BEYIN_REMINDERS !== "0";
43
43
  const INCLUDE_VAULT = process.env.BEYIN_INCLUDE_VAULT === "1";
44
44
  const DISABLED = process.env.BEYIN_DISABLE === "1";
45
45
  const DEBUG = process.env.BEYIN_DEBUG === "1";
46
+ /** Model-facing fixed texts: "tr" (default) or "en" via BEYIN_LANG. */
47
+ const LANG = /^en/i.test(process.env.BEYIN_LANG || "") ? "en" : "tr";
46
48
 
47
49
  const SYNTHETIC_PREFIXES = [
48
50
  "<task-notification>",
@@ -264,7 +266,8 @@ interface JevPrefs {
264
266
  /**
265
267
  * Topicality bar — on the **score scale** (0..2), not a probability.
266
268
  *
267
- * The score question is a 3-level ordinal: `İlgisiz=0 · Arka plan=1 · Doğrudan ilgili=2`
269
+ * The score question is a 3-level ordinal (0 irrelevant, 1 background, 2 directly relevant);
270
+ * the criteria labels themselves are Turkish strings in the code below.
268
271
  * (the same three levels as Python `CRITERIA`). Expected score = weighted mean of the
269
272
  * distribution -> under linear mapping **score ≈ 2·p** (p = probability).
270
273
  *
@@ -647,13 +650,21 @@ export default function beyinContext(pi: ExtensionAPI) {
647
650
  // Receipt reminder from the previous turn (full mode only); then reset the flags for the new turn.
648
651
  let reminder: string | undefined;
649
652
  if (REMINDERS && mode === "full" && prevEdited && !prevRecorded) {
653
+ const receiptCmd = `python3 ${path.join(VAULT, "beyin.py")} receipt --harness pi --event-id EVENT_ID --summary "..." --ref <vault-relative-path>`;
650
654
  reminder =
651
- "## İkinci beyin — kayıt gerekli\n" +
652
- "Önceki turda dosya düzenlendi ve ikinci beyne kayıt düşülmedi. " +
653
- "Bu mesajı yanıtlamadan ÖNCE kaydet: vault dosyasıysa " +
654
- `\`python3 ${path.join(VAULT, "beyin.py")} receipt --harness pi --event-id EVENT_ID --summary "..." --ref <vault-goreli-yol>\`; ` +
655
- "vault dışı bir işse `note-create`/`task-create` ile vault'a kısa bir sonuç/görev notu yaz. " +
656
- "Kalıcı bir öğrenim varsa `knowledge/` altına damıt. Sonra normal yanıtı ver.";
655
+ LANG === "en"
656
+ ? "## Second brain — record required\n" +
657
+ "The previous turn edited files without recording anything in the second brain. " +
658
+ "Record BEFORE answering this message: for a vault file run " +
659
+ `\`${receiptCmd}\`; ` +
660
+ "for work outside the vault write a short result/task note with `note-create`/`task-create`. " +
661
+ "If there is a durable lesson, distill it under `knowledge/`. Then answer normally."
662
+ : "## İkinci beyin — kayıt gerekli\n" +
663
+ "Önceki turda dosya düzenlendi ve ikinci beyne kayıt düşülmedi. " +
664
+ "Bu mesajı yanıtlamadan ÖNCE kaydet: vault dosyasıysa " +
665
+ `\`${receiptCmd}\`; ` +
666
+ "vault dışı bir işse `note-create`/`task-create` ile vault'a kısa bir sonuç/görev notu yaz. " +
667
+ "Kalıcı bir öğrenim varsa `knowledge/` altına damıt. Sonra normal yanıtı ver.";
657
668
  }
658
669
  prevEdited = false;
659
670
  prevRecorded = false;
@@ -2,7 +2,7 @@
2
2
  * Beyin distillation — a knowledge-distillation SUGGESTION at turn/session end.
3
3
  *
4
4
  * Why: in beyin's bare form the concept/distillation work is done by the active
5
- * agent, not a background model (the V2 background compiler is retired). But the
5
+ * agent, not a background model. But the
6
6
  * "was the lesson distilled" step could be skipped silently. If a turn wrote a record
7
7
  * to the second brain without distilling under `knowledge/`, this extension injects a
8
8
  * short "offer distillation candidates" instruction at the end of the turn.
@@ -43,6 +43,8 @@ const HOOK_CONFIG_FILE = process.env.BEYIN_HOOK_CONFIG || path.join(HOME, ".conf
43
43
  const DEFAULT_EXCLUDES: string[] = [];
44
44
  const DISABLED = process.env.BEYIN_DAMITMA === "0" || process.env.BEYIN_DISABLE === "1";
45
45
  const DEBUG = process.env.BEYIN_DEBUG === "1";
46
+ /** Model-facing fixed texts: "tr" (default) or "en" via BEYIN_LANG. */
47
+ const LANG = /^en/i.test(process.env.BEYIN_LANG || "") ? "en" : "tr";
46
48
 
47
49
  const RECEIPT_RE = /(?:^|\s)beyin\.py\s+(?:receipt|note-create|task-create|task-update)\b/;
48
50
  const KNOWLEDGE_RE = /(^|[\\/])knowledge[\\/]/;
@@ -127,6 +129,18 @@ function insideVault(p: string): boolean {
127
129
  }
128
130
 
129
131
  function instruction(maxCandidates: number): string {
132
+ if (LANG === "en") {
133
+ return [
134
+ "## Second brain — distillation offer",
135
+ "This turn wrote to the second brain but nothing was distilled under `knowledge/`.",
136
+ "Now give the user a SHORT distillation offer (a short visible list):",
137
+ `- At most ${maxCandidates} candidates. One line each: **title** — one sentence — source (file/receipt path).`,
138
+ "- Offer only reusable lessons/decisions/concepts/methods; never invent candidates to fill a quota, never offer transient detail.",
139
+ '- If there is no durable lesson, skip the offer and say "nothing durable to distill" in one sentence.',
140
+ "- Write nothing under `knowledge/` before the user approves. After approval, write it with `beyin.py note-create` and add it to the receipt refs.",
141
+ "- If improving an existing knowledge note is enough, say so; do not open a new file.",
142
+ ].join("\n");
143
+ }
130
144
  return [
131
145
  "## İkinci beyin — damıtma önerisi",
132
146
  "Bu turda ikinci beyne kayıt düşüldü ama kalıcı bilgi `knowledge/` altına damıtılmadı.",
@@ -226,13 +240,13 @@ export default function beyinDamitma(pi: ExtensionAPI) {
226
240
 
227
241
  // Manual trigger: /damitma — asks for the same suggestion right now.
228
242
  pi.registerCommand("damitma", {
229
- description: "İkinci beyin damıtma önerisini şimdi iste",
243
+ description: LANG === "en" ? "Ask for the second-brain distillation offer now" : "İkinci beyin damıtma önerisini şimdi iste",
230
244
  handler: async (_args, ctx: ExtensionContext) => {
231
245
  pi.sendMessage(
232
246
  { customType: "beyin-damitma", display: false, content: instruction(config.maxCandidates) },
233
247
  { triggerTurn: true },
234
248
  );
235
- ctx.ui.notify("Damıtma önerisi istendi", "info");
249
+ ctx.ui.notify(LANG === "en" ? "Distillation offer requested" : "Damıtma önerisi istendi", "info");
236
250
  },
237
251
  });
238
252
  }
package/extensions/jev.ts CHANGED
@@ -40,6 +40,8 @@ const DEFAULT_MODEL = "typesafe/jev";
40
40
  const KEY_FILE = path.join(HOME, ".config", "beyin", "jev-commandcode.env");
41
41
  const CONFIG_FILE = path.join(HOME, ".config", "beyin", "jev.json");
42
42
  const DEBUG = process.env.BEYIN_DEBUG === "1";
43
+ /** User-facing fixed texts: "tr" (default) or "en" via BEYIN_LANG. */
44
+ const LANG = /^en/i.test(process.env.BEYIN_LANG || "") ? "en" : "tr";
43
45
 
44
46
  // Latest session context, needed to use pi's auth API (without touching auth.json directly).
45
47
  let latestContext: ExtensionContext | undefined;
@@ -279,7 +281,7 @@ export default function beyinJev(pi: ExtensionAPI) {
279
281
  });
280
282
 
281
283
  pi.registerCommand("jev-test", {
282
- description: "CommandCode destekli Jev (typesafe/jev) classifier'ını dene",
284
+ description: LANG === "en" ? "Try the CommandCode-backed Jev (typesafe/jev) classifier" : "CommandCode destekli Jev (typesafe/jev) classifier'ını dene",
283
285
  handler: async (args, ctx: ExtensionContext) => {
284
286
  const model = ctx.modelRegistry.findOfType("classifier", PROVIDER, MODEL_ID);
285
287
  if (!model) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-beyin",
3
- "version": "0.1.8",
3
+ "version": "0.1.10",
4
4
  "description": "pi-native bridge for the beyin second brain: context injection, distillation reminders, and Jev advisor tools.",
5
5
  "keywords": [
6
6
  "pi-package",
@@ -70,7 +70,7 @@ your behalf.
70
70
 
71
71
  ## Turning results into permanent knowledge
72
72
 
73
- The active agent continues V2's concept and link production. If a result contains reusable knowledge, first read
73
+ The active agent produces the concept and link notes. If a result contains reusable knowledge, first read
74
74
  `knowledge/index.md` and only the relevant concept. Improve the existing note with its sources, or create
75
75
  `knowledge/concepts/<topic>.md`: short description, key points, reasoning/limits and sources. If the source is
76
76
  the user's own statement, say so explicitly. If two topics have a real relationship, create a reasoned connection