Skip to content

Commit 88cdd88

Browse files
authored
Merge pull request #37 from Gui-Yue/fix/jsonstore-exists-resume-consistency
fix: JSONStore.exists() validates meta.json integrity and add Agent.r…
2 parents ea2812a + d1b0870 commit 88cdd88

3 files changed

Lines changed: 85 additions & 1 deletion

File tree

src/core/agent.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -877,6 +877,43 @@ export class Agent {
877877
return Agent.resume(agentId, { ...baseConfig, ...overrides }, deps, opts);
878878
}
879879

880+
static async resumeOrCreate(
881+
agentId: string,
882+
config: AgentConfig,
883+
deps: AgentDependencies,
884+
opts?: {
885+
autoRun?: boolean;
886+
strategy?: ResumeStrategy;
887+
overrides?: Partial<AgentConfig>;
888+
onCorrupted?: (agentId: string, error: ResumeError) => Promise<void> | void;
889+
}
890+
): Promise<Agent> {
891+
try {
892+
return await Agent.resumeFromStore(agentId, deps, opts);
893+
} catch (error) {
894+
if (!(error instanceof ResumeError)) {
895+
throw error;
896+
}
897+
898+
switch (error.code) {
899+
case 'AGENT_NOT_FOUND':
900+
return Agent.create({ ...config, agentId }, deps);
901+
902+
case 'CORRUPTED_DATA': {
903+
if (opts?.onCorrupted) {
904+
await opts.onCorrupted(agentId, error);
905+
}
906+
const store = Agent.requireStore(deps);
907+
await store.delete(agentId);
908+
return Agent.create({ ...config, agentId }, deps);
909+
}
910+
911+
default:
912+
throw error;
913+
}
914+
}
915+
}
916+
880917
private ensureProcessing() {
881918
// 检查是否超时
882919
if (this.processingPromise) {

src/infra/store/json-store.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -673,7 +673,8 @@ export class JSONStore implements Store {
673673
const fs = require('fs').promises;
674674
try {
675675
await fs.access(this.getAgentDir(agentId));
676-
return true;
676+
const info = await this.loadInfo(agentId);
677+
return !!(info && info.metadata);
677678
} catch {
678679
return false;
679680
}

tests/unit/infra/json-store.test.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,52 @@ runner
142142

143143
await store.delete('agent');
144144
expect.toEqual(await store.exists('agent'), false);
145+
})
146+
147+
.test('exists() returns false when directory exists but meta.json is missing', async () => {
148+
const dir = createDir('exists-no-meta');
149+
const store = new JSONStore(dir);
150+
// Create agent directory without meta.json
151+
fs.mkdirSync(path.join(dir, 'agent'), { recursive: true });
152+
expect.toEqual(await store.exists('agent'), false);
153+
})
154+
155+
.test('exists() returns false when meta.json is corrupted JSON', async () => {
156+
const dir = createDir('exists-corrupt');
157+
const store = new JSONStore(dir);
158+
const agentDir = path.join(dir, 'agent');
159+
fs.mkdirSync(agentDir, { recursive: true });
160+
fs.writeFileSync(path.join(agentDir, 'meta.json'), '{not valid json!!!', 'utf-8');
161+
expect.toEqual(await store.exists('agent'), false);
162+
})
163+
164+
.test('exists() returns false when meta.json lacks metadata field', async () => {
165+
const dir = createDir('exists-no-metadata');
166+
const store = new JSONStore(dir);
167+
const agentDir = path.join(dir, 'agent');
168+
fs.mkdirSync(agentDir, { recursive: true });
169+
fs.writeFileSync(
170+
path.join(agentDir, 'meta.json'),
171+
JSON.stringify({ agentId: 'agent', templateId: 'tpl' }),
172+
'utf-8'
173+
);
174+
expect.toEqual(await store.exists('agent'), false);
175+
})
176+
177+
.test('exists() returns true when meta.json is complete', async () => {
178+
const dir = createDir('exists-complete');
179+
const store = new JSONStore(dir);
180+
await store.saveInfo('agent', {
181+
agentId: 'agent',
182+
templateId: 'tpl',
183+
createdAt: new Date().toISOString(),
184+
lineage: [],
185+
configVersion: 'test',
186+
messageCount: 0,
187+
lastSfpIndex: 0,
188+
metadata: { templateId: 'tpl' },
189+
});
190+
expect.toEqual(await store.exists('agent'), true);
145191
});
146192

147193
export async function run() {

0 commit comments

Comments
 (0)