Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions apps/docs/openapi-v2-knowledge.json
Original file line number Diff line number Diff line change
Expand Up @@ -728,9 +728,9 @@
"name": "tagFilters",
"in": "query",
"required": false,
"description": "A JSON-encoded array of at most 10 tag filters, using the same display-name shape as knowledge search: `[{\"tagName\":\"category\",\"operator\":\"eq\",\"value\":\"billing\"}]`. A name that is not defined in this knowledge base is rejected, never ignored.",
"description": "A JSON-encoded array of at most 10 tag filters, using the same display-name shape as knowledge search: `[{\"tagName\":\"category\",\"operator\":\"eq\",\"value\":\"billing\"}]`. Every filter must hold, including two that name the same tag. A name that is not defined in this knowledge base is rejected, never ignored.",
"schema": {
"description": "A JSON-encoded array of at most 10 tag filters, using the same display-name shape as knowledge search: `[{\"tagName\":\"category\",\"operator\":\"eq\",\"value\":\"billing\"}]`. A name that is not defined in this knowledge base is rejected, never ignored.",
"description": "A JSON-encoded array of at most 10 tag filters, using the same display-name shape as knowledge search: `[{\"tagName\":\"category\",\"operator\":\"eq\",\"value\":\"billing\"}]`. Every filter must hold, including two that name the same tag. A name that is not defined in this knowledge base is rejected, never ignored.",
"examples": [
"[{\"tagName\":\"category\",\"operator\":\"eq\",\"value\":\"billing\"}]"
],
Expand Down Expand Up @@ -2820,9 +2820,10 @@
"examples": [["7c9e6679-7425-40de-944b-e07fc1f90ae7"]]
},
"query": {
"description": "Natural-language query; required when tag filters are omitted.",
"description": "Natural-language query; required when tag filters are omitted. At most 32768 characters — longer text exceeds the embedding model's per-input token ceiling and would be truncated before the billed search ran.",
"examples": ["How do I reset my password?"],
"type": "string"
"type": "string",
"maxLength": 32768
},
"topK": {
"default": 10,
Expand All @@ -2832,7 +2833,8 @@
"maximum": 100
},
"tagFilters": {
"description": "Structured tag filters. Each filtered tag must resolve to the same slot and field type in every knowledge base selected; one missing from any of them, or defined inconsistently across them, is rejected rather than ignored, and those knowledge bases must be searched separately. List the available names with `GET /api/v2/knowledge/{id}/tags`.",
"description": "Structured tag filters, at most 10 of them. Every filter must hold, including two that name the same tag: repeating one tag narrows the result rather than widening it, matching `GET /api/v2/knowledge/{id}/documents`. To match either of two values for one tag, issue a search per value. Each filtered tag must resolve to the same slot and field type in every knowledge base selected; one missing from any of them, or defined inconsistently across them, is rejected rather than ignored, and those knowledge bases must be searched separately. List the available names with `GET /api/v2/knowledge/{id}/tags`.",
"maxItems": 10,
"type": "array",
"items": {
"$ref": "#/components/schemas/V2KnowledgeSearchTagFilter"
Expand Down
4 changes: 2 additions & 2 deletions apps/docs/openapi-v2-logs.json
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@
"name": "triggers",
"in": "query",
"required": false,
"description": "Comma-separated trigger types to include. An empty entry is rejected. The literal value `all` is a sentinel that disables this filter entirely, so a list containing it returns runs of every trigger type; no real trigger type is named `all`.",
"description": "Comma-separated trigger types to include. An empty entry is rejected. Values are matched exactly and are case-sensitive — every recorded trigger is lowercase, so `API` matches nothing while `api` matches. The vocabulary is open: it covers the core trigger types (`manual`, `api`, `schedule`, `chat`, `webhook`, `mcp`, `copilot`, `workflow`, `custom_block`) and the provider id of any webhook trigger (`slack`, `gmail`, `github`, …), so an unrecognized member is not rejected — it selects no runs. The literal value `all` is a sentinel that disables this filter entirely, so a list containing it returns runs of every trigger type; no real trigger type is named `all`.",
"schema": {
"type": "string",
"description": "Comma-separated trigger types to include. An empty entry is rejected. The literal value `all` is a sentinel that disables this filter entirely, so a list containing it returns runs of every trigger type; no real trigger type is named `all`."
"description": "Comma-separated trigger types to include. An empty entry is rejected. Values are matched exactly and are case-sensitive — every recorded trigger is lowercase, so `API` matches nothing while `api` matches. The vocabulary is open: it covers the core trigger types (`manual`, `api`, `schedule`, `chat`, `webhook`, `mcp`, `copilot`, `workflow`, `custom_block`) and the provider id of any webhook trigger (`slack`, `gmail`, `github`, …), so an unrecognized member is not rejected — it selects no runs. The literal value `all` is a sentinel that disables this filter entirely, so a list containing it returns runs of every trigger type; no real trigger type is named `all`."
}
},
{
Expand Down
8 changes: 3 additions & 5 deletions apps/docs/openapi-v2-resources.json
Original file line number Diff line number Diff line change
Expand Up @@ -2492,7 +2492,7 @@
"description": "Whether the server tools are available to workflows."
},
"connectionStatus": {
"description": "Result of the most recent connection attempt. Registration and re-registration store a configuration without contacting the endpoint, so a server beginsand returns to `disconnected` until a tool discovery runs.",
"description": "Result of the most recent connection attempt. Registration and re-registration establish no connection — the auth-type probe they may send does not count as one — so a server begins, and returns to, `disconnected` until a tool discovery runs.",
"type": "string",
"enum": ["connected", "disconnected", "error"]
},
Expand Down Expand Up @@ -2694,8 +2694,7 @@
"description": "Absolute HTTP or HTTPS endpoint URL without `{{ENV_VAR}}` references. It determines server identity and is immutable: delete and recreate the server to change endpoints."
},
"authType": {
"description": "Authentication method. Applied server-side as `headers` when omitted; registration never contacts the server, so an omitted value is never detected from it.",
"default": "headers",
"description": "Authentication method. When omitted, and no `headers` are sent, registration probes the endpoint once to classify it, falling back to `headers` when the probe fails or the server does not advertise OAuth. A server publishing RFC 9728 metadata is therefore stored as `oauth`, and headers configured afterwards will not authenticate — send this field explicitly to pin the method.",
"type": "string",
"enum": ["none", "headers", "oauth"]
},
Expand Down Expand Up @@ -2881,8 +2880,7 @@
"maxLength": 2048
},
"authType": {
"description": "Authentication method. Applied server-side as `headers` when omitted; registration never contacts the server, so an omitted value is never detected from it.",
"default": "headers",
"description": "Authentication method. When omitted, and no `headers` are sent, registration probes the endpoint once to classify it, falling back to `headers` when the probe fails or the server does not advertise OAuth. A server publishing RFC 9728 metadata is therefore stored as `oauth`, and headers configured afterwards will not authenticate — send this field explicitly to pin the method.",
"type": "string",
"enum": ["none", "headers", "oauth"]
},
Expand Down
6 changes: 4 additions & 2 deletions apps/docs/openapi-v2-tables.json
Original file line number Diff line number Diff line change
Expand Up @@ -6611,7 +6611,8 @@
"type": "boolean"
}
},
"required": ["name", "type"]
"required": ["name", "type"],
"additionalProperties": false
},
"description": "Columns created for producer outputs."
},
Expand Down Expand Up @@ -6750,7 +6751,8 @@
"type": "boolean"
}
},
"required": ["name", "type"]
"required": ["name", "type"],
"additionalProperties": false
}
},
"mappingUpdates": {
Expand Down
25 changes: 12 additions & 13 deletions apps/docs/openapi-v2-workflows.json
Original file line number Diff line number Diff line change
Expand Up @@ -1423,19 +1423,19 @@
"name": "includeOutput",
"in": "query",
"required": false,
"description": "Include final and block outputs when true.",
"description": "Include the final workflow output when true. It does not gate `blockOutputs`, which `selectedOutputs` selects on its own.",
"schema": {
"description": "Include final and block outputs when true.",
"description": "Include the final workflow output when true. It does not gate `blockOutputs`, which `selectedOutputs` selects on its own.",
"type": "boolean"
}
},
{
"name": "selectedOutputs",
"in": "query",
"required": false,
"description": "Comma-separated block output references to include.",
"description": "Comma-separated block output references to include, as `blockId` or `blockId.path`. Block *names* are not resolved here — unlike the execute request, this resource reads a recorded run and matches ids only, so a name selects nothing and yields an empty `blockOutputs`.",
"schema": {
"description": "Comma-separated block output references to include.",
"description": "Comma-separated block output references to include, as `blockId` or `blockId.path`. Block *names* are not resolved here — unlike the execute request, this resource reads a recorded run and matches ids only, so a name selects nothing and yields an empty `blockOutputs`.",
"type": "string"
}
}
Expand Down Expand Up @@ -3882,21 +3882,20 @@
"INVALID_INPUT",
"BLOCK_EXECUTION_FAILED",
"CHILD_WORKFLOW_FAILED",
"OUTPUT_TOO_LARGE",
"EXECUTION_FAILED"
],
"description": "Stable machine-readable execution failure code."
"description": "Stable machine-readable execution failure code. `BLOCK_EXECUTION_FAILED` and `CHILD_WORKFLOW_FAILED` are reported only where block attribution is available; elsewhere a block-level failure is reported as `EXECUTION_FAILED`."
},
"blockId": {
"description": "Identifier of the failing block, when attributable.",
"description": "Identifier of the failing block. Present on the synchronous execute response only; the polled run resource and the resume response cannot attribute a block.",
"type": "string"
},
"blockName": {
"description": "Display name of the failing block.",
"description": "Display name of the failing block. Present on the synchronous execute response only.",
"type": "string"
},
"blockType": {
"description": "Integration or block type that failed.",
"description": "Integration or block type that failed. Present on the synchronous execute response only.",
"type": "string"
}
},
Expand Down Expand Up @@ -4292,7 +4291,7 @@
"type": "null"
}
],
"description": "Trigger type, or null before the run is recorded."
"description": "Trigger type that started the run. Backfilled as `api` for a run that is still queued, so it is populated from the first poll."
},
"startedAt": {
"anyOf": [
Expand All @@ -4303,7 +4302,7 @@
"type": "null"
}
],
"description": "ISO 8601 start timestamp, or null while queued.",
"description": "ISO 8601 start timestamp. A queued run reports the time it was enqueued, so it is populated from the first poll.",
"format": "date-time"
},
"endedAt": {
Expand Down Expand Up @@ -4453,7 +4452,7 @@
"type": "null"
}
],
"description": "Structured execution failure, or null when none occurred."
"description": "Structured execution failure, or null when none occurred. Reclassified from the persisted error message, so `blockId`/`blockName`/`blockType` are absent and a block-level failure reports `EXECUTION_FAILED` here even when the same run reported `BLOCK_EXECUTION_FAILED` on its synchronous execute response."
},
"output": {
"anyOf": [
Expand Down Expand Up @@ -4481,7 +4480,7 @@
"type": "null"
}
],
"description": "Selected block outputs when requested, otherwise null."
"description": "Outputs of the blocks named by `selectedOutputs`, or null when none were requested. Gated by `selectedOutputs` alone — `includeOutput` governs `output` only."
}
},
"required": [
Expand Down
9 changes: 7 additions & 2 deletions apps/sim/app/api/v2/audit-logs/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { v2ListAuditLogsContract } from '@/lib/api/contracts/v2/audit-logs'
import { cursorScopeKey, instantScopePart, unorderedScopePart } from '@/lib/api/cursor-binding'
import {
cursorRoute,
cursorScopeKey,
instantScopePart,
unorderedScopePart,
} from '@/lib/api/cursor-binding'
import {
defineV2JsonRoute,
v2ApiKeyAuth,
Expand All @@ -23,7 +28,7 @@ function auditLogCursorFilters(query: {
startDate?: string
endDate?: string
}) {
return cursorScopeKey({
return cursorScopeKey(cursorRoute(v2ListAuditLogsContract), {
organizationId: query.organizationId,
includeDeparted: query.includeDeparted,
action: query.action,
Expand Down
5 changes: 3 additions & 2 deletions apps/sim/app/api/v2/billing/logs/route.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ vi.mock('@/lib/billing/application/list-billing-logs', () => ({
listBillingLogs: { operation: { id: 'billing.logs.list' }, execute: mocks.execute },
}))

import { cursorScopeKey } from '@/lib/api/cursor-binding'
import { v2ListBillingLogsContract } from '@/lib/api/contracts/v2/billing'
import { cursorRoute, cursorScopeKey } from '@/lib/api/cursor-binding'
import { UNKNOWN_CURSOR_MESSAGE } from '@/lib/billing/core/usage-log'
import { OrchestrationError } from '@/lib/core/orchestration/types'
import { GET } from '@/app/api/v2/billing/logs/route'
Expand All @@ -35,7 +36,7 @@ function ledgerCursor(
inner: string,
filters: { source?: string; workspaceId?: string; period?: string }
): string {
return encodeScopedCursor(cursorScopeKey(filters), inner)
return encodeScopedCursor(cursorScopeKey(cursorRoute(v2ListBillingLogsContract), filters), inner)
}

const auth = {
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/v2/billing/logs/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { v2ListBillingLogsContract } from '@/lib/api/contracts/v2/billing'
import { cursorScopeKey, instantScopePart } from '@/lib/api/cursor-binding'
import { cursorRoute, cursorScopeKey, instantScopePart } from '@/lib/api/cursor-binding'
import { defineV2JsonRoute, v2ApiKeyAuth, v2RateLimits } from '@/lib/api/server/routes'
import { v2BillingErrorPolicies } from '@/lib/billing/api/route-policies'
import { listBillingLogs } from '@/lib/billing/application/list-billing-logs'
Expand Down Expand Up @@ -32,7 +32,7 @@ function billingLogCursorFilters(query: {
startDate?: string
endDate?: string
}) {
return cursorScopeKey({
return cursorScopeKey(cursorRoute(v2ListBillingLogsContract), {
source: query.source,
workspaceId: query.workspaceId,
period: query.period,
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/v2/credentials/route.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { V2Credential } from '@/lib/api/contracts/v2/credentials'
import { v2ListCredentialsContract } from '@/lib/api/contracts/v2/credentials'
import { cursorScopeKey } from '@/lib/api/cursor-binding'
import { cursorRoute, cursorScopeKey } from '@/lib/api/cursor-binding'
import {
defineV2JsonRoute,
v2ApiKeyAuth,
Expand Down Expand Up @@ -42,7 +42,7 @@ function credentialCursorFilters(query: {
providerId?: string
search?: string
}) {
return cursorScopeKey({
return cursorScopeKey(cursorRoute(v2ListCredentialsContract), {
workspaceId: query.workspaceId,
type: query.type,
providerId: query.providerId,
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/v2/custom-tools/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
v2CreateCustomToolContract,
v2ListCustomToolsContract,
} from '@/lib/api/contracts/v2/custom-tools'
import { cursorScopeKey } from '@/lib/api/cursor-binding'
import { cursorRoute, cursorScopeKey } from '@/lib/api/cursor-binding'
import {
defineV2JsonRoute,
v2ApiKeyAuth,
Expand All @@ -22,7 +22,7 @@ export const revalidate = 0

/** Every param that changes which custom tools, in which order, this list returns. */
function customToolCursorFilters(query: { workspaceId: string; search?: string }) {
return cursorScopeKey({
return cursorScopeKey(cursorRoute(v2ListCustomToolsContract), {
workspaceId: query.workspaceId,
search: query.search,
})
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/v2/files/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {
v2CreateFileContract,
v2ListFilesContract,
} from '@/lib/api/contracts/v2/files'
import { cursorScopeKey } from '@/lib/api/cursor-binding'
import { cursorRoute, cursorScopeKey } from '@/lib/api/cursor-binding'
import { defineV2JsonRoute, v2ApiKeyAuth, v2RateLimits } from '@/lib/api/server/routes'
import { getFileExtension, getMimeTypeFromExtension } from '@/lib/uploads/utils/file-utils'
import { v2FileErrorPolicies } from '@/lib/workspace-files/api'
Expand All @@ -24,7 +24,7 @@ function fileCursorFilters(query: {
folderPath?: string
search?: string
}) {
return cursorScopeKey({
return cursorScopeKey(cursorRoute(v2ListFilesContract), {
workspaceId: query.workspaceId,
scope: query.scope,
folderPath: query.folderPath,
Expand Down
5 changes: 2 additions & 3 deletions apps/sim/app/api/v2/knowledge/[id]/documents/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
v2ListKnowledgeDocumentsContract,
v2UploadKnowledgeDocumentContract,
} from '@/lib/api/contracts/v2/knowledge'
import { cursorScopeKey, unorderedScopeOf } from '@/lib/api/cursor-binding'
import { cursorRoute, cursorScopeKey, unorderedScopeOf } from '@/lib/api/cursor-binding'
import {
defineV2BodyLifecycleRoute,
defineV2JsonRoute,
Expand Down Expand Up @@ -59,8 +59,7 @@ function documentCursorFilters(
query: { workspaceId: string; enabledFilter?: string; search?: string; tagFilters?: string }
) {
const parsed = parseV2KnowledgeTagFiltersParam(query.tagFilters)
return cursorScopeKey({
knowledgeBaseId,
return cursorScopeKey(cursorRoute(v2ListKnowledgeDocumentsContract, { id: knowledgeBaseId }), {
workspaceId: query.workspaceId,
enabledFilter: query.enabledFilter,
search: query.search,
Expand Down
4 changes: 2 additions & 2 deletions apps/sim/app/api/v2/knowledge/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import {
v2CreateKnowledgeBaseContract,
v2ListKnowledgeBasesContract,
} from '@/lib/api/contracts/v2/knowledge'
import { cursorScopeKey } from '@/lib/api/cursor-binding'
import { cursorRoute, cursorScopeKey } from '@/lib/api/cursor-binding'
import {
defineV2JsonRoute,
v2ApiKeyAuth,
Expand All @@ -28,7 +28,7 @@ function knowledgeCursorFilters(query: {
folderPath?: string
search?: string
}) {
return cursorScopeKey({
return cursorScopeKey(cursorRoute(v2ListKnowledgeBasesContract), {
workspaceId: query.workspaceId,
folderPath: query.folderPath,
search: query.search,
Expand Down
Loading
Loading