Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
253161a
feat(mult-credentials): progress
icecrasher321 Feb 11, 2026
7314675
checkpoint
icecrasher321 Feb 12, 2026
508772c
make it autoselect personal secret when create secret is clicked
icecrasher321 Feb 12, 2026
aefa281
improve collaborative UX
icecrasher321 Feb 12, 2026
319768c
remove add member ui for workspace secrets
icecrasher321 Feb 12, 2026
622023d
bulk entry of .env
icecrasher321 Feb 13, 2026
5e19226
promote to workspace secret
icecrasher321 Feb 13, 2026
8ed8a5a
more ux improvmeent
icecrasher321 Feb 13, 2026
bdd1483
share with workspace for oauth
icecrasher321 Feb 13, 2026
17710b3
remove new badge
icecrasher321 Feb 13, 2026
77bb048
share button
icecrasher321 Feb 13, 2026
dcf40be
copilot + oauth name comflict
icecrasher321 Feb 13, 2026
fa32b9e
reconnect option to connect diff account
icecrasher321 Feb 13, 2026
ff13b1f
remove credential no access marker
icecrasher321 Feb 13, 2026
3ad0f62
canonical credential id entry
icecrasher321 Feb 13, 2026
084ff9c
remove migration to prep stagin migration
icecrasher321 Feb 13, 2026
7092c88
Merge remote-tracking branch 'origin/staging' into feat/mult-credenti…
icecrasher321 Feb 13, 2026
93826cb
migration readded
icecrasher321 Feb 13, 2026
d70a5d4
backfill improvements
icecrasher321 Feb 14, 2026
ea42e64
run lint
icecrasher321 Feb 14, 2026
08b908f
fix tests
icecrasher321 Feb 14, 2026
6053050
remove unused code
icecrasher321 Feb 14, 2026
cd1ccf1
autoselect provider when connecting from block
icecrasher321 Feb 14, 2026
41cdca2
address bugbot comments
icecrasher321 Feb 14, 2026
3769da8
remove some dead code
icecrasher321 Feb 14, 2026
d235d74
more permissions stuff
icecrasher321 Feb 14, 2026
140f870
remove more unused code
icecrasher321 Feb 14, 2026
9584b99
address bugbot
icecrasher321 Feb 14, 2026
d8bbd7e
add filter
icecrasher321 Feb 14, 2026
6c3f3a4
remove migration to prep migration
icecrasher321 Feb 18, 2026
80282c3
Merge remote-tracking branch 'origin/staging' into feat/mult-credenti…
icecrasher321 Feb 18, 2026
ed9c35f
fix migration
icecrasher321 Feb 18, 2026
9b20e76
fix migration issues
icecrasher321 Feb 18, 2026
3f6fa6b
remove migration prep merge
icecrasher321 Feb 20, 2026
c50d194
Merge remote-tracking branch 'origin/staging' into feat/mult-credenti…
icecrasher321 Feb 20, 2026
c2edb50
readd migration
icecrasher321 Feb 20, 2026
abae19c
include user tables triggers
icecrasher321 Feb 20, 2026
c53fcb8
extract shared code
icecrasher321 Feb 20, 2026
34ca49a
fix
icecrasher321 Feb 20, 2026
4f5500f
fix tx issue
icecrasher321 Feb 20, 2026
1e4d255
remove migration to prep merge
icecrasher321 Feb 23, 2026
23e24b4
Merge branch 'staging' into feat/mult-credentials-rv
icecrasher321 Feb 23, 2026
94d5268
readd migration
icecrasher321 Feb 23, 2026
cc790aa
fix agent tool input
icecrasher321 Feb 23, 2026
ef358d0
agent with tool input deletion case
icecrasher321 Feb 23, 2026
35d6e17
fix credential subblock saving
icecrasher321 Feb 23, 2026
d117400
remove dead code
icecrasher321 Feb 23, 2026
e23ef7c
fix tests
icecrasher321 Feb 23, 2026
4e1d607
address bugbot comments
icecrasher321 Feb 23, 2026
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
Prev Previous commit
Next Next commit
fix agent tool input
  • Loading branch information
