@hyperspell/openclaw-hyperspell 0.11.1 → 0.13.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 +37 -1
- package/dist/client.js +341 -0
- package/dist/commands/setup.js +569 -0
- package/dist/commands/slash.js +159 -0
- package/dist/config.js +349 -0
- package/{graph/cron.ts → dist/graph/cron.js} +11 -15
- package/dist/graph/index.js +4 -0
- package/dist/graph/ops.js +221 -0
- package/dist/graph/state.js +68 -0
- package/dist/graph/tools.js +87 -0
- package/dist/hooks/auto-context.js +199 -0
- package/dist/hooks/auto-trace.js +141 -0
- package/dist/hooks/emotional-state.js +155 -0
- package/dist/hooks/memory-sync.js +54 -0
- package/dist/hooks/startup-orientation.js +156 -0
- package/dist/index.js +132 -0
- package/dist/lib/browser.js +29 -0
- package/dist/lib/sender.js +173 -0
- package/dist/lib/voice-id.js +22 -0
- package/dist/logger.js +32 -0
- package/dist/sync/markdown.js +151 -0
- package/dist/tools/remember.js +97 -0
- package/dist/tools/search.js +87 -0
- package/openclaw.plugin.json +17 -1
- package/package.json +7 -12
- package/client.ts +0 -566
- package/commands/setup.ts +0 -673
- package/commands/slash.ts +0 -198
- package/config.test.ts +0 -202
- package/config.ts +0 -497
- package/graph/index.ts +0 -5
- package/graph/ops.ts +0 -259
- package/graph/state.ts +0 -79
- package/graph/tools.ts +0 -117
- package/hooks/auto-context.ts +0 -272
- package/hooks/auto-trace.test.ts +0 -81
- package/hooks/auto-trace.ts +0 -197
- package/hooks/emotional-state.test.ts +0 -160
- package/hooks/emotional-state.ts +0 -179
- package/hooks/memory-sync.ts +0 -65
- package/index.ts +0 -152
- package/lib/browser.ts +0 -31
- package/lib/sender.test.ts +0 -234
- package/lib/sender.ts +0 -234
- package/lib/voice-id.ts +0 -39
- package/logger.ts +0 -41
- package/sync/markdown.ts +0 -186
- package/tools/remember.ts +0 -132
- package/tools/search.ts +0 -131
- package/types/openclaw.d.ts +0 -76
package/client.ts
DELETED
|
@@ -1,566 +0,0 @@
|
|
|
1
|
-
import Hyperspell from "hyperspell";
|
|
2
|
-
import type {
|
|
3
|
-
HyperspellConfig,
|
|
4
|
-
HyperspellSource,
|
|
5
|
-
ScopeName,
|
|
6
|
-
} from "./config.ts";
|
|
7
|
-
import { normalizeScope } from "./config.ts";
|
|
8
|
-
import { log } from "./logger.ts";
|
|
9
|
-
|
|
10
|
-
export type Highlight = {
|
|
11
|
-
id: string;
|
|
12
|
-
score: number;
|
|
13
|
-
text: string;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export type SearchResult = {
|
|
17
|
-
resourceId: string;
|
|
18
|
-
title: string | null;
|
|
19
|
-
source: HyperspellSource;
|
|
20
|
-
score: number | null;
|
|
21
|
-
url: string | null;
|
|
22
|
-
createdAt: string | null;
|
|
23
|
-
highlights: Highlight[];
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export type SearchWithAnswerResult = {
|
|
27
|
-
answer: string | null;
|
|
28
|
-
documents: SearchResult[];
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export type Integration = {
|
|
32
|
-
id: string;
|
|
33
|
-
name: string;
|
|
34
|
-
provider: HyperspellSource;
|
|
35
|
-
icon: string | null;
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export type Connection = {
|
|
39
|
-
id: string;
|
|
40
|
-
integrationId: string;
|
|
41
|
-
label: string | null;
|
|
42
|
-
provider: HyperspellSource;
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export type EmotionalStateResponse = {
|
|
46
|
-
resourceId: string
|
|
47
|
-
summary: string
|
|
48
|
-
extractedAt: string
|
|
49
|
-
sessionId: string | null
|
|
50
|
-
relationshipId: string | null
|
|
51
|
-
status: string
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
export type EmotionalStateLatest = {
|
|
55
|
-
resourceId: string
|
|
56
|
-
summary: string
|
|
57
|
-
extractedAt: string
|
|
58
|
-
sessionId: string | null
|
|
59
|
-
relationshipId: string | null
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
const API_BASE_URL = "https://api.hyperspell.com"
|
|
63
|
-
|
|
64
|
-
export class HyperspellClient {
|
|
65
|
-
private client: Hyperspell;
|
|
66
|
-
private config: HyperspellConfig;
|
|
67
|
-
|
|
68
|
-
constructor(config: HyperspellConfig) {
|
|
69
|
-
this.config = config;
|
|
70
|
-
this.client = new Hyperspell({
|
|
71
|
-
apiKey: config.apiKey,
|
|
72
|
-
userID: config.userId,
|
|
73
|
-
});
|
|
74
|
-
log.info(
|
|
75
|
-
`client initialized${config.userId ? ` for user ${config.userId}` : ""}`,
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
private rawHeaders(): Record<string, string> {
|
|
80
|
-
const headers: Record<string, string> = {
|
|
81
|
-
"Content-Type": "application/json",
|
|
82
|
-
Authorization: `Bearer ${this.config.apiKey}`,
|
|
83
|
-
};
|
|
84
|
-
if (this.config.userId) {
|
|
85
|
-
headers["X-As-User"] = this.config.userId;
|
|
86
|
-
}
|
|
87
|
-
return headers;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
private requestOptions(userId?: string) {
|
|
91
|
-
if (!userId) return undefined;
|
|
92
|
-
return { headers: { "X-As-User": userId } };
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
async search(
|
|
96
|
-
query: string,
|
|
97
|
-
options?: {
|
|
98
|
-
limit?: number;
|
|
99
|
-
sources?: HyperspellSource[];
|
|
100
|
-
after?: string;
|
|
101
|
-
before?: string;
|
|
102
|
-
userId?: string;
|
|
103
|
-
filter?: Record<string, unknown>;
|
|
104
|
-
},
|
|
105
|
-
): Promise<SearchResult[]> {
|
|
106
|
-
const limit = options?.limit ?? this.config.maxResults;
|
|
107
|
-
const sources =
|
|
108
|
-
options?.sources ??
|
|
109
|
-
(this.config.sources.length > 0 ? this.config.sources : undefined);
|
|
110
|
-
|
|
111
|
-
log.debugRequest("memories.search", {
|
|
112
|
-
query,
|
|
113
|
-
limit,
|
|
114
|
-
sources,
|
|
115
|
-
after: options?.after,
|
|
116
|
-
before: options?.before,
|
|
117
|
-
userId: options?.userId,
|
|
118
|
-
filter: options?.filter,
|
|
119
|
-
});
|
|
120
|
-
|
|
121
|
-
const response = await this.client.memories.search(
|
|
122
|
-
{
|
|
123
|
-
query,
|
|
124
|
-
sources,
|
|
125
|
-
options: {
|
|
126
|
-
max_results: limit,
|
|
127
|
-
...(options?.after ? { after: options.after } : {}),
|
|
128
|
-
...(options?.before ? { before: options.before } : {}),
|
|
129
|
-
...(options?.filter ? { filter: options.filter } : {}),
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
this.requestOptions(options?.userId),
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
const results: SearchResult[] = response.documents.map((doc) => {
|
|
136
|
-
const raw = doc as typeof doc & {
|
|
137
|
-
highlights?: Array<{ id: string; score: number; text: string }>;
|
|
138
|
-
};
|
|
139
|
-
return {
|
|
140
|
-
resourceId: doc.resource_id,
|
|
141
|
-
title: doc.title ?? null,
|
|
142
|
-
source: doc.source as HyperspellSource,
|
|
143
|
-
score: doc.score ?? null,
|
|
144
|
-
url: (doc.metadata?.url as string | null) ?? null,
|
|
145
|
-
createdAt: (doc.metadata?.created_at as string | null) ?? null,
|
|
146
|
-
highlights: (raw.highlights ?? []).map((h) => ({
|
|
147
|
-
id: h.id,
|
|
148
|
-
score: h.score,
|
|
149
|
-
text: h.text,
|
|
150
|
-
})),
|
|
151
|
-
};
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
log.debugResponse("memories.search", { count: results.length });
|
|
155
|
-
return results;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
async searchRaw(
|
|
159
|
-
query: string,
|
|
160
|
-
options?: {
|
|
161
|
-
limit?: number;
|
|
162
|
-
sources?: HyperspellSource[];
|
|
163
|
-
after?: string;
|
|
164
|
-
before?: string;
|
|
165
|
-
userId?: string;
|
|
166
|
-
filter?: Record<string, unknown>;
|
|
167
|
-
},
|
|
168
|
-
): Promise<Record<string, unknown>> {
|
|
169
|
-
const limit = options?.limit ?? this.config.maxResults;
|
|
170
|
-
const sources =
|
|
171
|
-
options?.sources ??
|
|
172
|
-
(this.config.sources.length > 0 ? this.config.sources : undefined);
|
|
173
|
-
|
|
174
|
-
log.debugRequest("memories.search (raw)", {
|
|
175
|
-
query,
|
|
176
|
-
limit,
|
|
177
|
-
sources,
|
|
178
|
-
after: options?.after,
|
|
179
|
-
before: options?.before,
|
|
180
|
-
userId: options?.userId,
|
|
181
|
-
filter: options?.filter,
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
const response = await this.client.memories.search(
|
|
185
|
-
{
|
|
186
|
-
query,
|
|
187
|
-
sources,
|
|
188
|
-
options: {
|
|
189
|
-
max_results: limit,
|
|
190
|
-
...(options?.after ? { after: options.after } : {}),
|
|
191
|
-
...(options?.before ? { before: options.before } : {}),
|
|
192
|
-
...(options?.filter ? { filter: options.filter } : {}),
|
|
193
|
-
},
|
|
194
|
-
},
|
|
195
|
-
this.requestOptions(options?.userId),
|
|
196
|
-
);
|
|
197
|
-
|
|
198
|
-
log.debugResponse("memories.search (raw)", {
|
|
199
|
-
count: response.documents.length,
|
|
200
|
-
});
|
|
201
|
-
|
|
202
|
-
return response as unknown as Record<string, unknown>;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
async searchWithAnswer(
|
|
206
|
-
query: string,
|
|
207
|
-
options?: {
|
|
208
|
-
limit?: number;
|
|
209
|
-
sources?: HyperspellSource[];
|
|
210
|
-
userId?: string;
|
|
211
|
-
filter?: Record<string, unknown>;
|
|
212
|
-
},
|
|
213
|
-
): Promise<SearchWithAnswerResult> {
|
|
214
|
-
const limit = options?.limit ?? this.config.maxResults;
|
|
215
|
-
const sources =
|
|
216
|
-
options?.sources ??
|
|
217
|
-
(this.config.sources.length > 0 ? this.config.sources : undefined);
|
|
218
|
-
|
|
219
|
-
log.debugRequest("memories.search (with answer)", {
|
|
220
|
-
query,
|
|
221
|
-
limit,
|
|
222
|
-
sources,
|
|
223
|
-
userId: options?.userId,
|
|
224
|
-
filter: options?.filter,
|
|
225
|
-
});
|
|
226
|
-
|
|
227
|
-
const response = await this.client.memories.search(
|
|
228
|
-
{
|
|
229
|
-
query,
|
|
230
|
-
sources,
|
|
231
|
-
answer: true,
|
|
232
|
-
options: {
|
|
233
|
-
max_results: limit,
|
|
234
|
-
...(options?.filter ? { filter: options.filter } : {}),
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
this.requestOptions(options?.userId),
|
|
238
|
-
);
|
|
239
|
-
|
|
240
|
-
const documents: SearchResult[] = response.documents.map((doc) => ({
|
|
241
|
-
resourceId: doc.resource_id,
|
|
242
|
-
title: doc.title ?? null,
|
|
243
|
-
source: doc.source as HyperspellSource,
|
|
244
|
-
score: doc.score ?? null,
|
|
245
|
-
url: (doc.metadata?.url as string | null) ?? null,
|
|
246
|
-
createdAt: (doc.metadata?.created_at as string | null) ?? null,
|
|
247
|
-
highlights: [],
|
|
248
|
-
}));
|
|
249
|
-
|
|
250
|
-
log.debugResponse("memories.search (with answer)", {
|
|
251
|
-
count: documents.length,
|
|
252
|
-
hasAnswer: !!response.answer,
|
|
253
|
-
});
|
|
254
|
-
|
|
255
|
-
return {
|
|
256
|
-
answer: response.answer ?? null,
|
|
257
|
-
documents,
|
|
258
|
-
};
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
async addMemory(
|
|
262
|
-
text: string,
|
|
263
|
-
options?: {
|
|
264
|
-
title?: string;
|
|
265
|
-
resourceId?: string;
|
|
266
|
-
collection?: string;
|
|
267
|
-
date?: string;
|
|
268
|
-
metadata?: Record<string, string | number | boolean>;
|
|
269
|
-
userId?: string;
|
|
270
|
-
scope?: ScopeName;
|
|
271
|
-
},
|
|
272
|
-
): Promise<{ resourceId: string }> {
|
|
273
|
-
log.debugRequest("memories.add", {
|
|
274
|
-
textLength: text.length,
|
|
275
|
-
title: options?.title,
|
|
276
|
-
resourceId: options?.resourceId,
|
|
277
|
-
collection: options?.collection,
|
|
278
|
-
date: options?.date,
|
|
279
|
-
userId: options?.userId,
|
|
280
|
-
scope: options?.scope,
|
|
281
|
-
});
|
|
282
|
-
|
|
283
|
-
const result = await this.client.memories.add(
|
|
284
|
-
{
|
|
285
|
-
text,
|
|
286
|
-
title: options?.title,
|
|
287
|
-
resource_id: options?.resourceId,
|
|
288
|
-
collection: options?.collection,
|
|
289
|
-
date: options?.date,
|
|
290
|
-
metadata: {
|
|
291
|
-
openclaw_source: "command",
|
|
292
|
-
...options?.metadata,
|
|
293
|
-
...(options?.userId ? { openclaw_user: options.userId } : {}),
|
|
294
|
-
...(options?.scope
|
|
295
|
-
? { openclaw_scope: normalizeScope(options.scope) }
|
|
296
|
-
: {}),
|
|
297
|
-
},
|
|
298
|
-
},
|
|
299
|
-
this.requestOptions(options?.userId),
|
|
300
|
-
);
|
|
301
|
-
|
|
302
|
-
log.debugResponse("memories.add", { resourceId: result.resource_id });
|
|
303
|
-
return { resourceId: result.resource_id };
|
|
304
|
-
}
|
|
305
|
-
|
|
306
|
-
async listIntegrations(): Promise<Integration[]> {
|
|
307
|
-
log.debugRequest("integrations.list", {});
|
|
308
|
-
|
|
309
|
-
const response = await this.client.integrations.list();
|
|
310
|
-
|
|
311
|
-
const integrations: Integration[] = response.integrations.map((int) => ({
|
|
312
|
-
id: int.id,
|
|
313
|
-
name: int.name,
|
|
314
|
-
provider: int.provider as HyperspellSource,
|
|
315
|
-
icon: int.icon,
|
|
316
|
-
}));
|
|
317
|
-
|
|
318
|
-
log.debugResponse("integrations.list", { count: integrations.length });
|
|
319
|
-
return integrations;
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
async getConnectUrl(
|
|
323
|
-
integrationId: string,
|
|
324
|
-
options?: { userId?: string },
|
|
325
|
-
): Promise<{ url: string; expiresAt: string }> {
|
|
326
|
-
log.debugRequest("integrations.connect", { integrationId });
|
|
327
|
-
|
|
328
|
-
const response = await this.client.integrations.connect(
|
|
329
|
-
integrationId,
|
|
330
|
-
undefined,
|
|
331
|
-
this.requestOptions(options?.userId),
|
|
332
|
-
);
|
|
333
|
-
|
|
334
|
-
log.debugResponse("integrations.connect", { url: response.url });
|
|
335
|
-
return {
|
|
336
|
-
url: response.url,
|
|
337
|
-
expiresAt: response.expires_at,
|
|
338
|
-
};
|
|
339
|
-
}
|
|
340
|
-
|
|
341
|
-
async *listMemories(options?: {
|
|
342
|
-
source?: HyperspellSource;
|
|
343
|
-
collection?: string;
|
|
344
|
-
pageSize?: number;
|
|
345
|
-
userId?: string;
|
|
346
|
-
}): AsyncGenerator<{
|
|
347
|
-
resourceId: string;
|
|
348
|
-
source: HyperspellSource;
|
|
349
|
-
title: string | null;
|
|
350
|
-
metadata: Record<string, unknown>;
|
|
351
|
-
}> {
|
|
352
|
-
log.debugRequest("memories.list", {
|
|
353
|
-
source: options?.source,
|
|
354
|
-
collection: options?.collection,
|
|
355
|
-
userId: options?.userId,
|
|
356
|
-
});
|
|
357
|
-
|
|
358
|
-
const params: Record<string, unknown> = {
|
|
359
|
-
size: options?.pageSize ?? 100,
|
|
360
|
-
};
|
|
361
|
-
if (options?.source) params.source = options.source;
|
|
362
|
-
if (options?.collection) params.collection = options.collection;
|
|
363
|
-
|
|
364
|
-
for await (const memory of this.client.memories.list(
|
|
365
|
-
params as any,
|
|
366
|
-
this.requestOptions(options?.userId),
|
|
367
|
-
)) {
|
|
368
|
-
yield {
|
|
369
|
-
resourceId: memory.resource_id,
|
|
370
|
-
source: memory.source as HyperspellSource,
|
|
371
|
-
title: memory.title ?? null,
|
|
372
|
-
metadata: (memory.metadata ?? {}) as Record<string, unknown>,
|
|
373
|
-
};
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
async getMemory(
|
|
378
|
-
resourceId: string,
|
|
379
|
-
source: HyperspellSource,
|
|
380
|
-
options?: { userId?: string },
|
|
381
|
-
): Promise<Record<string, unknown>> {
|
|
382
|
-
log.debugRequest("memories.get", { resourceId, source });
|
|
383
|
-
|
|
384
|
-
const response = await this.client.memories.get(
|
|
385
|
-
resourceId,
|
|
386
|
-
{ source },
|
|
387
|
-
this.requestOptions(options?.userId),
|
|
388
|
-
);
|
|
389
|
-
const raw = response as unknown as Record<string, unknown>;
|
|
390
|
-
|
|
391
|
-
log.debugResponse("memories.get", { resourceId, hasData: "data" in raw });
|
|
392
|
-
return raw;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
async sendTrace(
|
|
396
|
-
history: string,
|
|
397
|
-
options?: {
|
|
398
|
-
sessionId?: string;
|
|
399
|
-
title?: string;
|
|
400
|
-
extract?: Array<"procedure" | "memory" | "mood">;
|
|
401
|
-
metadata?: Record<string, string | number | boolean>;
|
|
402
|
-
userId?: string;
|
|
403
|
-
scope?: ScopeName;
|
|
404
|
-
},
|
|
405
|
-
): Promise<{ resourceId: string; status: string }> {
|
|
406
|
-
log.debugRequest("sessions.add", {
|
|
407
|
-
historyLength: history.length,
|
|
408
|
-
sessionId: options?.sessionId,
|
|
409
|
-
extract: options?.extract,
|
|
410
|
-
userId: options?.userId,
|
|
411
|
-
scope: options?.scope,
|
|
412
|
-
});
|
|
413
|
-
|
|
414
|
-
const result = await this.client.sessions.add(
|
|
415
|
-
{
|
|
416
|
-
history,
|
|
417
|
-
session_id: options?.sessionId,
|
|
418
|
-
title: options?.title,
|
|
419
|
-
format: "openclaw",
|
|
420
|
-
// Cast: SDK 0.35 typing accepts only ["procedure" | "memory"], but the
|
|
421
|
-
// backend's mood extractor (hyperspell/hyperspell#581) accepts "mood".
|
|
422
|
-
// Remove this cast once the OpenAPI spec is updated.
|
|
423
|
-
extract: (options?.extract ?? ["procedure"]) as Array<
|
|
424
|
-
"procedure" | "memory"
|
|
425
|
-
>,
|
|
426
|
-
metadata: {
|
|
427
|
-
openclaw_source: "agent_end",
|
|
428
|
-
...options?.metadata,
|
|
429
|
-
...(options?.userId ? { openclaw_user: options.userId } : {}),
|
|
430
|
-
...(options?.scope
|
|
431
|
-
? { openclaw_scope: normalizeScope(options.scope) }
|
|
432
|
-
: {}),
|
|
433
|
-
},
|
|
434
|
-
},
|
|
435
|
-
this.requestOptions(options?.userId),
|
|
436
|
-
);
|
|
437
|
-
|
|
438
|
-
log.debugResponse("sessions.add", {
|
|
439
|
-
resourceId: result.resource_id,
|
|
440
|
-
status: result.status,
|
|
441
|
-
});
|
|
442
|
-
return { resourceId: result.resource_id, status: result.status };
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
async listConnections(options?: {
|
|
446
|
-
userId?: string;
|
|
447
|
-
}): Promise<Connection[]> {
|
|
448
|
-
log.debugRequest("connections.list", { userId: options?.userId });
|
|
449
|
-
|
|
450
|
-
const response = await this.client.connections.list(
|
|
451
|
-
this.requestOptions(options?.userId),
|
|
452
|
-
);
|
|
453
|
-
|
|
454
|
-
const connections: Connection[] = response.connections.map((conn) => ({
|
|
455
|
-
id: conn.id,
|
|
456
|
-
integrationId: conn.integration_id,
|
|
457
|
-
label: conn.label,
|
|
458
|
-
provider: conn.provider as HyperspellSource,
|
|
459
|
-
}));
|
|
460
|
-
|
|
461
|
-
log.debugResponse("connections.list", { count: connections.length });
|
|
462
|
-
return connections;
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
// -- Emotional State (raw fetch -- not in public SDK) -----------------------
|
|
466
|
-
|
|
467
|
-
async storeEmotionalState(
|
|
468
|
-
conversation: string,
|
|
469
|
-
options?: {
|
|
470
|
-
sessionId?: string;
|
|
471
|
-
relationshipId?: string;
|
|
472
|
-
metadata?: Record<string, string | number | boolean>;
|
|
473
|
-
},
|
|
474
|
-
): Promise<EmotionalStateResponse> {
|
|
475
|
-
log.debugRequest("emotional-state.store", {
|
|
476
|
-
conversationLength: conversation.length,
|
|
477
|
-
relationshipId: options?.relationshipId,
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
const body: Record<string, unknown> = { conversation };
|
|
481
|
-
if (options?.sessionId) body.session_id = options.sessionId;
|
|
482
|
-
if (options?.relationshipId) body.relationship_id = options.relationshipId;
|
|
483
|
-
if (options?.metadata) body.metadata = options.metadata;
|
|
484
|
-
|
|
485
|
-
const res = await fetch(`${API_BASE_URL}/emotional-state`, {
|
|
486
|
-
method: "POST",
|
|
487
|
-
headers: this.rawHeaders(),
|
|
488
|
-
body: JSON.stringify(body),
|
|
489
|
-
});
|
|
490
|
-
|
|
491
|
-
if (!res.ok) {
|
|
492
|
-
const text = await res.text().catch(() => "");
|
|
493
|
-
throw new Error(`POST /emotional-state failed (${res.status}): ${text}`);
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
const data = await res.json();
|
|
497
|
-
const result: EmotionalStateResponse = {
|
|
498
|
-
resourceId: data.resource_id,
|
|
499
|
-
summary: data.summary,
|
|
500
|
-
extractedAt: data.extracted_at,
|
|
501
|
-
sessionId: data.session_id ?? null,
|
|
502
|
-
relationshipId: data.relationship_id ?? null,
|
|
503
|
-
status: data.status,
|
|
504
|
-
};
|
|
505
|
-
|
|
506
|
-
log.debugResponse("emotional-state.store", { resourceId: result.resourceId });
|
|
507
|
-
return result;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
async getEmotionalState(relationshipId?: string): Promise<EmotionalStateLatest | null> {
|
|
511
|
-
log.debugRequest("emotional-state.get", { relationshipId });
|
|
512
|
-
|
|
513
|
-
const url = new URL(`${API_BASE_URL}/emotional-state`);
|
|
514
|
-
if (relationshipId) url.searchParams.set("relationship_id", relationshipId);
|
|
515
|
-
|
|
516
|
-
const res = await fetch(url.toString(), {
|
|
517
|
-
method: "GET",
|
|
518
|
-
headers: this.rawHeaders(),
|
|
519
|
-
});
|
|
520
|
-
|
|
521
|
-
if (!res.ok) {
|
|
522
|
-
const text = await res.text().catch(() => "");
|
|
523
|
-
throw new Error(`GET /emotional-state failed (${res.status}): ${text}`);
|
|
524
|
-
}
|
|
525
|
-
|
|
526
|
-
const data = await res.json();
|
|
527
|
-
if (data === null) {
|
|
528
|
-
log.debugResponse("emotional-state.get", { found: false });
|
|
529
|
-
return null;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
const result: EmotionalStateLatest = {
|
|
533
|
-
resourceId: data.resource_id,
|
|
534
|
-
summary: data.summary,
|
|
535
|
-
extractedAt: data.extracted_at,
|
|
536
|
-
sessionId: data.session_id ?? null,
|
|
537
|
-
relationshipId: data.relationship_id ?? null,
|
|
538
|
-
};
|
|
539
|
-
|
|
540
|
-
log.debugResponse("emotional-state.get", { found: true, resourceId: result.resourceId });
|
|
541
|
-
return result;
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
async deleteEmotionalState(relationshipId?: string): Promise<{ deletedCount: number }> {
|
|
545
|
-
log.debugRequest("emotional-state.delete", { relationshipId });
|
|
546
|
-
|
|
547
|
-
const url = new URL(`${API_BASE_URL}/emotional-state`);
|
|
548
|
-
if (relationshipId) url.searchParams.set("relationship_id", relationshipId);
|
|
549
|
-
|
|
550
|
-
const res = await fetch(url.toString(), {
|
|
551
|
-
method: "DELETE",
|
|
552
|
-
headers: this.rawHeaders(),
|
|
553
|
-
});
|
|
554
|
-
|
|
555
|
-
if (!res.ok) {
|
|
556
|
-
const text = await res.text().catch(() => "");
|
|
557
|
-
throw new Error(`DELETE /emotional-state failed (${res.status}): ${text}`);
|
|
558
|
-
}
|
|
559
|
-
|
|
560
|
-
const data = await res.json();
|
|
561
|
-
const result = { deletedCount: data.deleted_count };
|
|
562
|
-
|
|
563
|
-
log.debugResponse("emotional-state.delete", result);
|
|
564
|
-
return result;
|
|
565
|
-
}
|
|
566
|
-
}
|