From c1252de993fdb101ca2b1e1160f093a42791672d Mon Sep 17 00:00:00 2001 From: Vikhyath Mondreti Date: Fri, 29 May 2026 18:44:51 -0700 Subject: [PATCH] fix(copilot): seq migration --- .../logs/execution/logging-factory.test.ts | 54 ++++++++++++++++++ packages/db/.env.swp | Bin 12288 -> 0 bytes packages/db/migrations/0219_amused_leo.sql | 4 +- 3 files changed, 56 insertions(+), 2 deletions(-) delete mode 100644 packages/db/.env.swp diff --git a/apps/sim/lib/logs/execution/logging-factory.test.ts b/apps/sim/lib/logs/execution/logging-factory.test.ts index 7ec7fe11d19..12c604aa428 100644 --- a/apps/sim/lib/logs/execution/logging-factory.test.ts +++ b/apps/sim/lib/logs/execution/logging-factory.test.ts @@ -658,4 +658,58 @@ describe('calculateCostSummary', () => { expect(result.models['gpt-4o'].total).toBe(0.03) expect(result.totalCost).toBeCloseTo(0.03 + BASE_EXECUTION_CHARGE, 10) }) + + test('does not double-count deeply nested (3-level) sub-workflow roots', () => { + // A → B → C: each level is its own synthetic { type: 'workflow' } root with + // an aggregate cost. Only the leaf agents at the bottom must be billed, once. + const leafAgent = (id: string, model: string, total: number) => ({ + id, + name: 'Agent', + type: 'agent', + model, + cost: { input: total / 3, output: (total * 2) / 3, total }, + tokens: { input: 100, output: 200, total: 300 }, + }) + + const traceSpans = [ + { + id: 'root', + name: 'Workflow Execution', + type: 'workflow', + cost: { total: 0.06 }, // aggregate of everything below + children: [ + leafAgent('parent-agent', 'gpt-4o', 0.02), + { + id: 'sub-a-root', + name: 'Workflow Execution', + type: 'workflow', + cost: { total: 0.04 }, + children: [ + leafAgent('a-agent', 'gpt-4o', 0.01), + { + id: 'sub-b-root', + name: 'Workflow Execution', + type: 'workflow', + cost: { total: 0.03 }, + children: [leafAgent('b-agent', 'claude-sonnet-4-6', 0.03)], + }, + ], + }, + ], + }, + ] + + const result = calculateCostSummary(traceSpans) + + expect(result.charges['Workflow Execution']).toBeUndefined() + // gpt-4o appears at two levels (0.02 + 0.01) and merges by model name. + expect(result.models['gpt-4o'].total).toBeCloseTo(0.03, 10) + expect(result.models['claude-sonnet-4-6'].total).toBeCloseTo(0.03, 10) + expect(result.totalCost).toBeCloseTo(0.06 + BASE_EXECUTION_CHARGE, 10) + const ledgerSum = + result.baseExecutionCharge + + Object.values(result.models).reduce((s, m) => s + m.total, 0) + + Object.values(result.charges).reduce((s, c) => s + c.total, 0) + expect(ledgerSum).toBeCloseTo(result.totalCost, 10) + }) }) diff --git a/packages/db/.env.swp b/packages/db/.env.swp deleted file mode 100644 index 27153b0737ce866350e9e2be1f2d286f244ca2e2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI&%}T>S5Ww+i@1p1n)Oc>UUmgqyrc_X{AZoozzGyB*leuU1`dowr@S%y(?Z|A{WFTB*x z!!o5VCbm1$I%=P%x;^Z~+O^}lGua8%5|c$aIO;DjqI79DbGk>^d3w_=q4|Eu$VIe#tJ2m}y7009ILKmY**5I_I{ z1Q7T?fw6UEjjYS#o9V^bp^@k;pQV0w8=Fd16SI0b`o5DN6glSpaL_NW+h_Tm7ivSk E0QbB{H2?qr diff --git a/packages/db/migrations/0219_amused_leo.sql b/packages/db/migrations/0219_amused_leo.sql index c32c029caca..36dcb651ebb 100644 --- a/packages/db/migrations/0219_amused_leo.sql +++ b/packages/db/migrations/0219_amused_leo.sql @@ -1,4 +1,4 @@ -ALTER TABLE "copilot_messages" ADD COLUMN "seq" integer;--> statement-breakpoint +ALTER TABLE "copilot_messages" ADD COLUMN IF NOT EXISTS "seq" integer;--> statement-breakpoint WITH ordered AS ( SELECT c."id" AS chat_id, elem.value->>'id' AS message_id, elem.ord AS ord FROM "copilot_chats" c @@ -16,4 +16,4 @@ ranked AS ( UPDATE "copilot_messages" m SET "seq" = r.seq FROM ranked r WHERE m."chat_id" = r.chat_id AND m."message_id" = r.message_id;--> statement-breakpoint -CREATE INDEX "copilot_messages_chat_seq_idx" ON "copilot_messages" USING btree ("chat_id","seq") WHERE "copilot_messages"."deleted_at" IS NULL; \ No newline at end of file +CREATE INDEX IF NOT EXISTS "copilot_messages_chat_seq_idx" ON "copilot_messages" USING btree ("chat_id","seq") WHERE "copilot_messages"."deleted_at" IS NULL; \ No newline at end of file