icecrasher321 committed Feb 23, 2026
commit cc790aab44b611e1ecdf39419db4b7ed3629cdf6
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,7 @@ import {
getMcpToolIssue as validateMcpTool,
} from '@/lib/mcp/tool-validation'
import type { McpToolSchema } from '@/lib/mcp/types'
import {
getCanonicalScopesForProvider,
getProviderIdFromServiceId,
type OAuthProvider,
type OAuthService,
} from '@/lib/oauth'
import { getProviderIdFromServiceId, type OAuthProvider, type OAuthService } from '@/lib/oauth'
import { extractInputFieldsFromBlocks } from '@/lib/workflows/input-format'
import { useUserPermissionsContext } from '@/app/workspace/[workspaceId]/providers/workspace-permissions-provider'
import {
Expand Down Expand Up @@ -1414,16 +1409,6 @@ export const ToolInput = memo(function ToolInput({
isToolAlreadySelected,
])

const toolRequiresOAuth = (toolId: string): boolean => {
const toolParams = getToolParametersConfig(toolId)
return toolParams?.toolConfig?.oauth?.required || false
}

const getToolOAuthConfig = (toolId: string) => {
const toolParams = getToolParametersConfig(toolId)
return toolParams?.toolConfig?.oauth
}

return (
<div className='w-full space-y-[8px]'>
<Combobox
Expand Down Expand Up @@ -1537,16 +1522,11 @@ export const ToolInput = memo(function ToolInput({
? subBlocksResult!.subBlocks
: []

const requiresOAuth =
!isCustomTool && !isMcpTool && currentToolId && toolRequiresOAuth(currentToolId)
const oauthConfig =
!isCustomTool && !isMcpTool && currentToolId ? getToolOAuthConfig(currentToolId) : null

const hasOperations = !isCustomTool && !isMcpTool && hasMultipleOperations(tool.type)
const hasParams = useSubBlocks
? displaySubBlocks.length > 0
: displayParams.filter((param) => evaluateParameterCondition(param, tool)).length > 0
const hasToolBody = hasOperations || (requiresOAuth && oauthConfig) || hasParams
const hasToolBody = hasOperations || hasParams

const isExpandedForDisplay = hasToolBody
? isPreview
Expand Down Expand Up @@ -1746,39 +1726,6 @@ export const ToolInput = memo(function ToolInput({
{(() => {
const renderedElements: React.ReactNode[] = []

const showOAuth =
requiresOAuth && oauthConfig && tool.params?.authMethod !== 'bot_token'

const renderOAuthAccount = (): React.ReactNode => {
if (!showOAuth || !oauthConfig) return null
const credentialSubBlock = toolBlock?.subBlocks?.find(
(s) => s.type === 'oauth-input'
)
return (
<div key='oauth-account' className='relative min-w-0 space-y-[6px]'>
<div className='font-medium text-[13px] text-[var(--text-primary)]'>
{credentialSubBlock?.title || 'Account'}{' '}
<span className='ml-0.5'>*</span>
</div>
<div className='w-full min-w-0'>
<ToolCredentialSelector
value={tool.params?.credential || ''}
onChange={(value: string) =>
handleParamChange(toolIndex, 'credential', value)
}
provider={oauthConfig.provider as OAuthProvider}
requiredScopes={
credentialSubBlock?.requiredScopes ||
getCanonicalScopesForProvider(oauthConfig.provider)
}
serviceId={oauthConfig.provider}
disabled={disabled}
/>
</div>
</div>
)
}

const renderSubBlock = (sb: BlockSubBlockConfig): React.ReactNode => {
const effectiveParamId = sb.id
const canonicalId = toolCanonicalIndex?.canonicalIdBySubBlockId[sb.id]
Expand Down Expand Up @@ -1848,44 +1795,8 @@ export const ToolInput = memo(function ToolInput({
})
)

type RenderItem =
| { kind: 'subblock'; sb: BlockSubBlockConfig }
| { kind: 'oauth' }

const renderOrder: RenderItem[] = displaySubBlocks.map((sb) => ({
kind: 'subblock' as const,
sb,
}))

if (showOAuth) {
const credentialIdx = allBlockSubBlocks.findIndex(
(sb) => sb.type === 'oauth-input'
)
if (credentialIdx >= 0) {
const sbPositions = new Map(allBlockSubBlocks.map((sb, i) => [sb.id, i]))
const insertAt = renderOrder.findIndex(
(item) =>
item.kind === 'subblock' &&
(sbPositions.get(item.sb.id) ?? Number.POSITIVE_INFINITY) >
credentialIdx
)
if (insertAt === -1) {
renderOrder.push({ kind: 'oauth' })
} else {
renderOrder.splice(insertAt, 0, { kind: 'oauth' })
}
} else {
renderOrder.unshift({ kind: 'oauth' })
}
}

for (const item of renderOrder) {
if (item.kind === 'oauth') {
const el = renderOAuthAccount()
if (el) renderedElements.push(el)
} else {
renderedElements.push(renderSubBlock(item.sb))
}
for (const sb of displaySubBlocks) {
renderedElements.push(renderSubBlock(sb))
}

const uncoveredParams = displayParams.filter(
Expand Down Expand Up @@ -1924,11 +1835,6 @@ export const ToolInput = memo(function ToolInput({
)
}

{
const el = renderOAuthAccount()
if (el) renderedElements.push(el)
}

const filteredParams = displayParams.filter((param) =>
evaluateParameterCondition(param, tool)
)
Expand Down
1 change: 1 addition & 0 deletions apps/sim/executor/handlers/agent/agent-handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1004,6 +1004,7 @@ export class AgentBlockHandler implements BlockHandler {
responseFormat,
workflowId: ctx.workflowId,
workspaceId: ctx.workspaceId,
userId: ctx.userId,
stream: streaming,
messages: messages?.map(({ executionId, ...msg }) => msg),
environmentVariables: ctx.environmentVariables || {},
Expand Down
7 changes: 5 additions & 2 deletions apps/sim/tools/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,10 @@ export async function executeTool(
throw new Error(`Tool not found: ${toolId}`)
}

// If we have a credential parameter, fetch the access token
if (contextParams.oauthCredential) {
contextParams.credential = contextParams.oauthCredential
}

if (contextParams.credential) {
logger.info(
`[${requestId}] Tool ${toolId} needs access token for credential: ${contextParams.credential}`
Expand Down Expand Up @@ -330,7 +333,7 @@ export async function executeTool(
const tokenHeaders: Record<string, string> = { 'Content-Type': 'application/json' }
if (typeof window === 'undefined') {
try {
const internalToken = await generateInternalToken()
const internalToken = await generateInternalToken(userId)
tokenHeaders.Authorization = `Bearer ${internalToken}`
} catch (_e) {
// Swallow token generation errors; the request will fail and be reported upstream
Expand Down
4 changes: 3 additions & 1 deletion apps/sim/tools/params.ts
Original file line number Diff line number Diff line change
Expand Up @@ -942,8 +942,10 @@ export function getSubBlocksForToolInput(
// Infer from structural checks
if (STRUCTURAL_SUBBLOCK_IDS.has(sb.id)) {
visibility = 'hidden'
} else if (AUTH_SUBBLOCK_TYPES.has(sb.type)) {
} else if (AUTH_SUBBLOCK_TYPES.has(sb.type) && sb.canonicalParamId !== 'oauthCredential') {
visibility = 'hidden'
} else if (sb.canonicalParamId === 'oauthCredential') {
visibility = 'user-only'
} else if (
sb.password &&
(sb.id === 'botToken' || sb.id === 'accessToken' || sb.id === 'apiKey')
Expand Down