pi-vault-mind 0.16.20 → 0.16.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * PersonalizationAgent — resolves user comments on personalized agent files.
3
+ *
4
+ * After personalization proposes changes to .pi/agent/system.md and AGENTS.md,
5
+ * the user can open those files in the editor, add comments/annotations, and
6
+ * then invoke @agent-personalization in chat to have this agent resolve them.
7
+ */
8
+ import { Agent, type AgentConfig } from "../agent-bus/Agent.js";
9
+ import type { LLMProvider } from "../agent-bus/LLMProvider.js";
10
+ import type { Message, MessageBus } from "../agent-bus/MessageBus.js";
11
+ export declare class PersonalizationAgent extends Agent {
12
+ constructor(config: AgentConfig, bus: MessageBus, llm?: LLMProvider);
13
+ tick(): Promise<void>;
14
+ protected handleMessage(msg: Message): Promise<void>;
15
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * PersonalizationAgent — resolves user comments on personalized agent files.
3
+ *
4
+ * After personalization proposes changes to .pi/agent/system.md and AGENTS.md,
5
+ * the user can open those files in the editor, add comments/annotations, and
6
+ * then invoke @agent-personalization in chat to have this agent resolve them.
7
+ */
8
+ import { Agent } from "../agent-bus/Agent.js";
9
+ export class PersonalizationAgent extends Agent {
10
+ constructor(config, bus, llm) {
11
+ super(config, bus, llm);
12
+ }
13
+ async tick() {
14
+ // Event-driven agent — no polling loop needed.
15
+ }
16
+ async handleMessage(msg) {
17
+ if (!this.llm) {
18
+ await this.bus.publish(`direct:${msg.senderId}`, this.config.id, {
19
+ type: "personalization_result",
20
+ dispatchId: msg.payload.dispatchId,
21
+ agentId: this.config.id,
22
+ status: "failed",
23
+ error: "No LLM provider configured for PersonalizationAgent",
24
+ });
25
+ return;
26
+ }
27
+ try {
28
+ const instruction = msg.payload.instruction;
29
+ const plan = await this.askLLM(`You are the Personalization agent. Resolve user comments in personalized agent files.
30
+
31
+ The user has reviewed proposed personalization changes and added comments/annotations.
32
+ Read the current state of .pi/agent/system.md and AGENTS.md, resolve any user comments,
33
+ and return updated content for each file that needs changes.
34
+
35
+ Instructions: ${instruction}
36
+
37
+ Return JSON: { "files": [{"path": "...", "action": "update"|"skip", "content": "..."}] }`);
38
+ if (plan?.files) {
39
+ for (const file of plan.files) {
40
+ if (file.action === "update") {
41
+ await this.invokePiTool("write", {
42
+ file_path: file.path,
43
+ content: file.content,
44
+ });
45
+ }
46
+ }
47
+ }
48
+ await this.bus.publish(`direct:${msg.senderId}`, this.config.id, {
49
+ type: "personalization_result",
50
+ dispatchId: msg.payload.dispatchId,
51
+ agentId: this.config.id,
52
+ status: "done",
53
+ });
54
+ }
55
+ catch (err) {
56
+ const errorMsg = err instanceof Error ? err.message : String(err);
57
+ await this.bus.publish(`direct:${msg.senderId}`, this.config.id, {
58
+ type: "personalization_result",
59
+ dispatchId: msg.payload.dispatchId,
60
+ agentId: this.config.id,
61
+ status: "failed",
62
+ error: errorMsg,
63
+ });
64
+ }
65
+ }
66
+ }
@@ -2,3 +2,4 @@ export { BroadcasterAgent } from "./BroadcasterAgent.js";
2
2
  export { type DispatchJob, HeavyLifterAgent } from "./HeavyLifterAgent.js";
3
3
  export { ManagerAgent } from "./ManagerAgent.js";
4
4
  export { MinerAgent } from "./MinerAgent.js";
5
+ export { PersonalizationAgent } from "./PersonalizationAgent.js";
@@ -2,3 +2,4 @@ export { BroadcasterAgent } from "./BroadcasterAgent.js";
2
2
  export { HeavyLifterAgent } from "./HeavyLifterAgent.js";
3
3
  export { ManagerAgent } from "./ManagerAgent.js";
4
4
  export { MinerAgent } from "./MinerAgent.js";
5
+ export { PersonalizationAgent } from "./PersonalizationAgent.js";
@@ -14,7 +14,7 @@ import * as path from "node:path";
14
14
  import { AgentLoader } from "./agent-bus/AgentLoader.js";
15
15
  import { AgentRegistry } from "./agent-bus/AgentRegistry.js";
16
16
  import { AgentModelProvider } from "./agent-bus/LLMProvider.js";
17
- import { BroadcasterAgent, HeavyLifterAgent, ManagerAgent, MinerAgent } from "./agents/index.js";
17
+ import { BroadcasterAgent, HeavyLifterAgent, ManagerAgent, MinerAgent, PersonalizationAgent, } from "./agents/index.js";
18
18
  import { registerAgentIdentity } from "./bridge.js";
19
19
  import { EXT_ROOT, loadConfig, resolveVaultFolder } from "./utils.js";
20
20
  // ── Agent registry setup ─────────────────────────────────────────────────────
@@ -24,6 +24,7 @@ export function registerAgentTypes() {
24
24
  AgentRegistry.register("MinerAgent", MinerAgent);
25
25
  AgentRegistry.register("BroadcasterAgent", BroadcasterAgent);
26
26
  AgentRegistry.register("ManagerAgent", ManagerAgent);
27
+ AgentRegistry.register("PersonalizationAgent", PersonalizationAgent);
27
28
  }
28
29
  /**
29
30
  * Create and start the agent engine.
@@ -3,6 +3,7 @@ import * as path from "node:path";
3
3
  import { parseFrontmatter } from "@earendil-works/pi-coding-agent";
4
4
  import { enableACM } from "./context-capture.js";
5
5
  import { getStatus } from "./lance.js";
6
+ import { scaffoldVaultConfig } from "./scaffold.js";
6
7
  import { expandHome, getPersonalizedMarkerPath, hasPiContextTools, isPersonalized, loadConfig, resolveAgentDir, } from "./utils.js";
7
8
  class PersonalizationCancelledError extends Error {
8
9
  constructor() {
@@ -620,13 +621,14 @@ export const runPersonalize = async (ctx, pi) => {
620
621
  throwIfPersonalizationCancelled(signal);
621
622
  const result = await presentAndApplyDiff(suggestions, ctx, currentConfig, signal);
622
623
  throwIfPersonalizationCancelled(signal);
624
+ // Scaffold collections and injectors before marking complete
625
+ throwIfPersonalizationCancelled(signal);
626
+ scaffoldVaultConfig(vaultPath);
623
627
  const markerPath = getPersonalizedMarkerPath(vaultPath);
624
628
  throwIfPersonalizationCancelled(signal);
625
629
  await fs.promises.mkdir(path.dirname(markerPath), { recursive: true });
626
630
  throwIfPersonalizationCancelled(signal);
627
- // The durable marker is the personalization commit point. Keep the final
628
- // abort check and synchronous write in one event-loop turn so cancellation
629
- // cannot report an aborted run after the marker has been committed.
631
+ // The durable marker is the personalization commit point.
630
632
  fs.writeFileSync(markerPath, JSON.stringify({ completed: true, completedAt: new Date().toISOString() }, null, 2));
631
633
  const sessionCfg = loadConfig(ctx.cwd);
632
634
  const piCtxCfg = sessionCfg.extensionCompatibility?.["pi-context"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-vault-mind",
3
- "version": "0.16.20",
3
+ "version": "0.16.22",
4
4
  "description": "Passive Obsidian vault extension for pi. Watches @agent markers, dispatches forked subagents (Miner, Broadcaster, Heavy-Lifter), stores in LanceDB with vector + FTS + graph. Multi-agent 'Drop & Forget' workflow for the pi agent ecosystem.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",