Compare commits

..

1 Commits

Author SHA1 Message Date
Waleed Latif
9ecd07b12c fix(ci): update ci 2026-01-24 14:27:55 -08:00
8 changed files with 78 additions and 136 deletions

View File

@@ -27,8 +27,9 @@ jobs:
steps:
- name: Extract version from commit message
id: extract
env:
COMMIT_MSG: ${{ github.event.head_commit.message }}
run: |
COMMIT_MSG="${{ github.event.head_commit.message }}"
# Only tag versions on main branch
if [ "${{ github.ref }}" = "refs/heads/main" ] && [[ "$COMMIT_MSG" =~ ^(v[0-9]+\.[0-9]+\.[0-9]+): ]]; then
VERSION="${BASH_REMATCH[1]}"

View File

@@ -1,15 +1,7 @@
import { useEffect, useRef, useState } from 'react'
import { Plus } from 'lucide-react'
import { useParams } from 'next/navigation'
import {
Badge,
Button,
Combobox,
type ComboboxOption,
Input,
Label,
Textarea,
} from '@/components/emcn'
import { Badge, Button, Combobox, Input, Label, Textarea } from '@/components/emcn'
import { Trash } from '@/components/emcn/icons/trash'
import { cn } from '@/lib/core/utils/cn'
import { formatDisplayText } from '@/app/workspace/[workspaceId]/w/[workflowId]/components/panel/components/editor/components/sub-block/components/formatted-text'
@@ -46,14 +38,6 @@ const DEFAULT_ASSIGNMENT: Omit<VariableAssignment, 'id'> = {
isExisting: false,
}
/**
* Boolean value options for Combobox
*/
const BOOLEAN_OPTIONS: ComboboxOption[] = [
{ label: 'true', value: 'true' },
{ label: 'false', value: 'false' },
]
/**
* Parses a value that might be a JSON string or already an array of VariableAssignment.
* This handles the case where workflows are imported with stringified values.
@@ -120,6 +104,8 @@ export function VariablesInput({
const allVariablesAssigned =
!hasNoWorkflowVariables && getAvailableVariablesFor('new').length === 0
// Initialize with one empty assignment if none exist and not in preview/disabled mode
// Also add assignment when first variable is created
useEffect(() => {
if (!isReadOnly && assignments.length === 0 && currentWorkflowVariables.length > 0) {
const initialAssignment: VariableAssignment = {
@@ -130,46 +116,45 @@ export function VariablesInput({
}
}, [currentWorkflowVariables.length, isReadOnly, assignments.length, setStoreValue])
// Clean up assignments when their associated variables are deleted
useEffect(() => {
if (isReadOnly || assignments.length === 0) return
const currentVariableIds = new Set(currentWorkflowVariables.map((v) => v.id))
const validAssignments = assignments.filter((assignment) => {
// Keep assignments that haven't selected a variable yet
if (!assignment.variableId) return true
// Keep assignments whose variable still exists
return currentVariableIds.has(assignment.variableId)
})
// If all variables were deleted, clear all assignments
if (currentWorkflowVariables.length === 0) {
setStoreValue([])
} else if (validAssignments.length !== assignments.length) {
// Some assignments reference deleted variables, remove them
setStoreValue(validAssignments.length > 0 ? validAssignments : [])
}
}, [currentWorkflowVariables, assignments, isReadOnly, setStoreValue])
const addAssignment = () => {
if (isReadOnly || allVariablesAssigned) return
if (isPreview || disabled || allVariablesAssigned) return
const newAssignment: VariableAssignment = {
...DEFAULT_ASSIGNMENT,
id: crypto.randomUUID(),
}
setStoreValue([...assignments, newAssignment])
setStoreValue([...(assignments || []), newAssignment])
}
const removeAssignment = (id: string) => {
if (isReadOnly) return
if (assignments.length === 1) {
setStoreValue([{ ...DEFAULT_ASSIGNMENT, id: crypto.randomUUID() }])
return
}
setStoreValue(assignments.filter((a) => a.id !== id))
if (isPreview || disabled) return
setStoreValue((assignments || []).filter((a) => a.id !== id))
}
const updateAssignment = (id: string, updates: Partial<VariableAssignment>) => {
if (isReadOnly) return
setStoreValue(assignments.map((a) => (a.id === id ? { ...a, ...updates } : a)))
if (isPreview || disabled) return
setStoreValue((assignments || []).map((a) => (a.id === id ? { ...a, ...updates } : a)))
}
const handleVariableSelect = (assignmentId: string, variableId: string) => {
@@ -184,12 +169,19 @@ export function VariablesInput({
}
}
const handleTagSelect = (newValue: string) => {
const handleTagSelect = (tag: string) => {
if (!activeFieldId) return
const assignment = assignments.find((a) => a.id === activeFieldId)
const originalValue = assignment?.value || ''
const textAfterCursor = originalValue.slice(cursorPosition)
if (!assignment) return
const currentValue = assignment.value || ''
const textBeforeCursor = currentValue.slice(0, cursorPosition)
const lastOpenBracket = textBeforeCursor.lastIndexOf('<')
const newValue =
currentValue.slice(0, lastOpenBracket) + tag + currentValue.slice(cursorPosition)
updateAssignment(activeFieldId, { value: newValue })
setShowTags(false)
@@ -198,7 +190,7 @@ export function VariablesInput({
const inputEl = valueInputRefs.current[activeFieldId]
if (inputEl) {
inputEl.focus()
const newCursorPos = newValue.length - textAfterCursor.length
const newCursorPos = lastOpenBracket + tag.length
inputEl.setSelectionRange(newCursorPos, newCursorPos)
}
}, 10)
@@ -280,18 +272,6 @@ export function VariablesInput({
}))
}
const syncOverlayScroll = (assignmentId: string, scrollLeft: number) => {
const overlay = overlayRefs.current[assignmentId]
if (overlay) overlay.scrollLeft = scrollLeft
}
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement | HTMLTextAreaElement>) => {
if (e.key === 'Escape') {
setShowTags(false)
setActiveSourceBlockId(null)
}
}
if (isPreview && (!assignments || assignments.length === 0)) {
return (
<div className='flex flex-col items-center justify-center rounded-md border border-border/40 bg-muted/20 py-8 text-center'>
@@ -322,7 +302,7 @@ export function VariablesInput({
return (
<div className='space-y-[8px]'>
{assignments.length > 0 && (
{assignments && assignments.length > 0 && (
<div className='space-y-[8px]'>
{assignments.map((assignment, index) => {
const collapsed = collapsedAssignments[assignment.id] || false
@@ -354,7 +334,7 @@ export function VariablesInput({
<Button
variant='ghost'
onClick={addAssignment}
disabled={isReadOnly || allVariablesAssigned}
disabled={isPreview || disabled || allVariablesAssigned}
className='h-auto p-0'
>
<Plus className='h-[14px] w-[14px]' />
@@ -363,7 +343,7 @@ export function VariablesInput({
<Button
variant='ghost'
onClick={() => removeAssignment(assignment.id)}
disabled={isReadOnly}
disabled={isPreview || disabled || assignments.length === 1}
className='h-auto p-0 text-[var(--text-error)] hover:text-[var(--text-error)]'
>
<Trash className='h-[14px] w-[14px]' />
@@ -378,26 +358,16 @@ export function VariablesInput({
<Label className='text-[13px]'>Variable</Label>
<Combobox
options={availableVars.map((v) => ({ label: v.name, value: v.id }))}
value={assignment.variableId || ''}
value={assignment.variableId || assignment.variableName || ''}
onChange={(value) => handleVariableSelect(assignment.id, value)}
placeholder='Select a variable...'
disabled={isReadOnly}
disabled={isPreview || disabled}
/>
</div>
<div className='flex flex-col gap-[6px]'>
<Label className='text-[13px]'>Value</Label>
{assignment.type === 'boolean' ? (
<Combobox
options={BOOLEAN_OPTIONS}
value={assignment.value ?? ''}
onChange={(v) =>
!isReadOnly && updateAssignment(assignment.id, { value: v })
}
placeholder='Select value'
disabled={isReadOnly}
/>
) : assignment.type === 'object' || assignment.type === 'array' ? (
{assignment.type === 'object' || assignment.type === 'array' ? (
<div className='relative'>
<Textarea
ref={(el) => {
@@ -411,32 +381,26 @@ export function VariablesInput({
e.target.selectionStart ?? undefined
)
}
onKeyDown={handleKeyDown}
onFocus={() => {
if (!isReadOnly && !assignment.value?.trim()) {
if (!isPreview && !disabled && !assignment.value?.trim()) {
setActiveFieldId(assignment.id)
setCursorPosition(0)
setShowTags(true)
}
}}
onScroll={(e) => {
const overlay = overlayRefs.current[assignment.id]
if (overlay) {
overlay.scrollTop = e.currentTarget.scrollTop
overlay.scrollLeft = e.currentTarget.scrollLeft
}
}}
placeholder={
assignment.type === 'object'
? '{\n "key": "value"\n}'
: '[\n 1, 2, 3\n]'
}
disabled={isReadOnly}
disabled={isPreview || disabled}
className={cn(
'min-h-[120px] font-mono text-sm text-transparent caret-foreground placeholder:text-muted-foreground/50',
dragHighlight[assignment.id] && 'ring-2 ring-blue-500 ring-offset-2'
)}
style={{
fontFamily: 'inherit',
lineHeight: 'inherit',
wordBreak: 'break-word',
whiteSpace: 'pre-wrap',
}}
@@ -449,7 +413,10 @@ export function VariablesInput({
if (el) overlayRefs.current[assignment.id] = el
}}
className='pointer-events-none absolute inset-0 flex items-start overflow-auto bg-transparent px-3 py-2 font-mono text-sm'
style={{ scrollbarWidth: 'none' }}
style={{
fontFamily: 'inherit',
lineHeight: 'inherit',
}}
>
<div className='w-full whitespace-pre-wrap break-words'>
{formatDisplayText(assignment.value || '', {
@@ -474,34 +441,21 @@ export function VariablesInput({
e.target.selectionStart ?? undefined
)
}
onKeyDown={handleKeyDown}
onFocus={() => {
if (!isReadOnly && !assignment.value?.trim()) {
if (!isPreview && !disabled && !assignment.value?.trim()) {
setActiveFieldId(assignment.id)
setCursorPosition(0)
setShowTags(true)
}
}}
onScroll={(e) =>
syncOverlayScroll(assignment.id, e.currentTarget.scrollLeft)
}
onPaste={() =>
setTimeout(() => {
const input = valueInputRefs.current[assignment.id]
if (input)
syncOverlayScroll(
assignment.id,
(input as HTMLInputElement).scrollLeft
)
}, 0)
}
placeholder={`${assignment.type} value`}
disabled={isReadOnly}
disabled={isPreview || disabled}
autoComplete='off'
className={cn(
'allow-scroll w-full overflow-x-auto overflow-y-hidden text-transparent caret-foreground',
'allow-scroll w-full overflow-auto text-transparent caret-foreground',
dragHighlight[assignment.id] && 'ring-2 ring-blue-500 ring-offset-2'
)}
style={{ overflowX: 'auto' }}
onDrop={(e) => handleDrop(e, assignment.id)}
onDragOver={(e) => handleDragOver(e, assignment.id)}
onDragLeave={(e) => handleDragLeave(e, assignment.id)}
@@ -511,7 +465,7 @@ export function VariablesInput({
if (el) overlayRefs.current[assignment.id] = el
}}
className='pointer-events-none absolute inset-0 flex items-center overflow-x-auto bg-transparent px-[8px] py-[6px] font-medium font-sans text-sm'
style={{ scrollbarWidth: 'none' }}
style={{ overflowX: 'auto' }}
>
<div
className='w-full whitespace-pre'

View File

@@ -4,9 +4,9 @@ import { createLogger } from '@sim/logger'
import { eq } from 'drizzle-orm'
import { refreshTokenIfNeeded } from '@/app/api/auth/oauth/utils'
import type { BlockOutput } from '@/blocks/types'
import { BlockType, DEFAULTS, EVALUATOR } from '@/executor/constants'
import { BlockType, DEFAULTS, EVALUATOR, HTTP } from '@/executor/constants'
import type { BlockHandler, ExecutionContext } from '@/executor/types'
import { buildAPIUrl, buildAuthHeaders, extractAPIErrorMessage } from '@/executor/utils/http'
import { buildAPIUrl, extractAPIErrorMessage } from '@/executor/utils/http'
import { isJSONString, parseJSON, stringifyJSON } from '@/executor/utils/json'
import { validateModelProvider } from '@/executor/utils/permission-check'
import { calculateCost, getProviderFromModel } from '@/providers/utils'
@@ -143,7 +143,9 @@ export class EvaluatorBlockHandler implements BlockHandler {
const response = await fetch(url.toString(), {
method: 'POST',
headers: await buildAuthHeaders(),
headers: {
'Content-Type': HTTP.CONTENT_TYPE.JSON,
},
body: stringifyJSON(providerRequest),
})

View File

@@ -9,12 +9,12 @@ import type { BlockOutput } from '@/blocks/types'
import {
BlockType,
DEFAULTS,
HTTP,
isAgentBlockType,
isRouterV2BlockType,
ROUTER,
} from '@/executor/constants'
import type { BlockHandler, ExecutionContext } from '@/executor/types'
import { buildAuthHeaders } from '@/executor/utils/http'
import { validateModelProvider } from '@/executor/utils/permission-check'
import { calculateCost, getProviderFromModel } from '@/providers/utils'
import type { SerializedBlock } from '@/serializer/types'
@@ -118,7 +118,9 @@ export class RouterBlockHandler implements BlockHandler {
const response = await fetch(url.toString(), {
method: 'POST',
headers: await buildAuthHeaders(),
headers: {
'Content-Type': HTTP.CONTENT_TYPE.JSON,
},
body: JSON.stringify(providerRequest),
})
@@ -275,7 +277,9 @@ export class RouterBlockHandler implements BlockHandler {
const response = await fetch(url.toString(), {
method: 'POST',
headers: await buildAuthHeaders(),
headers: {
'Content-Type': HTTP.CONTENT_TYPE.JSON,
},
body: JSON.stringify(providerRequest),
})

View File

@@ -24,7 +24,7 @@
},
"dependencies": {
"@a2a-js/sdk": "0.3.7",
"@anthropic-ai/sdk": "0.71.2",
"@anthropic-ai/sdk": "^0.39.0",
"@aws-sdk/client-bedrock-runtime": "3.940.0",
"@aws-sdk/client-dynamodb": "3.940.0",
"@aws-sdk/client-rds-data": "3.940.0",

View File

@@ -1,5 +1,4 @@
import Anthropic from '@anthropic-ai/sdk'
import { transformJSONSchema } from '@anthropic-ai/sdk/lib/transform-json-schema'
import { createLogger } from '@sim/logger'
import type { StreamingExecution } from '@/executor/types'
import { MAX_TOOL_ITERATIONS } from '@/providers'
@@ -186,10 +185,13 @@ export const anthropicProvider: ProviderConfig = {
const schema = request.responseFormat.schema || request.responseFormat
if (useNativeStructuredOutputs) {
const transformedSchema = transformJSONSchema(schema)
const schemaWithConstraints = {
...schema,
additionalProperties: false,
}
payload.output_format = {
type: 'json_schema',
schema: transformedSchema,
schema: schemaWithConstraints,
}
logger.info(`Using native structured outputs for model: ${modelId}`)
} else {

View File

@@ -55,7 +55,7 @@
"version": "0.1.0",
"dependencies": {
"@a2a-js/sdk": "0.3.7",
"@anthropic-ai/sdk": "0.71.2",
"@anthropic-ai/sdk": "^0.39.0",
"@aws-sdk/client-bedrock-runtime": "3.940.0",
"@aws-sdk/client-dynamodb": "3.940.0",
"@aws-sdk/client-rds-data": "3.940.0",
@@ -363,7 +363,7 @@
"@ampproject/remapping": ["@ampproject/remapping@2.3.0", "", { "dependencies": { "@jridgewell/gen-mapping": "^0.3.5", "@jridgewell/trace-mapping": "^0.3.24" } }, "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw=="],
"@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.71.2", "", { "dependencies": { "json-schema-to-ts": "^3.1.1" }, "peerDependencies": { "zod": "^3.25.0 || ^4.0.0" }, "optionalPeers": ["zod"], "bin": { "anthropic-ai-sdk": "bin/cli" } }, "sha512-TGNDEUuEstk/DKu0/TflXAEt+p+p/WhTlFzEnoosvbaDU2LTjm42igSdlL0VijrKpWejtOKxX0b8A7uc+XiSAQ=="],
"@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.39.0", "", { "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7" } }, "sha512-eMyDIPRZbt1CCLErRCi3exlAvNkBtRe+kW5vvJyef93PmNr/clstYgHhtvmkxN82nlKgzyGPCyGxrm0JQ1ZIdg=="],
"@ark/schema": ["@ark/schema@0.56.0", "", { "dependencies": { "@ark/util": "0.56.0" } }, "sha512-ECg3hox/6Z/nLajxXqNhgPtNdHWC9zNsDyskwO28WinoFEnWow4IsERNz9AnXRhTZJnYIlAJ4uGn3nlLk65vZA=="],
@@ -547,8 +547,6 @@
"@babel/plugin-transform-react-jsx-source": ["@babel/plugin-transform-react-jsx-source@7.27.1", "", { "dependencies": { "@babel/helper-plugin-utils": "^7.27.1" }, "peerDependencies": { "@babel/core": "^7.0.0-0" } }, "sha512-zbwoTsBruTeKB9hSq73ha66iFeJHuaFkUbwvqElnygoNbj/jHRsSeokowZFN3CZ64IvEqcmmkVe89OPXc7ldAw=="],
"@babel/runtime": ["@babel/runtime@7.28.6", "", {}, "sha512-05WQkdpL9COIMz4LjTxGpPNCdlpyimKppYNoJ5Di5EUObifl8t4tuLuUBBZEpoLYOmfvIWrsp9fCl0HoPRVTdA=="],
"@babel/template": ["@babel/template@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/parser": "^7.28.6", "@babel/types": "^7.28.6" } }, "sha512-YA6Ma2KsCdGb+WC6UpBVFJGXL58MDA6oyONbjyF/+5sBgxY/dwkhLogbMT2GXXyU84/IhRw/2D1Os1B/giz+BQ=="],
"@babel/traverse": ["@babel/traverse@7.28.6", "", { "dependencies": { "@babel/code-frame": "^7.28.6", "@babel/generator": "^7.28.6", "@babel/helper-globals": "^7.28.0", "@babel/parser": "^7.28.6", "@babel/template": "^7.28.6", "@babel/types": "^7.28.6", "debug": "^4.3.1" } }, "sha512-fgWX62k02qtjqdSNTAGxmKYY/7FSL9WAS1o2Hu5+I5m9T0yxZzr4cnrfXQ/MX0rIifthCSs6FKTlzYbJcPtMNg=="],
@@ -2445,8 +2443,6 @@
"json-schema": ["json-schema@0.4.0", "", {}, "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA=="],
"json-schema-to-ts": ["json-schema-to-ts@3.1.1", "", { "dependencies": { "@babel/runtime": "^7.18.3", "ts-algebra": "^2.0.0" } }, "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g=="],
"json-schema-traverse": ["json-schema-traverse@0.4.1", "", {}, "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="],
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
@@ -3391,8 +3387,6 @@
"trough": ["trough@2.2.0", "", {}, "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw=="],
"ts-algebra": ["ts-algebra@2.0.0", "", {}, "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw=="],
"ts-interface-checker": ["ts-interface-checker@0.1.13", "", {}, "sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA=="],
"tsafe": ["tsafe@1.8.12", "", {}, "sha512-nFRqW0ttu/2o6XTXsHiVZWJBCOaxhVqZLg7dgs3coZNsCMPXPfwz+zPHAQA+70fNnVJLAPg1EgGIqK9Q84tvAw=="],
@@ -3599,6 +3593,10 @@
"zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="],
"@anthropic-ai/sdk/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"@anthropic-ai/sdk/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
"@asamuzakjp/css-color/lru-cache": ["lru-cache@10.4.3", "", {}, "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ=="],
"@aws-crypto/crc32/@aws-sdk/types": ["@aws-sdk/types@3.969.0", "", { "dependencies": { "@smithy/types": "^4.12.0", "tslib": "^2.6.2" } }, "sha512-7IIzM5TdiXn+VtgPdVLjmE6uUBUtnga0f4RiSEI1WW10RPuNvZ9U+pL3SwDiRDAdoGrOF9tSLJOFZmfuwYuVYQ=="],
@@ -3715,8 +3713,6 @@
"@browserbasehq/sdk/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
"@browserbasehq/stagehand/@anthropic-ai/sdk": ["@anthropic-ai/sdk@0.39.0", "", { "dependencies": { "@types/node": "^18.11.18", "@types/node-fetch": "^2.6.4", "abort-controller": "^3.0.0", "agentkeepalive": "^4.2.1", "form-data-encoder": "1.7.2", "formdata-node": "^4.3.2", "node-fetch": "^2.6.7" } }, "sha512-eMyDIPRZbt1CCLErRCi3exlAvNkBtRe+kW5vvJyef93PmNr/clstYgHhtvmkxN82nlKgzyGPCyGxrm0JQ1ZIdg=="],
"@cerebras/cerebras_cloud_sdk/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"@cerebras/cerebras_cloud_sdk/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
@@ -4219,6 +4215,10 @@
"xml2js/xmlbuilder": ["xmlbuilder@11.0.1", "", {}, "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA=="],
"@anthropic-ai/sdk/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"@anthropic-ai/sdk/node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
"@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="],
"@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from": ["@smithy/util-buffer-from@2.2.0", "", { "dependencies": { "@smithy/is-array-buffer": "^2.2.0", "tslib": "^2.6.2" } }, "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA=="],
@@ -4275,10 +4275,6 @@
"@browserbasehq/sdk/node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
"@browserbasehq/stagehand/@anthropic-ai/sdk/@types/node": ["@types/node@18.19.130", "", { "dependencies": { "undici-types": "~5.26.4" } }, "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg=="],
"@browserbasehq/stagehand/@anthropic-ai/sdk/node-fetch": ["node-fetch@2.7.0", "", { "dependencies": { "whatwg-url": "^5.0.0" }, "peerDependencies": { "encoding": "^0.1.0" }, "optionalPeers": ["encoding"] }, "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A=="],
"@cerebras/cerebras_cloud_sdk/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"@cerebras/cerebras_cloud_sdk/node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
@@ -4689,6 +4685,10 @@
"vite/esbuild/@esbuild/win32-x64": ["@esbuild/win32-x64@0.27.2", "", { "os": "win32", "cpu": "x64" }, "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ=="],
"@anthropic-ai/sdk/node-fetch/whatwg-url/tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
"@anthropic-ai/sdk/node-fetch/whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
"@aws-crypto/sha1-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="],
"@aws-crypto/sha256-browser/@smithy/util-utf8/@smithy/util-buffer-from/@smithy/is-array-buffer": ["@smithy/is-array-buffer@2.2.0", "", { "dependencies": { "tslib": "^2.6.2" } }, "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA=="],
@@ -4737,10 +4737,6 @@
"@browserbasehq/sdk/node-fetch/whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
"@browserbasehq/stagehand/@anthropic-ai/sdk/@types/node/undici-types": ["undici-types@5.26.5", "", {}, "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="],
"@browserbasehq/stagehand/@anthropic-ai/sdk/node-fetch/whatwg-url": ["whatwg-url@5.0.0", "", { "dependencies": { "tr46": "~0.0.3", "webidl-conversions": "^3.0.0" } }, "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw=="],
"@cerebras/cerebras_cloud_sdk/node-fetch/whatwg-url/tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
"@cerebras/cerebras_cloud_sdk/node-fetch/whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
@@ -4833,10 +4829,6 @@
"@aws-sdk/client-sqs/@aws-sdk/credential-provider-node/@aws-sdk/credential-provider-sso/@aws-sdk/token-providers/@aws-sdk/nested-clients": ["@aws-sdk/nested-clients@3.947.0", "", { "dependencies": { "@aws-crypto/sha256-browser": "5.2.0", "@aws-crypto/sha256-js": "5.2.0", "@aws-sdk/core": "3.947.0", "@aws-sdk/middleware-host-header": "3.936.0", "@aws-sdk/middleware-logger": "3.936.0", "@aws-sdk/middleware-recursion-detection": "3.936.0", "@aws-sdk/middleware-user-agent": "3.947.0", "@aws-sdk/region-config-resolver": "3.936.0", "@aws-sdk/types": "3.936.0", "@aws-sdk/util-endpoints": "3.936.0", "@aws-sdk/util-user-agent-browser": "3.936.0", "@aws-sdk/util-user-agent-node": "3.947.0", "@smithy/config-resolver": "^4.4.3", "@smithy/core": "^3.18.7", "@smithy/fetch-http-handler": "^5.3.6", "@smithy/hash-node": "^4.2.5", "@smithy/invalid-dependency": "^4.2.5", "@smithy/middleware-content-length": "^4.2.5", "@smithy/middleware-endpoint": "^4.3.14", "@smithy/middleware-retry": "^4.4.14", "@smithy/middleware-serde": "^4.2.6", "@smithy/middleware-stack": "^4.2.5", "@smithy/node-config-provider": "^4.3.5", "@smithy/node-http-handler": "^4.4.5", "@smithy/protocol-http": "^5.3.5", "@smithy/smithy-client": "^4.9.10", "@smithy/types": "^4.9.0", "@smithy/url-parser": "^4.2.5", "@smithy/util-base64": "^4.3.0", "@smithy/util-body-length-browser": "^4.2.0", "@smithy/util-body-length-node": "^4.2.1", "@smithy/util-defaults-mode-browser": "^4.3.13", "@smithy/util-defaults-mode-node": "^4.2.16", "@smithy/util-endpoints": "^3.2.5", "@smithy/util-middleware": "^4.2.5", "@smithy/util-retry": "^4.2.5", "@smithy/util-utf8": "^4.2.0", "tslib": "^2.6.2" } }, "sha512-DjRJEYNnHUTu9kGPPQDTSXquwSEd6myKR4ssI4FaYLFhdT3ldWpj73yYt807H3tdmhS7vPmdVqchSJnjurUQAw=="],
"@browserbasehq/stagehand/@anthropic-ai/sdk/node-fetch/whatwg-url/tr46": ["tr46@0.0.3", "", {}, "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw=="],
"@browserbasehq/stagehand/@anthropic-ai/sdk/node-fetch/whatwg-url/webidl-conversions": ["webidl-conversions@3.0.1", "", {}, "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ=="],
"@trigger.dev/core/socket.io/engine.io/@types/node/undici-types": ["undici-types@7.10.0", "", {}, "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag=="],
"lint-staged/listr2/cli-truncate/string-width/strip-ansi": ["strip-ansi@7.1.2", "", { "dependencies": { "ansi-regex": "^6.0.1" } }, "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA=="],

View File

@@ -71,19 +71,6 @@ vi.mock('@/executor/path')
vi.mock('@/executor/resolver', () => ({
InputResolver: vi.fn(),
}))
vi.mock('@/executor/utils/http', () => ({
buildAuthHeaders: vi.fn().mockResolvedValue({ 'Content-Type': 'application/json' }),
buildAPIUrl: vi.fn((path: string) => new URL(path, 'http://localhost:3000')),
extractAPIErrorMessage: vi.fn(async (response: Response) => {
const defaultMessage = `API request failed with status ${response.status}`
try {
const errorData = await response.json()
return errorData.error || defaultMessage
} catch {
return defaultMessage
}
}),
}))
// Specific block utilities
vi.mock('@/blocks/blocks/router')