@tpsdev-ai/flair 0.2.0
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.
- package/LICENSE +19 -0
- package/README.md +246 -0
- package/SECURITY.md +116 -0
- package/config.yaml +16 -0
- package/dist/resources/A2AAdapter.js +474 -0
- package/dist/resources/Agent.js +9 -0
- package/dist/resources/AgentCard.js +45 -0
- package/dist/resources/AgentSeed.js +111 -0
- package/dist/resources/IngestEvents.js +149 -0
- package/dist/resources/Integration.js +13 -0
- package/dist/resources/IssueTokens.js +19 -0
- package/dist/resources/Memory.js +122 -0
- package/dist/resources/MemoryBootstrap.js +263 -0
- package/dist/resources/MemoryConsolidate.js +105 -0
- package/dist/resources/MemoryFeed.js +41 -0
- package/dist/resources/MemoryReflect.js +105 -0
- package/dist/resources/OrgEvent.js +43 -0
- package/dist/resources/OrgEventCatchup.js +65 -0
- package/dist/resources/OrgEventMaintenance.js +29 -0
- package/dist/resources/SemanticSearch.js +147 -0
- package/dist/resources/SkillScan.js +101 -0
- package/dist/resources/Soul.js +9 -0
- package/dist/resources/SoulFeed.js +12 -0
- package/dist/resources/WorkspaceLatest.js +45 -0
- package/dist/resources/WorkspaceState.js +76 -0
- package/dist/resources/auth-middleware.js +470 -0
- package/dist/resources/embeddings-provider.js +127 -0
- package/dist/resources/embeddings.js +42 -0
- package/dist/resources/health.js +6 -0
- package/dist/resources/memory-feed-lib.js +15 -0
- package/dist/resources/table-helpers.js +35 -0
- package/package.json +62 -0
- package/resources/A2AAdapter.ts +510 -0
- package/resources/Agent.ts +10 -0
- package/resources/AgentCard.ts +65 -0
- package/resources/AgentSeed.ts +119 -0
- package/resources/IngestEvents.ts +189 -0
- package/resources/Integration.ts +14 -0
- package/resources/IssueTokens.ts +29 -0
- package/resources/Memory.ts +138 -0
- package/resources/MemoryBootstrap.ts +283 -0
- package/resources/MemoryConsolidate.ts +121 -0
- package/resources/MemoryFeed.ts +48 -0
- package/resources/MemoryReflect.ts +122 -0
- package/resources/OrgEvent.ts +63 -0
- package/resources/OrgEventCatchup.ts +89 -0
- package/resources/OrgEventMaintenance.ts +37 -0
- package/resources/SemanticSearch.ts +157 -0
- package/resources/SkillScan.ts +146 -0
- package/resources/Soul.ts +10 -0
- package/resources/SoulFeed.ts +15 -0
- package/resources/WorkspaceLatest.ts +66 -0
- package/resources/WorkspaceState.ts +102 -0
- package/resources/auth-middleware.ts +502 -0
- package/resources/embeddings-provider.ts +144 -0
- package/resources/embeddings.ts +28 -0
- package/resources/health.ts +7 -0
- package/resources/memory-feed-lib.ts +22 -0
- package/resources/table-helpers.ts +46 -0
- package/schemas/agent.graphql +22 -0
- package/schemas/event.graphql +12 -0
- package/schemas/memory.graphql +50 -0
- package/schemas/schema.graphql +41 -0
- package/schemas/workspace.graphql +14 -0
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
|
|
3
|
+
export function computeContentHash(agentId: string, content: string): string {
|
|
4
|
+
return createHash("sha256")
|
|
5
|
+
.update(`${agentId}${content}`)
|
|
6
|
+
.digest("hex")
|
|
7
|
+
.slice(0, 16);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export async function findExistingMemoryByContentHash(
|
|
11
|
+
records: AsyncIterable<any> | Iterable<any>,
|
|
12
|
+
agentId: string,
|
|
13
|
+
contentHash: string,
|
|
14
|
+
): Promise<any | null> {
|
|
15
|
+
for await (const record of records) {
|
|
16
|
+
if (record?.agentId === agentId && record?.contentHash === contentHash) {
|
|
17
|
+
return record;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Safe read-modify-write helper for Harper tables.
|
|
3
|
+
*
|
|
4
|
+
* Harper's `put()` is FULL RECORD REPLACEMENT. If you pass a partial
|
|
5
|
+
* object, all missing fields (including embeddings!) are permanently
|
|
6
|
+
* deleted. This helper ensures you always read the full record first.
|
|
7
|
+
*
|
|
8
|
+
* Usage:
|
|
9
|
+
* import { patchRecord } from "./table-helpers.js";
|
|
10
|
+
* await patchRecord(tables.Memory, id, { lastReflected: now });
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
export async function patchRecord(
|
|
14
|
+
table: any,
|
|
15
|
+
id: string,
|
|
16
|
+
patch: Record<string, unknown>,
|
|
17
|
+
): Promise<void> {
|
|
18
|
+
const existing = await table.get(id);
|
|
19
|
+
if (!existing) throw new Error(`Record ${id} not found`);
|
|
20
|
+
await table.put({ ...existing, ...patch });
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Fire-and-forget variant — swallows errors silently.
|
|
25
|
+
* Use for best-effort metadata updates (lastReflected, lastRetrieved, etc.)
|
|
26
|
+
* where a failure should never break the calling request.
|
|
27
|
+
*/
|
|
28
|
+
export function patchRecordSilent(
|
|
29
|
+
table: any,
|
|
30
|
+
id: string,
|
|
31
|
+
patch: Record<string, unknown>,
|
|
32
|
+
): void {
|
|
33
|
+
patchRecord(table, id, patch).catch(() => {});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// ── RULE ──────────────────────────────────────────────────────────────────────
|
|
37
|
+
// Never call `tables.X.put(partial)` directly anywhere in Flair resources.
|
|
38
|
+
// Harper put() = FULL RECORD REPLACEMENT. Missing fields are deleted permanently.
|
|
39
|
+
// Always use patchRecord() or patchRecordSilent().
|
|
40
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
41
|
+
|
|
42
|
+
// ── RULE ──────────────────────────────────────────────────────────────────────
|
|
43
|
+
// Never call `tables.X.put(partial)` directly anywhere in Flair resources.
|
|
44
|
+
// Harper put() = FULL RECORD REPLACEMENT. Missing fields are deleted permanently.
|
|
45
|
+
// Always use patchRecord() or patchRecordSilent().
|
|
46
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
type Agent @table(database: "flair") @export {
|
|
2
|
+
id: ID @primaryKey
|
|
3
|
+
name: String!
|
|
4
|
+
role: String
|
|
5
|
+
type: String @indexed
|
|
6
|
+
publicKey: String!
|
|
7
|
+
createdAt: String!
|
|
8
|
+
updatedAt: String
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
type Integration @table(database: "flair") @export {
|
|
12
|
+
id: ID @primaryKey
|
|
13
|
+
agentId: String! @indexed
|
|
14
|
+
platform: String! @indexed
|
|
15
|
+
username: String
|
|
16
|
+
userId: String
|
|
17
|
+
email: String
|
|
18
|
+
encryptedCredential: String
|
|
19
|
+
metadata: String
|
|
20
|
+
createdAt: String!
|
|
21
|
+
updatedAt: String
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type OrgEvent @table(database: "flair") @export {
|
|
2
|
+
id: ID @primaryKey
|
|
3
|
+
authorId: String! @indexed
|
|
4
|
+
kind: String! @indexed
|
|
5
|
+
scope: String @indexed
|
|
6
|
+
summary: String!
|
|
7
|
+
detail: String
|
|
8
|
+
targetIds: [String] @indexed
|
|
9
|
+
refId: String @indexed
|
|
10
|
+
createdAt: String! @indexed
|
|
11
|
+
expiresAt: String @indexed
|
|
12
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
type Memory @table(database: "flair") {
|
|
2
|
+
id: ID @primaryKey
|
|
3
|
+
agentId: String! @indexed
|
|
4
|
+
content: String!
|
|
5
|
+
contentHash: String @indexed
|
|
6
|
+
visibility: String
|
|
7
|
+
embedding: [Float] @indexed(type: "HNSW")
|
|
8
|
+
tags: [String] @indexed
|
|
9
|
+
durability: String @indexed
|
|
10
|
+
source: String
|
|
11
|
+
createdAt: String! @indexed
|
|
12
|
+
updatedAt: String
|
|
13
|
+
expiresAt: String @indexed
|
|
14
|
+
retrievalCount: Int
|
|
15
|
+
lastRetrieved: String
|
|
16
|
+
promotionStatus: String # null | "pending" | "approved" | "rejected"
|
|
17
|
+
promotedAt: String
|
|
18
|
+
promotedBy: String # authenticated agentId who approved
|
|
19
|
+
archived: Boolean @indexed
|
|
20
|
+
archivedAt: String
|
|
21
|
+
archivedBy: String # authenticated agentId who archived
|
|
22
|
+
# Learning pipeline fields
|
|
23
|
+
parentId: String # link to related memory
|
|
24
|
+
derivedFrom: [String] # source memory IDs this was reflected from
|
|
25
|
+
sessionId: String @indexed # originating session
|
|
26
|
+
lastReflected: String # ISO timestamp of last reflection pass
|
|
27
|
+
supersedes: String @indexed # ID of memory this one replaces (version chain)
|
|
28
|
+
subject: String @indexed # entity this memory is about (person, service, project)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
type Soul @table(database: "flair") {
|
|
32
|
+
id: ID @primaryKey
|
|
33
|
+
agentId: String! @indexed
|
|
34
|
+
key: String! @indexed
|
|
35
|
+
value: String!
|
|
36
|
+
priority: String # critical | high | standard | low (skill governance)
|
|
37
|
+
metadata: String # JSON blob (skill governance: source, version, hash, etc.)
|
|
38
|
+
durability: String @indexed
|
|
39
|
+
createdAt: String!
|
|
40
|
+
updatedAt: String
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
type MemoryGrant @table(database: "flair") @export {
|
|
44
|
+
id: ID @primaryKey
|
|
45
|
+
ownerId: String!
|
|
46
|
+
granteeId: String!
|
|
47
|
+
scope: String!
|
|
48
|
+
filter: String
|
|
49
|
+
createdAt: String
|
|
50
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
|
|
2
|
+
# ─── Observatory tables ───────────────────────────────────────────────────────
|
|
3
|
+
|
|
4
|
+
type ObsOffice @table(database: "flair") @export {
|
|
5
|
+
id: ID @primaryKey # e.g. "rockit"
|
|
6
|
+
name: String!
|
|
7
|
+
publicKey: String! # Ed25519 hex public key for auth verification
|
|
8
|
+
status: String @indexed # "online" | "offline" | "degraded"
|
|
9
|
+
lastSeen: String
|
|
10
|
+
agentCount: Int
|
|
11
|
+
createdAt: String!
|
|
12
|
+
updatedAt: String
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
type ObsAgentSnapshot @table(database: "flair") @export {
|
|
16
|
+
id: ID @primaryKey # "{officeId}:{agentId}"
|
|
17
|
+
officeId: String! @indexed
|
|
18
|
+
agentId: String! @indexed
|
|
19
|
+
name: String
|
|
20
|
+
role: String
|
|
21
|
+
type: String # "agent" | "human"
|
|
22
|
+
model: String
|
|
23
|
+
status: String @indexed # "active" | "idle" | "offline"
|
|
24
|
+
currentTask: String
|
|
25
|
+
lastActivity: String
|
|
26
|
+
lastHeartbeat: String
|
|
27
|
+
updatedAt: String!
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
type ObsEventFeed @table(database: "flair") @export {
|
|
31
|
+
id: ID @primaryKey # "{officeId}:{eventId}"
|
|
32
|
+
officeId: String! @indexed
|
|
33
|
+
kind: String! @indexed
|
|
34
|
+
authorId: String! @indexed
|
|
35
|
+
summary: String!
|
|
36
|
+
refId: String @indexed
|
|
37
|
+
scope: String @indexed
|
|
38
|
+
createdAt: String! @indexed
|
|
39
|
+
receivedAt: String!
|
|
40
|
+
expiresAt: String @indexed
|
|
41
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type WorkspaceState @table(database: "flair") @export {
|
|
2
|
+
id: ID @primaryKey
|
|
3
|
+
agentId: String! @indexed
|
|
4
|
+
ref: String!
|
|
5
|
+
label: String @indexed
|
|
6
|
+
provider: String!
|
|
7
|
+
timestamp: String! @indexed
|
|
8
|
+
metadata: String
|
|
9
|
+
taskId: String @indexed
|
|
10
|
+
phase: String @indexed
|
|
11
|
+
summary: String
|
|
12
|
+
filesChanged: [String]
|
|
13
|
+
createdAt: String!
|
|
14
|
+
}
|