python: define core data models (OTARecord, CommitRecord, BranchMetadata)

Swadhin Biswas committed 7 months ago
3970c12
1 parent 419371c
commit 3970c12
1 file changed
+137 -0
Showing 1 changed file+137-0
▼PYTHON/contexa/models.py
+137-0
1
+"""
2
+GCC(Git-Context-Controller) Data Models Code by @swadhinbiswas
3
+
4
+Based on: arXiv:2508.00031v2 - "Git Context Controller: Manage the Context of
5
+LLM-based Agents like Git" by Junde Wu et al.
6
+
7
+The paper defines agent memory as a versioned, hierarchical file system with
8
+four core commands: COMMIT, BRANCH, MERGE, and CONTEXT.
9
+
10
+"""
11
+
12
+from dataclasses import dataclass, field
13
+from datetime import datetime
14
+from typing import Dict, Optional
15
+import yaml
16
+
17
+
18
+@dataclass
19
+class OTARecord:
20
+ """
21
+ Observation-Thought-Action record (OTA cycle).
22
+ The paper logs continuous OTA cycles in log.md for each branch.
23
+ """
24
+
25
+ timestamp: str
26
+ observation: str
27
+ thought: str
28
+ action: str
29
+ step: int
30
+
31
+ def to_markdown(self) -> str:
32
+ return (
33
+ f"### Step {self.step}-{self.timestamp}\n"
34
+ f"**Observation:** {self.observation}\n\n"
35
+ f"**Thought:** {self.thought}\n\n"
36
+ f"**Action:** {self.action}\n\n"
37
+ "--------\n"
38
+ )
39
+
40
+ @staticmethod
41
+ def from_dict(d: Dict) -> "OTARecord":
42
+ return OTARecord(
43
+ timestamp=d["timestamp"],
44
+ observation=d["observation"],
45
+ thought=d["thought"],
46
+ action=d["action"],
47
+ step=d["step"],
48
+ )
49
+
50
+
51
+@dataclass
52
+class CommitRecord:
53
+ commit_id: str
54
+ branch_name: str
55
+ branch_purpose: str
56
+ previous_progress_summary: str
57
+ this_commit_contribution: str
58
+ timestamp: str
59
+
60
+ def to_markdown(self) -> str:
61
+ return (
62
+ f"## Commit `{self.commit_id}`\n"
63
+ f"**Timestamp:** {self.timestamp}\n\n"
64
+ f"**Branch Purpose:** {self.branch_purpose}\n\n"
65
+ f"**Previous Progress Summary:** {self.previous_progress_summary}\n\n"
66
+ f"**This Commit's Contribution:** {self.this_commit_contribution}\n\n"
67
+ "---\n"
68
+ )
69
+
70
+
71
+@dataclass
72
+class BranchMetadata:
73
+ """
74
+ Structured metadata stored in metadata.yaml per branch.
75
+ Records architectural intent and motivation (per paper S3.1).
76
+ """
77
+
78
+ name: str
79
+ purpose: str
80
+ created_from: str
81
+ created_at: str
82
+ status: str = "active"
83
+ merged_into: Optional[str] = None
84
+ merged_at: Optional[str] = None
85
+
86
+ def to_yaml(self) -> str:
87
+ d = {
88
+ "name": self.name,
89
+ "purpose": self.purpose,
90
+ "created_from": self.created_from,
91
+ "created_at": self.created_at,
92
+ "status": self.status,
93
+ "merged_into": self.merged_into,
94
+ "merged_at": self.merged_at,
95
+ }
96
+ return yaml.dump(d, default_flow_style=False)
97
+
98
+ @staticmethod
99
+ def from_yaml(text: str) -> "BranchMetadata":
100
+ d = yaml.safe_load(text)
101
+ return BranchMetadata(
102
+ name=d["name"],
103
+ purpose=d["purpose"],
104
+ created_from=d["created_from"],
105
+ created_at=d["created_at"],
106
+ status=d.get("status", "active"),
107
+ merged_into=d.get("merged_into"),
108
+ merged_at=d.get("merged_at"),
109
+ )
110
+
111
+
112
+@dataclass
113
+class ContextResult:
114
+ """
115
+ Result returned by the CONTEXT command.
116
+ The paper specifies hierarchical retrieval at varying resolutions
117
+ (K = number of recent commit records to reveal; default K=1).
118
+ """
119
+
120
+ branch_name: str
121
+ k: int
122
+ commits: list[CommitRecord] = field(default_factory=list)
123
+ ota_records: list[OTARecord] = field(default_factory=list)
124
+ main_roadmap: str = ""
125
+ metadata: Optional[BranchMetadata] = None
126
+
127
+ def summary(self) -> str:
128
+ lines = [f"# CONTEXT — branch `{self.branch_name}` (K={self.k})\n"]
129
+ lines.append("## Global Roadmap\n" + self.main_roadmap + "\n")
130
+ lines.append(f"## Last {self.k} Commit(s)\n")
131
+ for c in self.commits:
132
+ lines.append(c.to_markdown())
133
+ if self.ota_records:
134
+ lines.append(f"## Recent OTA steps ({len(self.ota_records)} total)\n")
135
+ for rec in self.ota_records[-5:]:
136
+ lines.append(rec.to_markdown())
137
+ return "\n".join(lines)
0
138