@tpsdev-ai/flair-client 0.1.0 → 0.2.1
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/dist/client.d.ts +8 -1
- package/dist/client.js +26 -8
- package/dist/types.d.ts +2 -2
- package/package.json +1 -1
package/dist/client.d.ts
CHANGED
|
@@ -33,17 +33,24 @@ export declare class FlairClient {
|
|
|
33
33
|
declare class MemoryApi {
|
|
34
34
|
private client;
|
|
35
35
|
constructor(client: FlairClient);
|
|
36
|
-
/** Write a memory. */
|
|
36
|
+
/** Write a memory. Optionally checks for near-duplicates before writing. */
|
|
37
37
|
write(content: string, opts?: {
|
|
38
38
|
id?: string;
|
|
39
39
|
type?: MemoryType;
|
|
40
40
|
durability?: Durability;
|
|
41
41
|
tags?: string[];
|
|
42
42
|
subject?: string;
|
|
43
|
+
/** Check for similar existing memories before writing. If a near-duplicate
|
|
44
|
+
* is found (score >= threshold), returns it instead of creating a new one.
|
|
45
|
+
* Default: false (no dedup check). */
|
|
46
|
+
dedup?: boolean;
|
|
47
|
+
/** Similarity threshold for dedup. Default: 0.7 */
|
|
48
|
+
dedupThreshold?: number;
|
|
43
49
|
}): Promise<Memory>;
|
|
44
50
|
/** Search memories by meaning. */
|
|
45
51
|
search(query: string, opts?: {
|
|
46
52
|
limit?: number;
|
|
53
|
+
minScore?: number;
|
|
47
54
|
}): Promise<SearchResult[]>;
|
|
48
55
|
/** Get a memory by ID. */
|
|
49
56
|
get(id: string): Promise<Memory | null>;
|
package/dist/client.js
CHANGED
|
@@ -20,8 +20,8 @@ export class FlairClient {
|
|
|
20
20
|
keyPath;
|
|
21
21
|
timeoutMs;
|
|
22
22
|
constructor(config) {
|
|
23
|
-
this.url = (config.url ?? DEFAULT_URL).replace(/\/$/, "");
|
|
24
|
-
this.agentId = config.agentId;
|
|
23
|
+
this.url = (config.url ?? process.env.FLAIR_URL ?? DEFAULT_URL).replace(/\/$/, "");
|
|
24
|
+
this.agentId = config.agentId || process.env.FLAIR_AGENT_ID || "";
|
|
25
25
|
this.keyPath = config.keyPath;
|
|
26
26
|
this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT;
|
|
27
27
|
this.memory = new MemoryApi(this);
|
|
@@ -77,10 +77,22 @@ class MemoryApi {
|
|
|
77
77
|
constructor(client) {
|
|
78
78
|
this.client = client;
|
|
79
79
|
}
|
|
80
|
-
/** Write a memory. */
|
|
80
|
+
/** Write a memory. Optionally checks for near-duplicates before writing. */
|
|
81
81
|
async write(content, opts = {}) {
|
|
82
|
+
// Near-duplicate check — skip for very short content where similarity
|
|
83
|
+
// is unreliable (e.g., "ok", "thanks" would match each other)
|
|
84
|
+
if (opts.dedup && content.length >= 20) {
|
|
85
|
+
const threshold = opts.dedupThreshold ?? 0.7;
|
|
86
|
+
const existing = await this.search(content, { limit: 1, minScore: threshold });
|
|
87
|
+
if (existing.length > 0) {
|
|
88
|
+
// Return the existing memory instead of creating a duplicate
|
|
89
|
+
const match = await this.get(existing[0].id);
|
|
90
|
+
if (match)
|
|
91
|
+
return match;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
82
94
|
const id = opts.id ?? `${this.client.agentId}-${Date.now()}`;
|
|
83
|
-
|
|
95
|
+
const record = {
|
|
84
96
|
id,
|
|
85
97
|
agentId: this.client.agentId,
|
|
86
98
|
content,
|
|
@@ -89,20 +101,26 @@ class MemoryApi {
|
|
|
89
101
|
tags: opts.tags ?? [],
|
|
90
102
|
subject: opts.subject,
|
|
91
103
|
createdAt: new Date().toISOString(),
|
|
92
|
-
}
|
|
104
|
+
};
|
|
105
|
+
await this.client.request("PUT", `/Memory/${id}`, record);
|
|
106
|
+
// Harper PUT returns {} — return the record we constructed
|
|
107
|
+
return record;
|
|
93
108
|
}
|
|
94
109
|
/** Search memories by meaning. */
|
|
95
110
|
async search(query, opts = {}) {
|
|
96
111
|
const result = await this.client.request("POST", "/SemanticSearch", { agentId: this.client.agentId, q: query, limit: opts.limit ?? 5 });
|
|
97
|
-
|
|
112
|
+
const minScore = opts.minScore ?? 0;
|
|
113
|
+
return (result.results ?? [])
|
|
114
|
+
.map((r) => ({
|
|
98
115
|
id: r.id ?? r.memory?.id ?? "",
|
|
99
116
|
content: r.content ?? r.memory?.content ?? "",
|
|
100
|
-
score: r.score ?? r.similarity ?? 0,
|
|
117
|
+
score: r._score ?? r.score ?? r.similarity ?? 0,
|
|
101
118
|
type: r.type ?? r.memory?.type,
|
|
102
119
|
durability: r.durability ?? r.memory?.durability,
|
|
103
120
|
tags: r.tags ?? r.memory?.tags,
|
|
104
121
|
createdAt: r.createdAt ?? r.memory?.createdAt,
|
|
105
|
-
}))
|
|
122
|
+
}))
|
|
123
|
+
.filter((r) => r.score >= minScore);
|
|
106
124
|
}
|
|
107
125
|
/** Get a memory by ID. */
|
|
108
126
|
async get(id) {
|
package/dist/types.d.ts
CHANGED
|
@@ -43,8 +43,8 @@ export interface BootstrapResult {
|
|
|
43
43
|
export interface FlairClientConfig {
|
|
44
44
|
/** Flair server URL. Default: http://localhost:9926 */
|
|
45
45
|
url?: string;
|
|
46
|
-
/** Agent ID for authentication and data scoping. */
|
|
47
|
-
agentId
|
|
46
|
+
/** Agent ID for authentication and data scoping. Falls back to FLAIR_AGENT_ID env var. */
|
|
47
|
+
agentId?: string;
|
|
48
48
|
/** Path to Ed25519 private key file. Auto-resolved if omitted. */
|
|
49
49
|
keyPath?: string;
|
|
50
50
|
/** Request timeout in ms. Default: 10000 */
|
package/package.json
CHANGED