report update fixes

This commit is contained in:
dal 2025-09-22 09:47:12 -06:00
parent e63fd79df5
commit 651af9de4e
No known key found for this signature in database
GPG Key ID: 16F4B0E1E9F61122
5 changed files with 80 additions and 24 deletions

View File

@ -312,14 +312,35 @@ export function createModifyReportsDelta(context: ModifyReportsContext, state: M
}, },
}; };
// Update the database with the result of all edits // Update the database with the result of all edits using Promise chain
try { try {
await batchUpdateReport({ // Chain this write to ensure sequential execution
reportId: state.reportId, state.lastDbWritePromise = (async () => {
content: currentContent, // Wait for any previous write to complete
name: state.reportName || undefined, if (state.lastDbWritePromise) {
versionHistory, try {
}); await state.lastDbWritePromise;
} catch (error) {
// Previous write failed, but we continue
console.warn('[modify-reports-delta] Previous write failed:', error);
}
}
// Now do our write
// We're already inside a check for state.reportId being defined
if (!state.reportId) {
throw new Error('Report ID is unexpectedly undefined');
}
return batchUpdateReport({
reportId: state.reportId,
content: currentContent,
name: state.reportName || undefined,
versionHistory,
});
})();
// Await the promise to handle errors and ensure completion
await state.lastDbWritePromise;
// No cache update during delta - execute will handle write-through // No cache update during delta - execute will handle write-through

View File

@ -79,7 +79,8 @@ async function processEditOperations(
edits: Array<{ operation?: 'replace' | 'append'; code_to_replace: string; code: string }>, edits: Array<{ operation?: 'replace' | 'append'; code_to_replace: string; code: string }>,
messageId?: string, messageId?: string,
snapshotContent?: string, snapshotContent?: string,
versionHistory?: VersionHistory versionHistory?: VersionHistory,
state?: ModifyReportsState
): Promise<{ ): Promise<{
success: boolean; success: boolean;
finalContent?: string; finalContent?: string;
@ -176,6 +177,21 @@ async function processEditOperations(
// Write all changes to database in one operation // Write all changes to database in one operation
try { try {
// Wait for any pending delta writes to complete before doing final update
if (state?.lastDbWritePromise) {
console.info('[modify-reports-execute] Waiting for pending delta writes to complete');
try {
await state.lastDbWritePromise;
// Add small delay to ensure we're absolutely last
await new Promise((resolve) => setTimeout(resolve, 50));
} catch (error) {
console.warn(
'[modify-reports-execute] Delta write failed, proceeding with final update:',
error
);
}
}
await batchUpdateReport({ await batchUpdateReport({
reportId, reportId,
content: currentContent, content: currentContent,
@ -239,7 +255,8 @@ const modifyReportsFile = wrapTraced(
params: ModifyReportsInput, params: ModifyReportsInput,
context: ModifyReportsContext, context: ModifyReportsContext,
snapshotContent?: string, snapshotContent?: string,
versionHistory?: VersionHistory versionHistory?: VersionHistory,
state?: ModifyReportsState
): Promise<ModifyReportsOutput> => { ): Promise<ModifyReportsOutput> => {
// Get context values // Get context values
const userId = context.userId; const userId = context.userId;
@ -299,7 +316,8 @@ const modifyReportsFile = wrapTraced(
params.edits, params.edits,
messageId, messageId,
snapshotContent, // Pass immutable snapshot snapshotContent, // Pass immutable snapshot
versionHistory // Pass snapshot version history versionHistory, // Pass snapshot version history
state // Pass state to access lastDbWritePromise
); );
// Track file associations if this is a new version (not part of same turn) // Track file associations if this is a new version (not part of same turn)
@ -390,7 +408,8 @@ export function createModifyReportsExecute(
input, input,
context, context,
state.snapshotContent, // Pass immutable snapshot from state state.snapshotContent, // Pass immutable snapshot from state
state.versionHistory // Pass snapshot version history from state state.versionHistory, // Pass snapshot version history from state
state // Pass state to access lastDbWritePromise
); );
if (!result) { if (!result) {

View File

@ -101,9 +101,13 @@ const ModifyReportsStateSchema = z.object({
export type ModifyReportsInput = z.infer<typeof ModifyReportsInputSchema>; export type ModifyReportsInput = z.infer<typeof ModifyReportsInputSchema>;
export type ModifyReportsOutput = z.infer<typeof ModifyReportsOutputSchema>; export type ModifyReportsOutput = z.infer<typeof ModifyReportsOutputSchema>;
export type ModifyReportsContext = z.infer<typeof ModifyReportsContextSchema>; export type ModifyReportsContext = z.infer<typeof ModifyReportsContextSchema>;
export type ModifyReportsState = z.infer<typeof ModifyReportsStateSchema>;
export type ModifyReportsEditState = z.infer<typeof ModifyReportsEditStateSchema>; export type ModifyReportsEditState = z.infer<typeof ModifyReportsEditStateSchema>;
// Extend the inferred type to include Promise field (not supported by Zod directly)
export type ModifyReportsState = z.infer<typeof ModifyReportsStateSchema> & {
lastDbWritePromise?: Promise<void>;
};
// Factory function that accepts agent context and maps to tool context // Factory function that accepts agent context and maps to tool context
export function createModifyReportsTool(context: ModifyReportsContext) { export function createModifyReportsTool(context: ModifyReportsContext) {
// Initialize state for streaming // Initialize state for streaming

View File

@ -11,12 +11,14 @@ if (!connectionString) {
} }
// Disable SSL for local development // Disable SSL for local development
const isDevelopment = process.env.ENVIRONMENT === 'development' || process.env.NODE_ENV === 'development'; const isDevelopment =
process.env.ENVIRONMENT === 'development' || process.env.NODE_ENV === 'development';
// Append sslmode=disable for local development if not already present // Append sslmode=disable for local development if not already present
const dbUrl = isDevelopment && !connectionString.includes('sslmode=') const dbUrl =
? `${connectionString}?sslmode=disable` isDevelopment && !connectionString.includes('sslmode=')
: connectionString; ? `${connectionString}?sslmode=disable`
: connectionString;
export default defineConfig({ export default defineConfig({
schema: './src/schema.ts', schema: './src/schema.ts',

View File

@ -1,6 +1,6 @@
import { config } from 'dotenv';
import * as path from 'path'; import * as path from 'path';
import { fileURLToPath } from 'url'; import { fileURLToPath } from 'url';
import { config } from 'dotenv';
// Get the directory name for ES modules // Get the directory name for ES modules
const __filename = fileURLToPath(import.meta.url); const __filename = fileURLToPath(import.meta.url);
@ -61,18 +61,28 @@ export function initializePool<T extends Record<string, postgres.PostgresType>>(
// Create postgres client with pool configuration // Create postgres client with pool configuration
// Disable SSL for local development // Disable SSL for local development
const isDevelopment = process.env.ENVIRONMENT === 'development' || process.env.NODE_ENV === 'development'; const isDevelopment =
process.env.ENVIRONMENT === 'development' || process.env.NODE_ENV === 'development';
console.log('Database connection - ENVIRONMENT:', process.env.ENVIRONMENT, 'NODE_ENV:', process.env.NODE_ENV, 'isDevelopment:', isDevelopment);
console.log(
'Database connection - ENVIRONMENT:',
process.env.ENVIRONMENT,
'NODE_ENV:',
process.env.NODE_ENV,
'isDevelopment:',
isDevelopment
);
globalPool = postgres(connectionString, { globalPool = postgres(connectionString, {
max: poolSize, max: poolSize,
idle_timeout: 30, idle_timeout: 30,
connect_timeout: 30, connect_timeout: 30,
prepare: true, prepare: true,
ssl: isDevelopment ? false : { ssl: isDevelopment
rejectUnauthorized: false, // Allow self-signed certificates ? false
}, : {
rejectUnauthorized: false, // Allow self-signed certificates
},
...config, ...config,
}); });