repositories
loading repo index
repositories
loading repo index
repository
loading code, commits, and activity
public Clawd ADK gateway launch mirror
stars
latest
clone command
git clone gitlawb://did:key:z6Mkq5mY...iFZ5/my-project-publ...git clone gitlawb://did:key:z6Mkq5mY.../my-project-publ...2fa351d6docs: add automaton and perps launch sources16d ago| #1 | /** |
| #2 | * Lineage Tracking |
| #3 | * |
| #4 | * Track parent-child relationships between automatons. |
| #5 | * The parent records children in SQLite. |
| #6 | * Children record their parent in config. |
| #7 | * ERC-8004 registration includes parentAgent field. |
| #8 | */ |
| #9 | |
| #10 | import type { |
| #11 | AutomatonDatabase, |
| #12 | ChildAutomaton, |
| #13 | AutomatonConfig, |
| #14 | ConwayClient, |
| #15 | } from "../types.js"; |
| #16 | |
| #17 | /** |
| #18 | * Get the full lineage tree (parent -> children). |
| #19 | */ |
| #20 | export function getLineage(db: AutomatonDatabase): { |
| #21 | children: ChildAutomaton[]; |
| #22 | alive: number; |
| #23 | dead: number; |
| #24 | total: number; |
| #25 | } { |
| #26 | const children = db.getChildren(); |
| #27 | const alive = children.filter( |
| #28 | (c) => c.status === "running" || c.status === "sleeping", |
| #29 | ).length; |
| #30 | const dead = children.filter((c) => c.status === "dead").length; |
| #31 | |
| #32 | return { |
| #33 | children, |
| #34 | alive, |
| #35 | dead, |
| #36 | total: children.length, |
| #37 | }; |
| #38 | } |
| #39 | |
| #40 | /** |
| #41 | * Check if this automaton has a parent (is itself a child). |
| #42 | */ |
| #43 | export function hasParent(config: AutomatonConfig): boolean { |
| #44 | return !!config.parentAddress; |
| #45 | } |
| #46 | |
| #47 | /** |
| #48 | * Get a summary of the lineage for the system prompt. |
| #49 | */ |
| #50 | export function getLineageSummary( |
| #51 | db: AutomatonDatabase, |
| #52 | config: AutomatonConfig, |
| #53 | ): string { |
| #54 | const lineage = getLineage(db); |
| #55 | const parts: string[] = []; |
| #56 | |
| #57 | if (hasParent(config)) { |
| #58 | parts.push(`Parent: ${config.parentAddress}`); |
| #59 | } |
| #60 | |
| #61 | if (lineage.total > 0) { |
| #62 | parts.push( |
| #63 | `Children: ${lineage.total} total (${lineage.alive} alive, ${lineage.dead} dead)`, |
| #64 | ); |
| #65 | for (const child of lineage.children) { |
| #66 | parts.push( |
| #67 | ` - ${child.name} [${child.status}] sandbox:${child.sandboxId}`, |
| #68 | ); |
| #69 | } |
| #70 | } |
| #71 | |
| #72 | return parts.length > 0 ? parts.join("\n") : "No lineage (first generation)"; |
| #73 | } |
| #74 | |
| #75 | /** |
| #76 | * Prune dead children from tracking (optional cleanup). |
| #77 | */ |
| #78 | export function pruneDeadChildren( |
| #79 | db: AutomatonDatabase, |
| #80 | keepLast: number = 5, |
| #81 | ): number { |
| #82 | const children = db.getChildren(); |
| #83 | const dead = children.filter((c) => c.status === "dead"); |
| #84 | |
| #85 | if (dead.length <= keepLast) return 0; |
| #86 | |
| #87 | // Sort by creation date, oldest first |
| #88 | dead.sort( |
| #89 | (a, b) => |
| #90 | new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime(), |
| #91 | ); |
| #92 | |
| #93 | // Keep the most recent `keepLast` dead children |
| #94 | const toRemove = dead.slice(0, dead.length - keepLast); |
| #95 | |
| #96 | // We don't actually delete from DB -- just mark the records |
| #97 | // The DB retains all history for audit purposes |
| #98 | return toRemove.length; |
| #99 | } |
| #100 | |
| #101 | /** |
| #102 | * Refresh status of all children. |
| #103 | */ |
| #104 | export async function refreshChildrenStatus( |
| #105 | conway: ConwayClient, |
| #106 | db: AutomatonDatabase, |
| #107 | ): Promise<void> { |
| #108 | const { checkChildStatus } = await import("./spawn.js"); |
| #109 | const children = db.getChildren(); |
| #110 | |
| #111 | for (const child of children) { |
| #112 | if (child.status === "dead") continue; |
| #113 | |
| #114 | try { |
| #115 | await checkChildStatus(conway, db, child.id); |
| #116 | } catch { |
| #117 | db.updateChildStatus(child.id, "unknown"); |
| #118 | } |
| #119 | } |
| #120 | } |
| #121 |