clawport-ui 0.8.8 → 0.8.9
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/lib/memory.test.ts +47 -0
- package/lib/memory.ts +33 -8
- package/package.json +1 -1
package/lib/memory.test.ts
CHANGED
|
@@ -331,6 +331,53 @@ describe('getMemoryStatus', () => {
|
|
|
331
331
|
expect(status.lastIndexed).toBeNull()
|
|
332
332
|
expect(status.totalEntries).toBeNull()
|
|
333
333
|
})
|
|
334
|
+
|
|
335
|
+
it('parses new array-of-agents format from openclaw memory status --deep --json', () => {
|
|
336
|
+
mockExecSync.mockReturnValue(JSON.stringify([
|
|
337
|
+
{
|
|
338
|
+
agentId: 'main',
|
|
339
|
+
status: { files: 9, chunks: 13, dirty: false, provider: 'gemini', vector: { available: true } },
|
|
340
|
+
},
|
|
341
|
+
{
|
|
342
|
+
agentId: 'helper',
|
|
343
|
+
status: { files: 3, chunks: 5, dirty: false, provider: 'gemini', vector: { available: true } },
|
|
344
|
+
},
|
|
345
|
+
]))
|
|
346
|
+
|
|
347
|
+
const status = getMemoryStatus()
|
|
348
|
+
expect(status.indexed).toBe(true)
|
|
349
|
+
expect(status.totalEntries).toBe(18) // 13 + 5 chunks
|
|
350
|
+
expect(status.vectorAvailable).toBe(true)
|
|
351
|
+
expect(status.embeddingProvider).toBe('gemini')
|
|
352
|
+
})
|
|
353
|
+
|
|
354
|
+
it('reports not indexed when any agent has dirty files', () => {
|
|
355
|
+
mockExecSync.mockReturnValue(JSON.stringify([
|
|
356
|
+
{
|
|
357
|
+
agentId: 'main',
|
|
358
|
+
status: { files: 9, chunks: 13, dirty: false, provider: 'gemini', vector: { available: true } },
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
agentId: 'helper',
|
|
362
|
+
status: { files: 3, chunks: 5, dirty: true, provider: 'gemini', vector: { available: true } },
|
|
363
|
+
},
|
|
364
|
+
]))
|
|
365
|
+
|
|
366
|
+
const status = getMemoryStatus()
|
|
367
|
+
expect(status.indexed).toBe(false)
|
|
368
|
+
})
|
|
369
|
+
|
|
370
|
+
it('reports not indexed when an agent has zero files', () => {
|
|
371
|
+
mockExecSync.mockReturnValue(JSON.stringify([
|
|
372
|
+
{
|
|
373
|
+
agentId: 'main',
|
|
374
|
+
status: { files: 0, chunks: 0, dirty: false, provider: 'gemini', vector: { available: true } },
|
|
375
|
+
},
|
|
376
|
+
]))
|
|
377
|
+
|
|
378
|
+
const status = getMemoryStatus()
|
|
379
|
+
expect(status.indexed).toBe(false)
|
|
380
|
+
})
|
|
334
381
|
})
|
|
335
382
|
|
|
336
383
|
// ── computeMemoryStats ──────────────────────────────────────────
|
package/lib/memory.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { readFileSync, existsSync, statSync, readdirSync } from 'fs'
|
|
|
3
3
|
import { join, basename, dirname } from 'path'
|
|
4
4
|
import { execSync } from 'child_process'
|
|
5
5
|
import { requireEnv } from '@/lib/env'
|
|
6
|
+
import { extractJson } from '@/lib/cli-utils'
|
|
6
7
|
|
|
7
8
|
// ── Date pattern for daily logs ─────────────────────────────────
|
|
8
9
|
|
|
@@ -213,21 +214,45 @@ export function getMemoryStatus(): MemoryStatus {
|
|
|
213
214
|
}
|
|
214
215
|
|
|
215
216
|
try {
|
|
216
|
-
const output = execSync(`${bin} memory status --deep`, {
|
|
217
|
+
const output = execSync(`${bin} memory status --deep --json`, {
|
|
217
218
|
timeout: 15000,
|
|
218
219
|
encoding: 'utf-8',
|
|
219
220
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
220
221
|
}).trim()
|
|
221
222
|
|
|
222
|
-
// Try JSON parse first
|
|
223
223
|
try {
|
|
224
|
-
const data =
|
|
224
|
+
const data = extractJson(output)
|
|
225
|
+
|
|
226
|
+
// New format: array of per-agent status objects
|
|
227
|
+
// [{ agentId, status: { files, chunks, dirty, provider, vector } }, ...]
|
|
228
|
+
if (Array.isArray(data) && data.length > 0) {
|
|
229
|
+
const agents = data as { agentId?: string; status?: Record<string, unknown> }[]
|
|
230
|
+
const primary = agents[0].status ?? {}
|
|
231
|
+
const totalEntries = agents.reduce(
|
|
232
|
+
(sum, a) => sum + (typeof a.status?.chunks === 'number' ? a.status.chunks : 0), 0,
|
|
233
|
+
)
|
|
234
|
+
const allIndexed = agents.every(
|
|
235
|
+
a => (typeof a.status?.files === 'number' && a.status.files > 0) && !a.status?.dirty,
|
|
236
|
+
)
|
|
237
|
+
const vec = primary.vector as Record<string, unknown> | undefined
|
|
238
|
+
return {
|
|
239
|
+
indexed: allIndexed,
|
|
240
|
+
lastIndexed: null,
|
|
241
|
+
totalEntries,
|
|
242
|
+
vectorAvailable: typeof vec?.available === 'boolean' ? vec.available : null,
|
|
243
|
+
embeddingProvider: typeof primary.provider === 'string' ? primary.provider : null,
|
|
244
|
+
raw: output,
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
// Legacy flat object format
|
|
249
|
+
const flat = data as Record<string, unknown>
|
|
225
250
|
return {
|
|
226
|
-
indexed:
|
|
227
|
-
lastIndexed:
|
|
228
|
-
totalEntries:
|
|
229
|
-
vectorAvailable:
|
|
230
|
-
embeddingProvider:
|
|
251
|
+
indexed: flat.indexed === true,
|
|
252
|
+
lastIndexed: typeof flat.lastIndexed === 'string' ? flat.lastIndexed : null,
|
|
253
|
+
totalEntries: typeof flat.totalEntries === 'number' ? flat.totalEntries : null,
|
|
254
|
+
vectorAvailable: typeof flat.vectorAvailable === 'boolean' ? flat.vectorAvailable : null,
|
|
255
|
+
embeddingProvider: typeof flat.embeddingProvider === 'string' ? flat.embeddingProvider : null,
|
|
231
256
|
raw: output,
|
|
232
257
|
}
|
|
233
258
|
} catch {
|