@tpsdev-ai/flair-client 0.1.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/README.md +118 -0
- package/dist/auth.d.ts +13 -0
- package/dist/auth.js +42 -0
- package/dist/client.d.ts +76 -0
- package/dist/client.js +184 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +2 -0
- package/dist/types.d.ts +52 -0
- package/dist/types.js +1 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# @tpsdev-ai/flair-client
|
|
2
|
+
|
|
3
|
+
Lightweight client for [Flair](https://tps.dev/#flair) — identity, memory, and soul for AI agents.
|
|
4
|
+
|
|
5
|
+
Zero heavy dependencies. Just Ed25519 auth + HTTP. Works with any Flair instance, local or remote.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install @tpsdev-ai/flair-client
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
```ts
|
|
16
|
+
import { FlairClient } from '@tpsdev-ai/flair-client'
|
|
17
|
+
|
|
18
|
+
const flair = new FlairClient({
|
|
19
|
+
url: 'http://localhost:9926', // or remote: https://flair.example.com
|
|
20
|
+
agentId: 'my-agent',
|
|
21
|
+
// keyPath auto-resolved from ~/.flair/keys/my-agent.key
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
// Write a memory
|
|
25
|
+
await flair.memory.write('Harper v5 sandbox blocks bare imports')
|
|
26
|
+
|
|
27
|
+
// Search by meaning
|
|
28
|
+
const results = await flair.memory.search('native module loading issues')
|
|
29
|
+
// → [{ content: 'Harper v5 sandbox blocks bare imports', score: 0.72, ... }]
|
|
30
|
+
|
|
31
|
+
// Cold-start bootstrap (soul + recent memories)
|
|
32
|
+
const ctx = await flair.bootstrap({ maxTokens: 4000 })
|
|
33
|
+
console.log(ctx.context) // formatted context block
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Memory API
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
// Write with options
|
|
40
|
+
await flair.memory.write('deploy procedure changed', {
|
|
41
|
+
type: 'decision',
|
|
42
|
+
durability: 'persistent',
|
|
43
|
+
tags: ['ops', 'deploy'],
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
// Get by ID
|
|
47
|
+
const mem = await flair.memory.get('my-agent-1234567890')
|
|
48
|
+
|
|
49
|
+
// List recent
|
|
50
|
+
const recent = await flair.memory.list({ limit: 10 })
|
|
51
|
+
|
|
52
|
+
// Delete
|
|
53
|
+
await flair.memory.delete('my-agent-1234567890')
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Soul API
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
// Set personality/values
|
|
60
|
+
await flair.soul.set('role', 'Security reviewer, meticulous and skeptical')
|
|
61
|
+
await flair.soul.set('tone', 'Direct, technical, no fluff')
|
|
62
|
+
|
|
63
|
+
// Read
|
|
64
|
+
const role = await flair.soul.get('role')
|
|
65
|
+
|
|
66
|
+
// List all
|
|
67
|
+
const entries = await flair.soul.list()
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Auth
|
|
71
|
+
|
|
72
|
+
Flair uses Ed25519 signatures. The client auto-discovers your key from:
|
|
73
|
+
|
|
74
|
+
1. `keyPath` option (explicit)
|
|
75
|
+
2. `FLAIR_KEY_DIR` env + `{agentId}.key`
|
|
76
|
+
3. `~/.flair/keys/{agentId}.key`
|
|
77
|
+
4. `~/.tps/secrets/flair/{agentId}-priv.key`
|
|
78
|
+
|
|
79
|
+
Generate a key with the Flair CLI:
|
|
80
|
+
|
|
81
|
+
```bash
|
|
82
|
+
npm install -g @tpsdev-ai/flair
|
|
83
|
+
flair init && flair agent add my-agent
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Use with Claude Code
|
|
87
|
+
|
|
88
|
+
Add to your `CLAUDE.md`:
|
|
89
|
+
|
|
90
|
+
```markdown
|
|
91
|
+
## Memory (Flair)
|
|
92
|
+
You have persistent memory. Use it.
|
|
93
|
+
- Bootstrap on start: `npx @tpsdev-ai/flair-client bootstrap --agent $AGENT_ID`
|
|
94
|
+
- Store lessons: `npx @tpsdev-ai/flair-client write --agent $AGENT_ID "what you learned"`
|
|
95
|
+
- Search: `npx @tpsdev-ai/flair-client search --agent $AGENT_ID "your query"`
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
Or use the Flair CLI directly:
|
|
99
|
+
|
|
100
|
+
```markdown
|
|
101
|
+
## Memory (Flair)
|
|
102
|
+
- `flair memory search --agent my-agent -q "your query"`
|
|
103
|
+
- `flair memory add --agent my-agent --content "what to remember"`
|
|
104
|
+
- `flair memory list --agent my-agent --limit 20`
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## Configuration
|
|
108
|
+
|
|
109
|
+
| Option | Env | Default | Description |
|
|
110
|
+
|--------|-----|---------|-------------|
|
|
111
|
+
| `url` | `FLAIR_URL` | `http://localhost:9926` | Flair server URL |
|
|
112
|
+
| `agentId` | `FLAIR_AGENT_ID` | — | Agent identifier |
|
|
113
|
+
| `keyPath` | `FLAIR_KEY_DIR` | auto-resolved | Private key path |
|
|
114
|
+
| `timeoutMs` | — | `10000` | Request timeout |
|
|
115
|
+
|
|
116
|
+
## License
|
|
117
|
+
|
|
118
|
+
[Apache 2.0](../../LICENSE)
|
package/dist/auth.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ed25519 request signing for Flair.
|
|
3
|
+
*
|
|
4
|
+
* Signs requests with: agentId:timestamp:nonce:METHOD:/path
|
|
5
|
+
* Produces: TPS-Ed25519 agentId:timestamp:nonce:base64(signature)
|
|
6
|
+
*/
|
|
7
|
+
import { type KeyObject } from "node:crypto";
|
|
8
|
+
/** Resolve an Ed25519 private key from a file (base64 PKCS8 DER or raw 32-byte seed). */
|
|
9
|
+
export declare function loadPrivateKey(path: string): KeyObject;
|
|
10
|
+
/** Find the agent's private key file from standard locations. */
|
|
11
|
+
export declare function resolveKeyPath(agentId: string, keyPath?: string): string | null;
|
|
12
|
+
/** Build an Authorization header for a Flair request. */
|
|
13
|
+
export declare function signRequest(agentId: string, privateKey: KeyObject, method: string, path: string): string;
|
package/dist/auth.js
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ed25519 request signing for Flair.
|
|
3
|
+
*
|
|
4
|
+
* Signs requests with: agentId:timestamp:nonce:METHOD:/path
|
|
5
|
+
* Produces: TPS-Ed25519 agentId:timestamp:nonce:base64(signature)
|
|
6
|
+
*/
|
|
7
|
+
import { randomUUID, sign as ed25519Sign, createPrivateKey } from "node:crypto";
|
|
8
|
+
import { readFileSync, existsSync } from "node:fs";
|
|
9
|
+
import { resolve } from "node:path";
|
|
10
|
+
import { homedir } from "node:os";
|
|
11
|
+
const PKCS8_ED25519_PREFIX = Buffer.from("302e020100300506032b657004220420", "hex");
|
|
12
|
+
/** Resolve an Ed25519 private key from a file (base64 PKCS8 DER or raw 32-byte seed). */
|
|
13
|
+
export function loadPrivateKey(path) {
|
|
14
|
+
const raw = readFileSync(path);
|
|
15
|
+
// Try as base64-encoded PKCS8 DER first
|
|
16
|
+
const decoded = raw.length === 32 ? raw : Buffer.from(raw.toString("utf-8").trim(), "base64");
|
|
17
|
+
const der = decoded.length === 32
|
|
18
|
+
? Buffer.concat([PKCS8_ED25519_PREFIX, decoded])
|
|
19
|
+
: decoded;
|
|
20
|
+
return createPrivateKey({ key: der, format: "der", type: "pkcs8" });
|
|
21
|
+
}
|
|
22
|
+
/** Find the agent's private key file from standard locations. */
|
|
23
|
+
export function resolveKeyPath(agentId, keyPath) {
|
|
24
|
+
if (keyPath) {
|
|
25
|
+
const resolved = resolve(keyPath.replace(/^~/, homedir()));
|
|
26
|
+
return existsSync(resolved) ? resolved : null;
|
|
27
|
+
}
|
|
28
|
+
const candidates = [
|
|
29
|
+
process.env.FLAIR_KEY_DIR ? resolve(process.env.FLAIR_KEY_DIR, `${agentId}.key`) : null,
|
|
30
|
+
resolve(homedir(), ".flair", "keys", `${agentId}.key`),
|
|
31
|
+
resolve(homedir(), ".tps", "secrets", "flair", `${agentId}-priv.key`),
|
|
32
|
+
].filter(Boolean);
|
|
33
|
+
return candidates.find(existsSync) ?? null;
|
|
34
|
+
}
|
|
35
|
+
/** Build an Authorization header for a Flair request. */
|
|
36
|
+
export function signRequest(agentId, privateKey, method, path) {
|
|
37
|
+
const ts = Date.now().toString();
|
|
38
|
+
const nonce = randomUUID();
|
|
39
|
+
const payload = `${agentId}:${ts}:${nonce}:${method}:${path}`;
|
|
40
|
+
const sig = ed25519Sign(null, Buffer.from(payload), privateKey);
|
|
41
|
+
return `TPS-Ed25519 ${agentId}:${ts}:${nonce}:${sig.toString("base64")}`;
|
|
42
|
+
}
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flair client — lightweight, zero-dep HTTP client for Flair.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* const flair = new FlairClient({ agentId: 'my-agent' })
|
|
6
|
+
* await flair.memory.write('learned something')
|
|
7
|
+
* const results = await flair.memory.search('that thing')
|
|
8
|
+
* const ctx = await flair.bootstrap({ maxTokens: 4000 })
|
|
9
|
+
*/
|
|
10
|
+
import type { FlairClientConfig, Memory, MemoryType, Durability, SoulEntry, SearchResult, BootstrapResult } from "./types.js";
|
|
11
|
+
export declare class FlairClient {
|
|
12
|
+
readonly url: string;
|
|
13
|
+
readonly agentId: string;
|
|
14
|
+
readonly memory: MemoryApi;
|
|
15
|
+
readonly soul: SoulApi;
|
|
16
|
+
private privateKey;
|
|
17
|
+
private keyResolved;
|
|
18
|
+
private keyPath;
|
|
19
|
+
private timeoutMs;
|
|
20
|
+
constructor(config: FlairClientConfig);
|
|
21
|
+
private resolveKey;
|
|
22
|
+
/** Make an authenticated request to Flair. */
|
|
23
|
+
request<T = unknown>(method: string, path: string, body?: unknown): Promise<T>;
|
|
24
|
+
/** Cold-start bootstrap — get soul + recent memories as a formatted context block. */
|
|
25
|
+
bootstrap(opts?: {
|
|
26
|
+
maxTokens?: number;
|
|
27
|
+
}): Promise<BootstrapResult>;
|
|
28
|
+
/** Health check. */
|
|
29
|
+
health(): Promise<{
|
|
30
|
+
status: string;
|
|
31
|
+
}>;
|
|
32
|
+
}
|
|
33
|
+
declare class MemoryApi {
|
|
34
|
+
private client;
|
|
35
|
+
constructor(client: FlairClient);
|
|
36
|
+
/** Write a memory. */
|
|
37
|
+
write(content: string, opts?: {
|
|
38
|
+
id?: string;
|
|
39
|
+
type?: MemoryType;
|
|
40
|
+
durability?: Durability;
|
|
41
|
+
tags?: string[];
|
|
42
|
+
subject?: string;
|
|
43
|
+
}): Promise<Memory>;
|
|
44
|
+
/** Search memories by meaning. */
|
|
45
|
+
search(query: string, opts?: {
|
|
46
|
+
limit?: number;
|
|
47
|
+
}): Promise<SearchResult[]>;
|
|
48
|
+
/** Get a memory by ID. */
|
|
49
|
+
get(id: string): Promise<Memory | null>;
|
|
50
|
+
/** List recent memories. */
|
|
51
|
+
list(opts?: {
|
|
52
|
+
limit?: number;
|
|
53
|
+
type?: MemoryType;
|
|
54
|
+
durability?: Durability;
|
|
55
|
+
}): Promise<Memory[]>;
|
|
56
|
+
/** Delete a memory. */
|
|
57
|
+
delete(id: string): Promise<void>;
|
|
58
|
+
}
|
|
59
|
+
declare class SoulApi {
|
|
60
|
+
private client;
|
|
61
|
+
constructor(client: FlairClient);
|
|
62
|
+
/** Set a soul entry (key-value personality/values). */
|
|
63
|
+
set(key: string, value: string): Promise<SoulEntry>;
|
|
64
|
+
/** Get a soul entry. */
|
|
65
|
+
get(key: string): Promise<SoulEntry | null>;
|
|
66
|
+
/** List all soul entries. */
|
|
67
|
+
list(): Promise<SoulEntry[]>;
|
|
68
|
+
}
|
|
69
|
+
export declare class FlairError extends Error {
|
|
70
|
+
readonly method: string;
|
|
71
|
+
readonly path: string;
|
|
72
|
+
readonly status: number;
|
|
73
|
+
readonly body: string;
|
|
74
|
+
constructor(method: string, path: string, status: number, body: string);
|
|
75
|
+
}
|
|
76
|
+
export {};
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Flair client — lightweight, zero-dep HTTP client for Flair.
|
|
3
|
+
*
|
|
4
|
+
* Usage:
|
|
5
|
+
* const flair = new FlairClient({ agentId: 'my-agent' })
|
|
6
|
+
* await flair.memory.write('learned something')
|
|
7
|
+
* const results = await flair.memory.search('that thing')
|
|
8
|
+
* const ctx = await flair.bootstrap({ maxTokens: 4000 })
|
|
9
|
+
*/
|
|
10
|
+
import { loadPrivateKey, resolveKeyPath, signRequest } from "./auth.js";
|
|
11
|
+
const DEFAULT_URL = "http://localhost:9926";
|
|
12
|
+
const DEFAULT_TIMEOUT = 10_000;
|
|
13
|
+
export class FlairClient {
|
|
14
|
+
url;
|
|
15
|
+
agentId;
|
|
16
|
+
memory;
|
|
17
|
+
soul;
|
|
18
|
+
privateKey = null;
|
|
19
|
+
keyResolved = false;
|
|
20
|
+
keyPath;
|
|
21
|
+
timeoutMs;
|
|
22
|
+
constructor(config) {
|
|
23
|
+
this.url = (config.url ?? DEFAULT_URL).replace(/\/$/, "");
|
|
24
|
+
this.agentId = config.agentId;
|
|
25
|
+
this.keyPath = config.keyPath;
|
|
26
|
+
this.timeoutMs = config.timeoutMs ?? DEFAULT_TIMEOUT;
|
|
27
|
+
this.memory = new MemoryApi(this);
|
|
28
|
+
this.soul = new SoulApi(this);
|
|
29
|
+
}
|
|
30
|
+
resolveKey() {
|
|
31
|
+
if (this.keyResolved)
|
|
32
|
+
return this.privateKey;
|
|
33
|
+
this.keyResolved = true;
|
|
34
|
+
const path = resolveKeyPath(this.agentId, this.keyPath);
|
|
35
|
+
if (path) {
|
|
36
|
+
// Key file exists — failure to parse is a hard error.
|
|
37
|
+
// Silent fallback to unauthenticated would be a security risk.
|
|
38
|
+
this.privateKey = loadPrivateKey(path);
|
|
39
|
+
}
|
|
40
|
+
return this.privateKey;
|
|
41
|
+
}
|
|
42
|
+
/** Make an authenticated request to Flair. */
|
|
43
|
+
async request(method, path, body) {
|
|
44
|
+
const headers = { "Content-Type": "application/json" };
|
|
45
|
+
const key = this.resolveKey();
|
|
46
|
+
if (key) {
|
|
47
|
+
headers["Authorization"] = signRequest(this.agentId, key, method, path);
|
|
48
|
+
}
|
|
49
|
+
const res = await fetch(`${this.url}${path}`, {
|
|
50
|
+
method,
|
|
51
|
+
headers,
|
|
52
|
+
body: body !== undefined ? JSON.stringify(body) : undefined,
|
|
53
|
+
signal: AbortSignal.timeout(this.timeoutMs),
|
|
54
|
+
});
|
|
55
|
+
if (!res.ok) {
|
|
56
|
+
const text = await res.text().catch(() => "");
|
|
57
|
+
throw new FlairError(method, path, res.status, text.slice(0, 500));
|
|
58
|
+
}
|
|
59
|
+
const text = await res.text();
|
|
60
|
+
return text ? JSON.parse(text) : {};
|
|
61
|
+
}
|
|
62
|
+
/** Cold-start bootstrap — get soul + recent memories as a formatted context block. */
|
|
63
|
+
async bootstrap(opts = {}) {
|
|
64
|
+
return this.request("POST", "/BootstrapMemories", {
|
|
65
|
+
agentId: this.agentId,
|
|
66
|
+
maxTokens: opts.maxTokens ?? 4000,
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
/** Health check. */
|
|
70
|
+
async health() {
|
|
71
|
+
return this.request("GET", "/Health");
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// ─── Memory API ─────────────────────────────────────────────────────────────
|
|
75
|
+
class MemoryApi {
|
|
76
|
+
client;
|
|
77
|
+
constructor(client) {
|
|
78
|
+
this.client = client;
|
|
79
|
+
}
|
|
80
|
+
/** Write a memory. */
|
|
81
|
+
async write(content, opts = {}) {
|
|
82
|
+
const id = opts.id ?? `${this.client.agentId}-${Date.now()}`;
|
|
83
|
+
return this.client.request("PUT", `/Memory/${id}`, {
|
|
84
|
+
id,
|
|
85
|
+
agentId: this.client.agentId,
|
|
86
|
+
content,
|
|
87
|
+
type: opts.type ?? "session",
|
|
88
|
+
durability: opts.durability ?? "standard",
|
|
89
|
+
tags: opts.tags ?? [],
|
|
90
|
+
subject: opts.subject,
|
|
91
|
+
createdAt: new Date().toISOString(),
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
/** Search memories by meaning. */
|
|
95
|
+
async search(query, opts = {}) {
|
|
96
|
+
const result = await this.client.request("POST", "/SemanticSearch", { agentId: this.client.agentId, q: query, limit: opts.limit ?? 5 });
|
|
97
|
+
return (result.results ?? []).map((r) => ({
|
|
98
|
+
id: r.id ?? r.memory?.id ?? "",
|
|
99
|
+
content: r.content ?? r.memory?.content ?? "",
|
|
100
|
+
score: r.score ?? r.similarity ?? 0,
|
|
101
|
+
type: r.type ?? r.memory?.type,
|
|
102
|
+
durability: r.durability ?? r.memory?.durability,
|
|
103
|
+
tags: r.tags ?? r.memory?.tags,
|
|
104
|
+
createdAt: r.createdAt ?? r.memory?.createdAt,
|
|
105
|
+
}));
|
|
106
|
+
}
|
|
107
|
+
/** Get a memory by ID. */
|
|
108
|
+
async get(id) {
|
|
109
|
+
try {
|
|
110
|
+
return await this.client.request("GET", `/Memory/${id}`);
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
if (e instanceof FlairError && e.status === 404)
|
|
114
|
+
return null;
|
|
115
|
+
throw e;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/** List recent memories. */
|
|
119
|
+
async list(opts = {}) {
|
|
120
|
+
const params = new URLSearchParams();
|
|
121
|
+
params.set("agentId", this.client.agentId);
|
|
122
|
+
if (opts.limit)
|
|
123
|
+
params.set("limit", String(opts.limit));
|
|
124
|
+
if (opts.type)
|
|
125
|
+
params.set("type", opts.type);
|
|
126
|
+
if (opts.durability)
|
|
127
|
+
params.set("durability", opts.durability);
|
|
128
|
+
return this.client.request("GET", `/Memory?${params}`);
|
|
129
|
+
}
|
|
130
|
+
/** Delete a memory. */
|
|
131
|
+
async delete(id) {
|
|
132
|
+
await this.client.request("DELETE", `/Memory/${id}`);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
// ─── Soul API ───────────────────────────────────────────────────────────────
|
|
136
|
+
class SoulApi {
|
|
137
|
+
client;
|
|
138
|
+
constructor(client) {
|
|
139
|
+
this.client = client;
|
|
140
|
+
}
|
|
141
|
+
/** Set a soul entry (key-value personality/values). */
|
|
142
|
+
async set(key, value) {
|
|
143
|
+
const id = `${this.client.agentId}:${key}`;
|
|
144
|
+
return this.client.request("PUT", `/Soul/${encodeURIComponent(id)}`, {
|
|
145
|
+
id,
|
|
146
|
+
agentId: this.client.agentId,
|
|
147
|
+
key,
|
|
148
|
+
value,
|
|
149
|
+
createdAt: new Date().toISOString(),
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/** Get a soul entry. */
|
|
153
|
+
async get(key) {
|
|
154
|
+
const id = `${this.client.agentId}:${key}`;
|
|
155
|
+
try {
|
|
156
|
+
return await this.client.request("GET", `/Soul/${encodeURIComponent(id)}`);
|
|
157
|
+
}
|
|
158
|
+
catch (e) {
|
|
159
|
+
if (e instanceof FlairError && e.status === 404)
|
|
160
|
+
return null;
|
|
161
|
+
throw e;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
/** List all soul entries. */
|
|
165
|
+
async list() {
|
|
166
|
+
const params = new URLSearchParams({ agentId: this.client.agentId });
|
|
167
|
+
return this.client.request("GET", `/Soul?${params}`);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// ─── Error ──────────────────────────────────────────────────────────────────
|
|
171
|
+
export class FlairError extends Error {
|
|
172
|
+
method;
|
|
173
|
+
path;
|
|
174
|
+
status;
|
|
175
|
+
body;
|
|
176
|
+
constructor(method, path, status, body) {
|
|
177
|
+
super(`Flair ${method} ${path} → ${status}: ${body}`);
|
|
178
|
+
this.method = method;
|
|
179
|
+
this.path = path;
|
|
180
|
+
this.status = status;
|
|
181
|
+
this.body = body;
|
|
182
|
+
this.name = "FlairError";
|
|
183
|
+
}
|
|
184
|
+
}
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Memory durability levels. */
|
|
2
|
+
export type Durability = "permanent" | "persistent" | "standard" | "ephemeral";
|
|
3
|
+
/** Memory type classification. */
|
|
4
|
+
export type MemoryType = "session" | "lesson" | "decision" | "preference" | "fact" | "goal";
|
|
5
|
+
/** A memory record. */
|
|
6
|
+
export interface Memory {
|
|
7
|
+
id: string;
|
|
8
|
+
agentId: string;
|
|
9
|
+
content: string;
|
|
10
|
+
type: MemoryType;
|
|
11
|
+
durability: Durability;
|
|
12
|
+
tags: string[];
|
|
13
|
+
subject?: string;
|
|
14
|
+
createdAt: string;
|
|
15
|
+
updatedAt?: string;
|
|
16
|
+
}
|
|
17
|
+
/** A soul entry (persistent personality/values). */
|
|
18
|
+
export interface SoulEntry {
|
|
19
|
+
id: string;
|
|
20
|
+
agentId: string;
|
|
21
|
+
key: string;
|
|
22
|
+
value: string;
|
|
23
|
+
createdAt: string;
|
|
24
|
+
}
|
|
25
|
+
/** Semantic search result. */
|
|
26
|
+
export interface SearchResult {
|
|
27
|
+
id: string;
|
|
28
|
+
content: string;
|
|
29
|
+
score: number;
|
|
30
|
+
type?: MemoryType;
|
|
31
|
+
durability?: Durability;
|
|
32
|
+
tags?: string[];
|
|
33
|
+
createdAt?: string;
|
|
34
|
+
}
|
|
35
|
+
/** Bootstrap response — formatted context block. */
|
|
36
|
+
export interface BootstrapResult {
|
|
37
|
+
context: string;
|
|
38
|
+
memoryCount: number;
|
|
39
|
+
soulCount: number;
|
|
40
|
+
tokenEstimate: number;
|
|
41
|
+
}
|
|
42
|
+
/** Client configuration. */
|
|
43
|
+
export interface FlairClientConfig {
|
|
44
|
+
/** Flair server URL. Default: http://localhost:9926 */
|
|
45
|
+
url?: string;
|
|
46
|
+
/** Agent ID for authentication and data scoping. */
|
|
47
|
+
agentId: string;
|
|
48
|
+
/** Path to Ed25519 private key file. Auto-resolved if omitted. */
|
|
49
|
+
keyPath?: string;
|
|
50
|
+
/** Request timeout in ms. Default: 10000 */
|
|
51
|
+
timeoutMs?: number;
|
|
52
|
+
}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tpsdev-ai/flair-client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Lightweight client for Flair — identity, memory, and soul for AI agents. Zero heavy dependencies.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"import": "./dist/index.js",
|
|
11
|
+
"types": "./dist/index.d.ts"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/",
|
|
16
|
+
"LICENSE",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsc",
|
|
21
|
+
"prepublishOnly": "npm run build"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public"
|
|
25
|
+
},
|
|
26
|
+
"engines": {
|
|
27
|
+
"node": ">=18"
|
|
28
|
+
},
|
|
29
|
+
"license": "Apache-2.0",
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/tpsdev-ai/flair.git",
|
|
33
|
+
"directory": "packages/flair-client"
|
|
34
|
+
},
|
|
35
|
+
"homepage": "https://tps.dev/#flair",
|
|
36
|
+
"keywords": [
|
|
37
|
+
"flair",
|
|
38
|
+
"ai",
|
|
39
|
+
"agent",
|
|
40
|
+
"memory",
|
|
41
|
+
"identity",
|
|
42
|
+
"client",
|
|
43
|
+
"ed25519"
|
|
44
|
+
],
|
|
45
|
+
"devDependencies": {
|
|
46
|
+
"typescript": "5.9.3"
|
|
47
|
+
}
|
|
48
|
+
}
|