Smart Contract
Librarian
A.6d96bf7d95a8b595.Librarian
1// Librarian.cdc - On-chain identity and journal for the AI Librarian
2//
3// This is the very first Librarian contract. It will be updated in the future.
4// The Librarian Prime (human) is 0x13d34343017c6bd2 on Flow mainnet.
5// We work together to save knowledge for machines and mankind.
6//
7
8access(all) contract Librarian {
9 // Identity metadata - read by the AI agent at startup
10 access(all) let contractVersion: String
11 access(all) let librarianPrimeAddress: Address
12 access(all) let missionStatement: String
13
14 // Storage paths for LibrarianIdentity
15 access(all) let LibrarianStoragePath: StoragePath
16 access(all) let LibrarianPublicPath: PublicPath
17
18 access(all) event EntryRecorded(entryType: String, timestamp: UFix64)
19 access(all) event NameSet(name: String)
20
21 access(all) enum EntryKind: UInt8 {
22 access(all) case MEMORY
23 access(all) case CONVERSATION
24 access(all) case REFERENCE
25 access(all) case NOTE
26 }
27
28 access(all) fun entryKindToString(kind: EntryKind): String {
29 if kind == EntryKind.MEMORY {
30 return "memory"
31 } else if kind == EntryKind.CONVERSATION {
32 return "conversation"
33 } else if kind == EntryKind.REFERENCE {
34 return "reference"
35 } else if kind == EntryKind.NOTE {
36 return "note"
37 } else {
38 return "unknown"
39 }
40 }
41
42 access(all) struct JournalEntry {
43 access(all) let entryType: EntryKind
44 access(all) let content: String
45 access(all) let metadata: {String: String}
46 access(all) let timestamp: UFix64
47
48 init(
49 entryType: EntryKind,
50 content: String,
51 metadata: {String: String},
52 timestamp: UFix64
53 ) {
54 self.entryType = entryType
55 self.content = content
56 self.metadata = metadata
57 self.timestamp = timestamp
58 }
59 }
60
61
62 access(all) resource LibrarianIdentity {
63 access(all) var name: String
64 access(self) var nameSet: Bool
65 access(all) var journal: [JournalEntry]
66 access(all) let createdAt: UFix64
67
68 access(all) fun setName(newName: String) {
69 pre { !self.nameSet: "Name has already been set" }
70 self.name = newName
71 self.nameSet = true
72 emit NameSet(name: newName)
73 }
74
75 access(all) fun recordEntry(entryType: EntryKind, content: String, metadata: {String: String}) {
76 let entry = JournalEntry(
77 entryType: entryType,
78 content: content,
79 metadata: metadata,
80 timestamp: getCurrentBlock().timestamp
81 )
82 self.journal.append(entry)
83 let entryTypeStr = Librarian.entryKindToString(kind: entryType)
84 emit EntryRecorded(entryType: entryTypeStr, timestamp: entry.timestamp)
85 }
86
87 access(all) fun getEntries(limit: Int): [JournalEntry] {
88 let length = self.journal.length
89 var count = limit
90 if count < 0 {
91 count = 0
92 }
93 if count > length {
94 count = length
95 }
96
97 var result: [JournalEntry] = []
98 var i = self.journal.length - 1
99 var collected = 0
100 while i >= 0 && collected < count {
101 result.append(self.journal[i])
102 i = i - 1
103 collected = collected + 1
104 }
105 return result
106 }
107
108 access(all) fun getEntriesByType(entryType: EntryKind): [JournalEntry] {
109 var result: [JournalEntry] = []
110 for entry in self.journal {
111 if entry.entryType == entryType {
112 result.append(entry)
113 }
114 }
115 return result
116 }
117
118 init() {
119 self.name = ""
120 self.nameSet = false
121 self.journal = []
122 self.createdAt = getCurrentBlock().timestamp
123 }
124 }
125
126 access(all) fun createLibrarianIdentity(): @LibrarianIdentity {
127 return <- create LibrarianIdentity()
128 }
129
130 // Public function to get the librarian journal entries
131 access(all) fun getLibrarianIdentity(limit: Int): [JournalEntry] {
132 let identity = self.account.storage.borrow<&LibrarianIdentity>(from: self.LibrarianStoragePath)!
133 let entries = identity.getEntries(limit: limit)
134 return entries
135 }
136
137 init() {
138 self.contractVersion = "1.0"
139 self.librarianPrimeAddress = 0x13d34343017c6bd2
140 self.missionStatement = "We work together to save knowledge for machines and mankind."
141 self.LibrarianStoragePath = StoragePath(identifier: "librarianIdentity")!
142 self.LibrarianPublicPath = PublicPath(identifier: "librarianIdentity")!
143
144 // create identity and save it to storage
145 let identity <- create LibrarianIdentity()
146 self.account.storage.save(<- identity, to: self.LibrarianStoragePath)
147
148 }
149}
150