close to win

This commit is contained in:
Alex Newman
2025-11-01 21:33:08 -04:00
parent 65c89ea2f0
commit 02130c49d1
12 changed files with 761 additions and 142 deletions
+67 -5
View File
@@ -7,6 +7,7 @@ import express, { Request, Response } from 'express';
import { query } from '@anthropic-ai/claude-agent-sdk';
import type { SDKUserMessage, SDKSystemMessage } from '@anthropic-ai/claude-agent-sdk';
import { SessionStore } from './sqlite/SessionStore.js';
import { ChromaSync } from './sync/ChromaSync.js';
import { buildInitPrompt, buildObservationPrompt, buildSummaryPrompt } from '../sdk/prompts.js';
import { parseObservations, parseSummary } from '../sdk/parser.js';
import type { SDKSession } from '../sdk/prompts.js';
@@ -83,11 +84,16 @@ class WorkerService {
private app: express.Application;
private port: number | null = null;
private sessions: Map<number, ActiveSession> = new Map();
private chromaSync: ChromaSync;
constructor() {
this.app = express();
this.app.use(express.json({ limit: '50mb' }));
// Initialize ChromaSync (fail fast if Chroma unavailable)
this.chromaSync = new ChromaSync('claude-mem');
logger.info('SYSTEM', 'ChromaSync initialized');
// Health check
this.app.get('/health', this.handleHealth.bind(this));
@@ -111,6 +117,16 @@ class WorkerService {
logger.info('SYSTEM', `Cleaned up ${cleanedCount} orphaned sessions`);
}
// Backfill Chroma with any missing observations/summaries (blocking)
logger.info('SYSTEM', 'Starting Chroma backfill...');
try {
await this.chromaSync.ensureBackfilled();
logger.info('SYSTEM', 'Chroma backfill complete');
} catch (error) {
logger.error('SYSTEM', 'Chroma backfill failed - worker cannot start', {}, error as Error);
throw error;
}
return new Promise((resolve, reject) => {
this.app.listen(FIXED_PORT, '127.0.0.1', () => {
logger.info('SYSTEM', `Worker started`, { port: FIXED_PORT, pid: process.pid, activeSessions: this.sessions.size });
@@ -406,7 +422,7 @@ class WorkerService {
// In debug mode, log the full response
logger.debug('SDK', 'Full response', { sessionId: session.sessionDbId }, textContent);
// Parse and store with prompt number
// Parse and store with prompt number (non-blocking Chroma sync)
this.handleAgentMessage(session, textContent, session.lastPromptNumber);
}
}
@@ -558,12 +574,36 @@ class WorkerService {
}
const db = new SessionStore();
// Store observations and sync to Chroma (non-blocking, fail-fast)
for (const obs of observations) {
db.storeObservation(session.claudeSessionId, session.project, obs, promptNumber);
const { id, createdAtEpoch } = db.storeObservation(session.claudeSessionId, session.project, obs, promptNumber);
logger.success('DB', 'Observation stored', {
correlationId,
type: obs.type,
title: obs.title
title: obs.title,
id
});
// Sync to Chroma (non-blocking fire-and-forget, but crash on failure)
this.chromaSync.syncObservation(
id,
session.claudeSessionId,
session.project,
obs,
promptNumber,
createdAtEpoch
).then(() => {
logger.success('CHROMA', 'Observation synced', {
correlationId,
observationId: id
});
}).catch((error: Error) => {
logger.error('CHROMA', 'Observation sync failed - crashing worker', {
correlationId,
observationId: id
}, error);
process.exit(1); // Fail fast - no fallbacks
});
}
@@ -580,8 +620,30 @@ class WorkerService {
hasCompleted: !!summary.completed,
hasNextSteps: !!summary.next_steps
});
db.storeSummary(session.claudeSessionId, session.project, summary, promptNumber);
logger.success('DB', '📝 SUMMARY STORED IN DATABASE', { sessionId: session.sessionDbId, promptNumber });
const { id, createdAtEpoch } = db.storeSummary(session.claudeSessionId, session.project, summary, promptNumber);
logger.success('DB', '📝 SUMMARY STORED IN DATABASE', { sessionId: session.sessionDbId, promptNumber, id });
// Sync to Chroma (non-blocking fire-and-forget, but crash on failure)
this.chromaSync.syncSummary(
id,
session.claudeSessionId,
session.project,
summary,
promptNumber,
createdAtEpoch
).then(() => {
logger.success('CHROMA', 'Summary synced', {
sessionId: session.sessionDbId,
summaryId: id
});
}).catch((error: Error) => {
logger.error('CHROMA', 'Summary sync failed - crashing worker', {
sessionId: session.sessionDbId,
summaryId: id
}, error);
process.exit(1); // Fail fast - no fallbacks
});
} else {
logger.warn('PARSER', 'NO SUMMARY TAGS FOUND in response', {
sessionId: session.sessionDbId,