Skip to content

Commit cdf89ad

Browse files
committed
Reconcile Plan feature with staging contracts and validation gates
1 parent b25efe4 commit cdf89ad

49 files changed

Lines changed: 3256 additions & 9694 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎apps/desktop/src/main/ipc.test.ts‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,8 @@ describe('registerIpcHandlers', () => {
654654
})
655655
deps.computerUse = service
656656
const cancel = vi.spyOn(service, 'cancel')
657-
const execute = collectHandlers().invoke.get('computer-use:execute-tool')!
657+
const execute = collectHandlers().invoke.get('computer-use:execute-tool')
658+
if (!execute) throw new Error('Computer use handler was not registered')
658659
return { native, approveApp, status, cancel, execute }
659660
}
660661

‎apps/docs/content/docs/integrations/gmail.mdx‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -315,8 +315,6 @@ List all labels in a Gmail account
315315
| --------- | ---- | ----------- |
316316
| `labels` | json | Array of label objects with id, name, type, and visibility settings |
317317

318-
319-
320318
## Triggers
321319

322320
A **Trigger** is a block that starts a workflow when an event happens in this service.

‎apps/sim/app/api/copilot/chat/stream/route.test.ts‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ describe('copilot chat stream replay route', () => {
156156
executionId: 'exec-1',
157157
id: 'run-1',
158158
})
159-
.mockResolvedValueOnce({
159+
.mockResolvedValue({
160160
status: 'cancelled',
161161
executionId: 'exec-1',
162162
id: 'run-1',
@@ -167,14 +167,21 @@ describe('copilot chat stream replay route', () => {
167167
)
168168

169169
const chunks = await readAllChunks(response)
170+
if (elapsedMs >= 3_600_000) {
171+
expect(chunks.join('')).not.toContain('"type":"complete"')
172+
const reattached = await GET(
173+
new NextRequest('http://localhost:3000/api/copilot/chat/stream?streamId=stream-1&after=0')
174+
)
175+
chunks.push(...(await readAllChunks(reattached)))
176+
}
170177
expect(chunks[0]).toBe(': accepted\n\n')
171178
expect(chunks.join('')).toContain(
172179
JSON.stringify({
173180
status: MothershipStreamV1CompletionStatus.cancelled,
174181
reason: 'terminal_status',
175182
})
176183
)
177-
expect(getLatestRunForStream).toHaveBeenCalledTimes(2)
184+
expect(getLatestRunForStream).toHaveBeenCalledTimes(elapsedMs >= 3_600_000 ? 3 : 2)
178185
clock.mockRestore()
179186
}
180187
)

‎apps/sim/app/api/desktop/computer/authorize/route.test.ts‎

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
/** @vitest-environment node */
22
import { authMockFns } from '@sim/testing'
3+
import { rateLimiterMock, rateLimiterMockFns } from '@sim/testing/mocks/rate-limiter.mock'
34
import { NextRequest } from 'next/server'
45
import { beforeEach, describe, expect, it, vi } from 'vitest'
56
import { OrchestrationError } from '@/lib/core/orchestration/types'
67

7-
const mocks = vi.hoisted(() => ({ execute: vi.fn(), rate: vi.fn() }))
8+
const mocks = vi.hoisted(() => ({ execute: vi.fn() }))
89
vi.mock('@/lib/computer-use/application/authorize', () => ({
910
authorizeComputerUse: {
1011
operation: {
@@ -15,10 +16,6 @@ vi.mock('@/lib/computer-use/application/authorize', () => ({
1516
execute: mocks.execute,
1617
},
1718
}))
18-
vi.mock('@/lib/core/rate-limiter', async (importOriginal) => ({
19-
...(await importOriginal<typeof import('@/lib/core/rate-limiter')>()),
20-
enforceUserRateLimit: mocks.rate,
21-
}))
2219

2320
import { POST } from '@/app/api/desktop/computer/authorize/route'
2421

@@ -30,12 +27,11 @@ const request = (body: unknown) =>
3027
})
3128
describe('computer authorization route', () => {
3229
beforeEach(() => {
33-
vi.clearAllMocks()
3430
authMockFns.mockGetSession.mockResolvedValue({
3531
user: { id: 'user-1' },
3632
session: { id: 'session-1' },
3733
})
38-
mocks.rate.mockResolvedValue(null)
34+
rateLimiterMockFns.mockEnforceUserRateLimit.mockResolvedValue(null)
3935
mocks.execute.mockResolvedValue({
4036
toolName: 'computer',
4137
chatId: 'chat-1',
@@ -68,7 +64,11 @@ describe('computer authorization route', () => {
6864
input: { toolCallId: 'call-1' },
6965
})
7066
)
71-
expect(mocks.rate).toHaveBeenCalledWith('desktop-computer-use', 'user-1', undefined)
67+
expect(rateLimiterMockFns.mockEnforceUserRateLimit).toHaveBeenCalledWith(
68+
'desktop-computer-use',
69+
'user-1',
70+
undefined
71+
)
7272
})
7373
it.each([
7474
['not_found', 404],
@@ -78,3 +78,5 @@ describe('computer authorization route', () => {
7878
expect((await POST(request({ toolCallId: 'call-1' }))).status).toBe(status)
7979
})
8080
})
81+
82+
vi.mock('@/lib/core/rate-limiter', () => rateLimiterMock)
Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,2 @@
11
export { BenchmarkDetail } from '@/app/o/[organizationId]/benchmark/components/benchmark-detail'
2-
export { BenchmarkJson } from '@/app/o/[organizationId]/benchmark/components/benchmark-json'
3-
export { BenchmarkReference } from '@/app/o/[organizationId]/benchmark/components/benchmark-reference'
4-
export { BenchmarkResults } from '@/app/o/[organizationId]/benchmark/components/benchmark-results'
5-
export { BenchmarkStep } from '@/app/o/[organizationId]/benchmark/components/benchmark-step'
62
export { CreateBenchmark } from '@/app/o/[organizationId]/benchmark/components/create-benchmark'

‎apps/sim/app/o/[organizationId]/layout.tsx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ import { redirect } from 'next/navigation'
44
import { SettingsNavigationProvider } from '@/components/settings/settings-navigation-provider'
55
import { getSession } from '@/lib/auth'
66
import { getActiveOrganizationId } from '@/lib/auth/session-response'
7-
import { isDashboardsEnabled } from '@/lib/dashboards/feature-flag'
87
import { canUseBenchmarks } from '@/lib/benchmarks/application/access'
8+
import { isDashboardsEnabled } from '@/lib/dashboards/feature-flag'
99
import {
1010
isMemorySpacesEnabled,
1111
isMothershipModelSelectorEnabled,

‎apps/sim/hooks/queries/benchmarks.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import {
2222
updateBenchmarkContract,
2323
} from '@/lib/api/contracts/benchmarks'
2424

25-
export const benchmarkKeys = {
25+
const benchmarkKeys = {
2626
all: ['benchmarks'] as const,
2727
lists: () => [...benchmarkKeys.all, 'list'] as const,
2828
list: (organizationId: string, runAsUserId?: string) =>
@@ -49,7 +49,7 @@ export const benchmarkKeys = {
4949
[...benchmarkKeys.runs(), organizationId, benchmarkId, runId] as const,
5050
}
5151

52-
export const BENCHMARK_STALE_TIME = 10_000
52+
const BENCHMARK_STALE_TIME = 10_000
5353
const BENCHMARK_POLL_INTERVAL = 2_000
5454
const BENCHMARK_PAGE_SIZE = 20
5555

‎apps/sim/hooks/queries/computer-use.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { useQuery } from '@tanstack/react-query'
22
import { requestJson } from '@/lib/api/client'
33
import { computerUseAvailabilityContract } from '@/lib/api/contracts/computer-use'
44

5-
export const computerUseKeys = {
5+
const computerUseKeys = {
66
all: ['computer-use'] as const,
77
availability: () => [...computerUseKeys.all, 'availability'] as const,
88
}

‎apps/sim/hooks/queries/memory-spaces.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import {
99
} from '@/lib/api/contracts/memory-spaces'
1010

1111
const MEMORY_SPACES_STALE_TIME = 10_000
12-
export const memorySpacesKeys = {
12+
const memorySpacesKeys = {
1313
all: ['memory-spaces'] as const,
1414
list: (organizationId: string) => [...memorySpacesKeys.all, organizationId] as const,
1515
}

‎apps/sim/lib/api/contracts/benchmarks.ts‎

Lines changed: 19 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -15,44 +15,44 @@ import {
1515
benchmarkSummarySchema,
1616
} from '@/lib/benchmarks/types'
1717

18-
export const benchmarkOrganizationParamsSchema = z.object({ id: organizationIdSchema })
19-
export const benchmarkParamsSchema = benchmarkOrganizationParamsSchema.extend({
18+
const benchmarkOrganizationParamsSchema = z.object({ id: organizationIdSchema })
19+
const benchmarkParamsSchema = benchmarkOrganizationParamsSchema.extend({
2020
benchmarkId: z.string().min(1).max(128),
2121
})
22-
export const benchmarkRunParamsSchema = benchmarkParamsSchema.extend({
22+
const benchmarkRunParamsSchema = benchmarkParamsSchema.extend({
2323
runId: z.string().min(1).max(128),
2424
})
25-
export const listBenchmarksQuerySchema = z.object({
25+
const listBenchmarksQuerySchema = z.object({
2626
runAsUserId: z.string().min(1).max(128).optional(),
2727
cursor: z.string().min(1).max(512).optional(),
2828
limit: z.coerce.number().int().min(1).max(50).default(20),
2929
})
30-
export const createBenchmarkBodySchema = z
30+
const createBenchmarkBodySchema = z
3131
.object({
3232
runAsUserId: z.string().min(1).max(128),
3333
sourceWorkspaceId: workspaceIdSchema,
3434
name: benchmarkNameSchema,
3535
taskBrief: benchmarkBriefSchema.optional(),
3636
})
3737
.strict()
38-
export const updateBenchmarkBodySchema = benchmarkEditablePatchSchema
38+
const updateBenchmarkBodySchema = benchmarkEditablePatchSchema
3939
.extend({ version: z.number().int().min(1) })
4040
.strict()
41-
export const deleteBenchmarkBodySchema = z.object({ version: z.number().int().min(1) }).strict()
42-
export const runBenchmarkStageBodySchema = deleteBenchmarkBodySchema
41+
const deleteBenchmarkBodySchema = z.object({ version: z.number().int().min(1) }).strict()
42+
const runBenchmarkStageBodySchema = deleteBenchmarkBodySchema
4343
.extend({ stage: benchmarkStageSchema, runLabel: benchmarkRunLabelSchema.optional() })
4444
.strict()
45-
export const benchmarkResponseSchema = z.object({ benchmark: benchmarkCaseSchema })
46-
export const listBenchmarksResponseSchema = z.object({
45+
const benchmarkResponseSchema = z.object({ benchmark: benchmarkCaseSchema })
46+
const listBenchmarksResponseSchema = z.object({
4747
benchmarks: z.array(benchmarkSummarySchema).max(50),
4848
nextCursor: z.string().max(512).nullable(),
4949
})
50-
export const listBenchmarkRunsResponseSchema = z.object({
50+
const listBenchmarkRunsResponseSchema = z.object({
5151
runs: z.array(benchmarkRunSummarySchema).max(50),
5252
nextCursor: z.string().max(512).nullable(),
5353
})
54-
export const benchmarkRunResponseSchema = z.object({ run: benchmarkRunSchema })
55-
export const reviewBenchmarkRunBodySchema = z
54+
const benchmarkRunResponseSchema = z.object({ run: benchmarkRunSchema })
55+
const reviewBenchmarkRunBodySchema = z
5656
.object({
5757
version: z.number().int().min(1),
5858
blankId: benchmarkBlankSchema.shape.id,
@@ -124,21 +124,16 @@ export const reviewBenchmarkRunContract = defineRouteContract({
124124
response: { mode: 'json', schema: benchmarkRunResponseSchema },
125125
})
126126

127-
export type ListBenchmarksResponse = z.infer<typeof listBenchmarksResponseSchema>
128127
export type BenchmarkResponse = z.infer<typeof benchmarkResponseSchema>
129128
export type BenchmarkCase = z.infer<typeof benchmarkCaseSchema>
130-
export type BenchmarkSummary = z.infer<typeof benchmarkSummarySchema>
131129
export type CreateBenchmarkBody = z.input<typeof createBenchmarkBodySchema>
132130
export type UpdateBenchmarkBody = z.input<typeof updateBenchmarkBodySchema>
133131
export type DeleteBenchmarkBody = z.input<typeof deleteBenchmarkBodySchema>
134132
export type RunBenchmarkStageBody = z.input<typeof runBenchmarkStageBodySchema>
135133
export type BenchmarkRun = z.infer<typeof benchmarkRunSchema>
136-
export type BenchmarkRunSummary = z.infer<typeof benchmarkRunSummarySchema>
137-
export type BenchmarkRunResponse = z.infer<typeof benchmarkRunResponseSchema>
138-
export type ListBenchmarkRunsResponse = z.infer<typeof listBenchmarkRunsResponseSchema>
139134
export type ReviewBenchmarkRunBody = z.input<typeof reviewBenchmarkRunBodySchema>
140135

141-
export const benchmarkSelectionQuerySchema = z.object({
136+
const benchmarkSelectionQuerySchema = z.object({
142137
search: z.string().trim().max(200).default(''),
143138
cursor: z.string().min(1).max(128).optional(),
144139
selectedId: z.string().min(1).max(128).optional(),
@@ -148,25 +143,25 @@ const selectionOptionSchema = z.object({
148143
name: z.string().max(1_000),
149144
})
150145
const userOptionSchema = selectionOptionSchema.extend({ email: z.string().max(320) })
151-
export const benchmarkOrganizationsResponseSchema = z.object({
146+
const benchmarkOrganizationsResponseSchema = z.object({
152147
organizations: z.array(selectionOptionSchema).max(50),
153148
selected: selectionOptionSchema.nullable(),
154149
nextCursor: z.string().max(128).nullable(),
155150
})
156-
export const benchmarkUsersResponseSchema = z.object({
151+
const benchmarkUsersResponseSchema = z.object({
157152
users: z.array(userOptionSchema).max(50),
158153
selected: userOptionSchema.nullable(),
159154
nextCursor: z.string().max(128).nullable(),
160155
})
161-
export const benchmarkWorkspacesQuerySchema = benchmarkSelectionQuerySchema
156+
const benchmarkWorkspacesQuerySchema = benchmarkSelectionQuerySchema
162157
.omit({ selectedId: true })
163158
.extend({ runAsUserId: z.string().min(1).max(128) })
164-
export const benchmarkWorkspacesResponseSchema = z.object({
159+
const benchmarkWorkspacesResponseSchema = z.object({
165160
workspaces: z.array(selectionOptionSchema).max(50),
166161
nextCursor: z.string().max(128).nullable(),
167162
canPlan: z.boolean(),
168163
})
169-
export const benchmarkAvailabilityResponseSchema = z.object({ available: z.boolean() })
164+
const benchmarkAvailabilityResponseSchema = z.object({ available: z.boolean() })
170165
export const benchmarkOrganizationsContract = defineRouteContract({
171166
method: 'GET',
172167
path: '/api/benchmarks/organizations',
@@ -192,9 +187,3 @@ export const benchmarkAvailabilityContract = defineRouteContract({
192187
path: '/api/benchmarks/availability',
193188
response: { mode: 'json', schema: benchmarkAvailabilityResponseSchema },
194189
})
195-
export type BenchmarkSelectionQuery = z.input<typeof benchmarkSelectionQuerySchema>
196-
export type BenchmarkWorkspacesQuery = z.input<typeof benchmarkWorkspacesQuerySchema>
197-
export type BenchmarkOrganizationsResponse = z.output<typeof benchmarkOrganizationsResponseSchema>
198-
export type BenchmarkUsersResponse = z.output<typeof benchmarkUsersResponseSchema>
199-
export type BenchmarkWorkspacesResponse = z.output<typeof benchmarkWorkspacesResponseSchema>
200-
export type BenchmarkAvailabilityResponse = z.output<typeof benchmarkAvailabilityResponseSchema>

0 commit comments

Comments
 (0)