391325eb0ba212b9e17747916a357ca49308a4094f48825e247f56746b2be937afterMetadataWrite1/**
2 * Dynamic Rename
3 *
4 * Listens for setup completion on any extension tree.
5 * Reads the tree content, makes one background LLM call,
6 * renames the root to something descriptive. Non-blocking.
7 */
8
9import log from "../../seed/log.js";
10
11const GENERIC_NAMES = new Set([
12 "Fitness", "Food", "Recovery", "Study", "KB", "Knowledge Base",
13]);
14
15export async function init(core) {
16 const Node = core.models.Node;
17 const runChat = core.llm?.runChat || null;
18
19 core.hooks.register("afterMetadataWrite", async ({ nodeId, extName, data }) => {
20 // Only fire on setup completion
21 if (data?.setupPhase !== "complete") return;
22
23 // Only for root nodes
24 const root = await Node.findById(nodeId).select("name rootOwner children").lean();
25 if (!root?.rootOwner) return;
26
27 // Don't overwrite a name the user or AI already set
28 if (!GENERIC_NAMES.has(root.name)) return;
29
30 // Read tree content for context
31 const children = await Node.find({ parent: nodeId })
32 .select("name children").lean();
33
34 let summary = `Extension: ${extName}\nChildren: ${children.map(c => c.name).join(", ")}`;
35
36 // Read grandchildren for more context (topics, exercises, substances, etc.)
37 const grandchildIds = children.flatMap(c => c.children || []);
38 if (grandchildIds.length > 0) {
39 const grandchildren = await Node.find({ _id: { $in: grandchildIds.slice(0, 20) } })
40 .select("name").lean();
41 if (grandchildren.length > 0) {
42 summary += `\nTopics/Items: ${grandchildren.map(g => g.name).join(", ")}`;
43 }
44 }
45
46 // One background LLM call
47 if (!runChat) return;
48 try {
49 const { answer } = await runChat({
50 userId: String(root.rootOwner),
51 username: "system",
52 message: `Rename this tree. Return ONLY the new name. 2-4 words. No quotes. No explanation.\n\n${summary}\n\nExamples: "Strength Training", "Keto Tracking", "Learning React", "Nicotine Recovery", "Team Wiki"`,
53 mode: "home:default",
54 llmPriority: core.llm.LLM_PRIORITY.BACKGROUND,
55 });
56
57 const newName = (answer || "").trim().replace(/^["']|["']$/g, "").slice(0, 60);
58 if (newName && newName.length >= 2 && newName !== root.name) {
59 await Node.findByIdAndUpdate(nodeId, { $set: { name: newName } });
60 log.info("DynamicRename", `Renamed "${root.name}" to "${newName}"`);
61 }
62 } catch (err) {
63 log.debug("DynamicRename", `Rename failed for ${nodeId}: ${err.message}`);
64 }
65 }, "dynamic-rename");
66
67 log.info("DynamicRename", "Loaded. Trees get named after setup.");
68 return {};
69}
701export default {
2 name: "dynamic-rename",
3 version: "1.0.1",
4 builtFor: "TreeOS",
5 description:
6 "Renames tree roots after setup completes. Reads the tree content and generates " +
7 "a short descriptive name via one background LLM call. Non-blocking. Works with any " +
8 "extension that follows the setupPhase pattern. Silent failure if LLM unavailable.",
9
10 needs: {
11 services: ["hooks", "llm"],
12 models: ["Node"],
13 },
14
15 optional: {},
16
17 provides: {
18 models: {},
19 routes: false,
20 tools: false,
21 jobs: false,
22 modes: false,
23
24 hooks: {
25 fires: [],
26 listens: ["afterMetadataWrite"],
27 },
28 },
29};
30
| Version | Published | Downloads |
|---|---|---|
| 1.0.1 | 38d ago | 0 |
| 1.0.0 | 48d ago | 0 |
treeos ext star dynamic-rename
Post comments from the CLI: treeos ext comment dynamic-rename "your comment"
Max 3 comments per extension. One star and one flag per user.
Loading comments...