Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
138 commits
Select commit Hold shift + click to select a range
0b9019d
v0.6.23: MCP fixes, remove local state in favor of server state, moth…
waleedlatif1 Apr 4, 2026
a54dcbe
v0.6.24: copilot feedback wiring, captcha fixes
waleedlatif1 Apr 4, 2026
28af223
v0.6.25: cloudwatch, cloudformation, live kb sync, linear fixes, post…
waleedlatif1 Apr 5, 2026
d889f32
v0.6.26: ui improvements, multiple response blocks, docx previews, ol…
waleedlatif1 Apr 5, 2026
316bc8c
v0.6.27: new triggers, mothership improvements, files archive, queuei…
waleedlatif1 Apr 7, 2026
3f508e4
v0.6.28: new docs, delete confirmation standardization, dagster integ…
waleedlatif1 Apr 7, 2026
d6ec115
v0.6.29: login improvements, posthog telemetry (#4026)
TheodoreSpeaks Apr 7, 2026
d7da35b
v0.6.30: slack trigger enhancements, connectors performance improveme…
waleedlatif1 Apr 8, 2026
cf233bb
v0.6.31: elevenlabs voice, trigger.dev fixes, cloud whitelabeling for…
waleedlatif1 Apr 8, 2026
f8f3758
v0.6.32: BYOK fixes, ui improvements, cloudwatch tools, jsm tools ext…
waleedlatif1 Apr 9, 2026
3c8bb40
v0.6.33: polling improvements, jsm forms tools, credentials reactquer…
waleedlatif1 Apr 9, 2026
d33acf4
v0.6.34: trigger.dev fixes, CI speedup, atlassian error extractor
waleedlatif1 Apr 9, 2026
4f40c4c
v0.6.35: additional jira fields, HITL docs, logs cleanup efficiency
waleedlatif1 Apr 10, 2026
cbfab1c
v0.6.36: new chunkers, sockets state machine, google sheets/drive/cal…
waleedlatif1 Apr 11, 2026
4309d06
v0.6.37: audit logs page, isolated-vm worker rotation, permission gro…
waleedlatif1 Apr 12, 2026
8b57476
v0.6.38: models page
waleedlatif1 Apr 12, 2026
e3d0e74
v0.6.39: billing fixes, tools audit, landing fix
waleedlatif1 Apr 13, 2026
0ac0539
v0.6.40: mothership tool loop, new skills, agiloft, STS, IAM integrat…
waleedlatif1 Apr 14, 2026
3838b6e
v0.6.41: webhooks fix, workers removal
waleedlatif1 Apr 14, 2026
fc07922
v0.6.42: mothership nested file reads, search modal improvements
waleedlatif1 Apr 14, 2026
3a1b1a8
v0.6.43: mothership billing idempotency, env var resolution fixes
waleedlatif1 Apr 14, 2026
46ffc49
v0.6.44: streamdown, mothership intelligence, excel extension
waleedlatif1 Apr 15, 2026
010435c
v0.6.45: superagent, csp, brightdata integration, gemini response for…
Sg312 Apr 15, 2026
c0bc62c
Merge pull request #4190 from simstudioai/staging
icecrasher321 Apr 16, 2026
387cc97
v0.6.46: mothership queueing, web vitals
waleedlatif1 Apr 16, 2026
2dbc7fd
v0.6.47: files focusing, documentation, opus 4.7
waleedlatif1 Apr 16, 2026
8a50f18
v0.6.48: import csv into tables, subflow fixes, CSP updates
waleedlatif1 Apr 16, 2026
dcf3302
v0.6.49: deploy sockets event, resolver, logs improvements, monday.co…
waleedlatif1 Apr 17, 2026
bc09865
v0.6.50: ppt/doc/pdf worker isolation, docs, chat, sidebar improvements
icecrasher321 Apr 18, 2026
5f56e46
v0.6.51: tables improvements, billing fixes, 404 pages, code hygiene
waleedlatif1 Apr 20, 2026
ca3bbf1
v0.6.52: data retention, docs updates, slack manifest generator, secu…
waleedlatif1 Apr 22, 2026
bbf400f
v0.6.53: permissions groups migration, docs updates
waleedlatif1 Apr 22, 2026
7c619e7
Merge pull request #4261 from simstudioai/staging
icecrasher321 Apr 22, 2026
64cfda5
v0.6.54: mothership tracing, db pool size increase
icecrasher321 Apr 22, 2026
7ca736a
v0.6.55: standardize monorepo conventions, api key hash, thinking tex…
waleedlatif1 Apr 23, 2026
6066fc1
v0.6.56: data retention improvements, tables column double click resi…
waleedlatif1 Apr 24, 2026
3422f64
Merge pull request #4285 from simstudioai/staging
waleedlatif1 Apr 24, 2026
595c4c3
Merge pull request #4293 from simstudioai/staging
TheodoreSpeaks Apr 24, 2026
d6c1bc2
v0.6.58: queue abort state machine improvement, contributing guide
icecrasher321 Apr 25, 2026
58a3ae2
v0.6.59: gpt 5.5, security hardening, parallel subagents rendering
icecrasher321 Apr 27, 2026
489f2d3
v0.6.60: copilot security improvements, slack canvas ops, retention j…
icecrasher321 Apr 27, 2026
6aa3fe3
v0.6.61: SAP integration, live URLs for browser use, 5xx error catego…
icecrasher321 Apr 29, 2026
ecbf5e5
Merge pull request #4342 from simstudioai/staging
TheodoreSpeaks Apr 29, 2026
2aaf2b7
v0.6.62: firecrawl parse, new gmail tools, trace improvements, tool f…
waleedlatif1 May 2, 2026
d445b9c
v0.6.63: knowledgebase UI, folder search in mothership
waleedlatif1 May 2, 2026
4bc6a17
v0.6.64: table limits env vars, workspace files improvements, integra…
waleedlatif1 May 3, 2026
5be12f8
v0.6.65: memory fix, image uploads in files
waleedlatif1 May 3, 2026
4253e57
v0.6.66: child trace spans, reranker controls, attachment previews, l…
waleedlatif1 May 5, 2026
8d6b615
v0.6.67: VFS upload fix, posthog/copilot correlation, exa date filter…
TheodoreSpeaks May 5, 2026
efcd51a
v0.6.68: atlassian service accounts, 30 day wait block, markdown rend…
waleedlatif1 May 6, 2026
8d934f3
v0.6.69: security hardening, nextjs upgrade, SAP Concur, Emailbison i…
waleedlatif1 May 7, 2026
5ea80a8
v0.6.70: legacy workflow sanitization
icecrasher321 May 7, 2026
3cc581e
v0.6.71: build error fix
icecrasher321 May 7, 2026
273e608
Merge pull request #4496 from simstudioai/staging
TheodoreSpeaks May 7, 2026
07b8f1b
v0.6.72: tables improvements, search and replace, logs with files, im…
waleedlatif1 May 9, 2026
dcaf3e9
v0.6.73: zustand v5 migration fix
icecrasher321 May 9, 2026
6aeb981
v0.6.74: security hardening, workers recycling, next-mdx-remote and o…
waleedlatif1 May 12, 2026
3e9849b
v0.6.75: scheduler claim-budget drain, helm chart hardening, mothersh…
TheodoreSpeaks May 12, 2026
64d855a
v0.6.76: helm updates, media centering, lazy loading, security hardening
waleedlatif1 May 13, 2026
ab156b5
v0.6.77: mothership improvements, trigger.dev telemetry
icecrasher321 May 14, 2026
c09a2c9
v0.6.78: file block get
Sg312 May 14, 2026
6a5eebc
v0.6.79: rate limits, tables checkboxes, drizzle config changes, bill…
waleedlatif1 May 14, 2026
4efe999
v0.6.80: security hardening, nextjs minor version bump, cloudwatch to…
waleedlatif1 May 15, 2026
f69a9a0
v0.6.81: files in agent block, file block update, mermaid version upd…
waleedlatif1 May 16, 2026
db7f1c1
v0.6.82: fix duplicate migration
Sg312 May 16, 2026
dbe8e51
v0.6.83: redis TLS SNI override for IP-based REDIS_URL, zod schema fixes
TheodoreSpeaks May 17, 2026
11bcb8f
v0.6.84: redis pub/sub SNI override, security hardening, copilot read…
TheodoreSpeaks May 17, 2026
d14af04
v0.6.85: mothership stream, resource column spacing, prospeo, findyma…
waleedlatif1 May 19, 2026
e6b3cce
v0.6.86: gemini 3.5 flash, wiza integration, CORS cleanup, railway an…
waleedlatif1 May 20, 2026
97a609a
v0.6.86: CORS updates, OAuth MCP, navigation pinning dynamic pages, g…
waleedlatif1 May 21, 2026
fde70e2
v0.6.87: performance improvements
icecrasher321 May 21, 2026
e9ee351
v0.6.88: mutex lock on oauth refresh, files export fix, hubspot trigg…
waleedlatif1 May 22, 2026
b5b2d83
v0.6.89: connectors ui, perf improvements, mcp hardening, og image
waleedlatif1 May 23, 2026
f6c9998
v0.6.90: resource breadcrumb flash fix, dedupe external URL fetches, …
icecrasher321 May 23, 2026
e532e0a
v0.6.91: file zoom, Zoom KB connector, error classifications, LiteLLM…
waleedlatif1 May 26, 2026
fd19470
v0.6.92: enrichment table column type, table run fixes, scheduled jit…
TheodoreSpeaks May 27, 2026
856182b
v0.6.93: schedules/mcp performance improvements, integration bugfixes
icecrasher321 May 28, 2026
6bf9e96
v0.6.94: 4.8 opus, better auth upgrade, zoominfo integration, copilot…
waleedlatif1 May 29, 2026
503432c
v0.6.95: data enrichment block, nullable workflow description fix
TheodoreSpeaks May 29, 2026
a8dcdd5
v0.6.96: pinned table columns, sequence number in copilot messages, t…
waleedlatif1 May 30, 2026
2f1f633
v0.6.97: migration fix for copilot_messages
icecrasher321 May 30, 2026
e32699d
v0.6.98: redundant index, security hardening, new copilot messages ta…
waleedlatif1 May 31, 2026
12ada0c
v0.6.99: tables filter operators, copilot chat persistence consolidat…
waleedlatif1 Jun 2, 2026
e8f09ae
v0.6.100: auth, mothership, scopes improvements, new apify tools
icecrasher321 Jun 2, 2026
3ba8668
v0.6.101: 11 new knowledgebase connectors, slack scopes update, login…
waleedlatif1 Jun 3, 2026
1192e20
v0.6.102: support S3-compatible in object storage, GitLab code knowle…
waleedlatif1 Jun 3, 2026
1ce8e92
v0.6.103: readme updates, tables lifecycle improvements, new connecto…
waleedlatif1 Jun 6, 2026
0c2df1e
v0.7.0: vibes improvement, new UI, new tools, chat-first, mothership …
waleedlatif1 Jun 10, 2026
7ffc495
v0.7.1: chat voice mode model update, sim trigger, codepipeline integ…
waleedlatif1 Jun 10, 2026
d4722f9
v0.7.2: logs export security, code hygiene, mship cost attribution
icecrasher321 Jun 10, 2026
f4d22ff
v0.7.3: jira oauth scope fix, read-replica client, table wire data fi…
TheodoreSpeaks Jun 11, 2026
a48b4a1
v0.7.4: round-robin byok support, table block fix, db read replica ro…
waleedlatif1 Jun 12, 2026
79d98b3
v0.7.5: deployments API and block, vanta integration, performance imp…
waleedlatif1 Jun 13, 2026
e6587ca
v0.7.6: calendar scheduled tasks, new hubspot tools, virtualized chat…
waleedlatif1 Jun 15, 2026
8c3706e
v0.7.7: square, context.dev integrations, scheduled tasks styling cha…
waleedlatif1 Jun 15, 2026
59d9496
v0.7.8: security hardening, code hygiene, MSFT oauth provider, new at…
waleedlatif1 Jun 16, 2026
56a88a2
v0.7.9: agent file attachments, chat autoscroll, knowledge base uploa…
icecrasher321 Jun 16, 2026
db47da5
v0.7.10: models sorting, compress/decompress file block tools, new en…
icecrasher321 Jun 18, 2026
8df34a3
v0.7.11: parallel subagents, new tools, rich markdown editor, governa…
waleedlatif1 Jun 21, 2026
aaca750
v0.7.12: mcp servers ui/ux fixes, nuqs for query param management
icecrasher321 Jun 22, 2026
ad0b867
v0.7.13: pii redaction, react query frontend refactor, pi coding agen…
TheodoreSpeaks Jun 24, 2026
11168f9
v0.7.14: perf improvements, code hygiene, GitLab private host support
waleedlatif1 Jun 25, 2026
613e8ea
v0.7.15: academy, perf improvements, db attribution, kb tags filter f…
waleedlatif1 Jun 27, 2026
38c088a
v0.7.16: security hardening, db o11y and profiling, settings UI
waleedlatif1 Jun 28, 2026
0371856
v0.7.17: emcn and workflow renderer isolated package, popular blocks …
waleedlatif1 Jun 30, 2026
fabf696
v0.7.18: landing, tools depth, media embeds in md editor, sonnet 5
waleedlatif1 Jul 1, 2026
6e426f8
v0.7.19: newsletter, contact, careers
waleedlatif1 Jul 1, 2026
62ef96f
v0.7.20: perf, ui improvements, fable 5, tables row size bump, blogs
waleedlatif1 Jul 2, 2026
4fcfe76
v0.7.21: tools audits and extensions, appsheet integration, hitl fix
waleedlatif1 Jul 2, 2026
8afc4f1
v0.7.22: competitor pages, seo fixes, billing usage table
waleedlatif1 Jul 4, 2026
616a71d
v0.7.23: mobile comparison table, security hardening, subflow & strea…
waleedlatif1 Jul 5, 2026
62d3140
v0.7.24: frontend perf improvements, md editor fixes, mailer fix, too…
waleedlatif1 Jul 7, 2026
21ee602
v0.7.25: new tools, gmail send fixes, email lifecycle adjustments
waleedlatif1 Jul 7, 2026
9d44d42
v0.7.26: API block default headers fix, tables perf and correctness, …
waleedlatif1 Jul 8, 2026
067d3b0
v0.7.27: document tags improvements, grok 4.5, forking, custom blocks…
waleedlatif1 Jul 9, 2026
e2fecc8
v0.7.28: rich markdown editor improvements, autosave in files, helm i…
waleedlatif1 Jul 10, 2026
6c3d11b
v0.7.29: GLM, ui and ux improvements, tables improvements, enterprise…
waleedlatif1 Jul 11, 2026
207785c
v0.7.30: md editor improvements, og image updates, spacexai hosted ke…
waleedlatif1 Jul 12, 2026
e01bfb1
v0.7.31: sidebar shortcut, env var expansion in lifecycle triggers, a…
waleedlatif1 Jul 12, 2026
dc81795
v0.7.32: concurrency control, seo/geo, new lib, buffer & flint integr…
waleedlatif1 Jul 13, 2026
377f963
v0.7.33: workflow/custom block fix, community pages improvements, cha…
waleedlatif1 Jul 14, 2026
a403d05
v0.7.34: billing page fixes, chat rendering improvements
waleedlatif1 Jul 14, 2026
91b29b3
v0.7.35: sidebar styling, custom blocks reserved names fix, client en…
icecrasher321 Jul 14, 2026
50364ed
Merge pull request #5677 from simstudioai/staging
TheodoreSpeaks Jul 14, 2026
874c998
v0.7.36: mothership secrets resolution, SEO, service accounts for var…
waleedlatif1 Jul 15, 2026
9d23e25
v0.7.37: impersonation fixes, instagram/tiktok, landing improvements,…
icecrasher321 Jul 15, 2026
28b56d7
v0.7.38: mothership improvements, clickup, rocketlane integrations, g…
waleedlatif1 Jul 17, 2026
4ddad74
v0.7.39: mcp oauth hardening, chat perf improvements
waleedlatif1 Jul 18, 2026
d985f12
feat(managed-agent): Claude Platform Managed Agents workflow blocks
rdematos Jul 20, 2026
45278a5
fix(managed-agent): address MR feedback (decrypt escape, cancel, requ…
rdematos Jul 20, 2026
e51d388
fix(managed-agent): proxy routes no longer 500 on decrypt failure
rdematos Jul 20, 2026
fd2fe27
feat(managed-agent): require vault-authorization ack when a vault is …
rdematos Jul 20, 2026
bd7dbda
feat(managed-agent): promote the vault disclaimer to the switch label
rdematos Jul 20, 2026
3f6be08
feat(managed-agent): name Anthropic sessions after the origin workflo…
rdematos Jul 20, 2026
f42a13a
fix(managed-agent): address 3 medium-severity review comments
rdematos Jul 20, 2026
fa2cc10
fix(managed-agent): authenticate defaults API + wire up key rotation UI
rdematos Jul 20, 2026
872953a
fix(managed-agent): async table seed no longer clobbers in-flight edits
rdematos Jul 20, 2026
8e9f8a1
refactor(managed-agent): remove self-hosted default-row pre-seeding
rdematos Jul 20, 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
2 changes: 2 additions & 0 deletions apps/sim/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,8 @@ API_ENCRYPTION_KEY=your_api_encryption_key # Use `openssl rand -hex 32` to gener
# LITELLM_API_KEY= # Optional bearer token if your LiteLLM proxy requires auth
# FIREWORKS_API_KEY= # Optional Fireworks AI API key for model listing
# NEXT_PUBLIC_BEDROCK_DEFAULT_CREDENTIALS=true # Set when using AWS default credential chain (IAM roles, ECS task roles, IRSA). Hides credential fields in Agent block UI.
# MANAGED_AGENT_SELF_HOSTED_DEFAULTS='{"SOURCE_TYPE":"git","SOURCE_REF":"main"}' # Server-only JSON object of default session-metadata rows seeded into fresh Claude Managed Agents (self-hosted) blocks. Deployment-specific; keys map to whatever env vars your self-hosted agent sandbox reads. Absent = empty table. Values are served via GET /api/managed-agent-defaults and never inlined into the client bundle — safe to include values that should not leak to the browser.
# NEXT_PUBLIC_MANAGED_AGENT_SELF_HOSTED_MEMORY_ENABLED=true # Reveal Memory Store + Memory Access fields on the Claude Managed Agents (self-hosted) block. Off by default: Claude self-hosted environments do not currently support the memory-store resource attach on the session API. Enable only if your self-hosted agent sandbox implements memory attach on its side.
# AZURE_OPENAI_ENDPOINT= # Azure OpenAI endpoint (hides field in UI when set alongside NEXT_PUBLIC_AZURE_CONFIGURED)
# AZURE_OPENAI_API_KEY= # Azure OpenAI API key
# AZURE_OPENAI_API_VERSION= # Azure OpenAI API version
Expand Down
89 changes: 89 additions & 0 deletions apps/sim/app/api/managed-agent-connections/[id]/agents/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import {
type ManagedAgentAgent,
managedAgentProxyParamsSchema,
managedAgentProxyQuerySchema,
} from '@/lib/api/contracts'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
import { getDecryptedApiKey } from '@/lib/managed-agents/connections'
import {
type AnthropicListPage,
apiKeyFailureResponse,
ManagedAgentProxyError,
proxyManagedAgentsGet,
} from '@/lib/managed-agents/proxy'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'

const logger = createLogger('ManagedAgentAgentsAPI')

interface AnthropicAgent {
id: string
name?: string
description?: string
latest_version?: number | string
version?: number | string
}

interface RouteContext {
params: Promise<{ id: string }>
}

export const GET = withRouteHandler(async (request: NextRequest, context: RouteContext) => {
const requestId = generateRequestId()
try {
const authResult = await checkSessionOrInternalAuth(request, { requireWorkflowId: false })
if (!authResult.success || !authResult.userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
const userId = authResult.userId

const rawParams = await context.params
const paramsValidation = managedAgentProxyParamsSchema.safeParse(rawParams)
const queryValidation = managedAgentProxyQuerySchema.safeParse(
Object.fromEntries(request.nextUrl.searchParams.entries())
)
if (!paramsValidation.success || !queryValidation.success) {
return NextResponse.json({ error: 'Invalid request data' }, { status: 400 })
}
const { id } = paramsValidation.data
const { workspaceId } = queryValidation.data

const userPermission = await getUserEntityPermissions(userId, 'workspace', workspaceId)
if (!userPermission) {
return NextResponse.json({ error: 'Access denied' }, { status: 403 })
}

const keyResult = await getDecryptedApiKey({ id, workspaceId })
if (!keyResult.ok) return apiKeyFailureResponse(keyResult)
const apiKey = keyResult.apiKey

try {
const body = await proxyManagedAgentsGet<AnthropicListPage<AnthropicAgent>>(
apiKey,
'/v1/agents?limit=100'
)
const data: ManagedAgentAgent[] = (body.data ?? []).map((row) => ({
id: row.id,
name: row.name ?? null,
description: row.description ?? null,
version: row.latest_version ?? row.version ?? null,
}))
return NextResponse.json({ data })
} catch (error) {
if (error instanceof ManagedAgentProxyError) {
return NextResponse.json({ error: error.message }, { status: 502 })
}
throw error
}
} catch (error) {
logger.error(`[${requestId}] Failed to list agents`, error)
return NextResponse.json(
{ error: getErrorMessage(error, 'Failed to list agents') },
{ status: 500 }
)
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import {
type ManagedAgentEnvironment,
managedAgentEnvironmentDetailParamsSchema,
managedAgentProxyQuerySchema,
} from '@/lib/api/contracts'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
import { getDecryptedApiKey } from '@/lib/managed-agents/connections'
import {
apiKeyFailureResponse,
ManagedAgentProxyError,
proxyManagedAgentsGet,
} from '@/lib/managed-agents/proxy'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'

const logger = createLogger('ManagedAgentEnvironmentAPI')

interface AnthropicEnvironment {
id: string
name?: string
description?: string
scope?: 'organization' | 'account' | null
config?: { type?: 'cloud' | 'self_hosted' }
}

interface RouteContext {
params: Promise<{ id: string; envId: string }>
}

/**
* GET /api/managed-agent-connections/[id]/environments/[envId] — used by
* the workflow-block tool at run time to resolve `envType` before
* building the session-create payload.
*/
export const GET = withRouteHandler(async (request: NextRequest, context: RouteContext) => {
const requestId = generateRequestId()
try {
const authResult = await checkSessionOrInternalAuth(request, { requireWorkflowId: false })
if (!authResult.success || !authResult.userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
const userId = authResult.userId

const rawParams = await context.params
const paramsValidation = managedAgentEnvironmentDetailParamsSchema.safeParse(rawParams)
const queryValidation = managedAgentProxyQuerySchema.safeParse(
Object.fromEntries(request.nextUrl.searchParams.entries())
)
if (!paramsValidation.success || !queryValidation.success) {
return NextResponse.json({ error: 'Invalid request data' }, { status: 400 })
}
const { id, envId } = paramsValidation.data
const { workspaceId } = queryValidation.data

const userPermission = await getUserEntityPermissions(userId, 'workspace', workspaceId)
if (!userPermission) {
return NextResponse.json({ error: 'Access denied' }, { status: 403 })
}

const keyResult = await getDecryptedApiKey({ id, workspaceId })
if (!keyResult.ok) return apiKeyFailureResponse(keyResult)
const apiKey = keyResult.apiKey

try {
const body = await proxyManagedAgentsGet<AnthropicEnvironment>(
apiKey,
`/v1/environments/${encodeURIComponent(envId)}`
)
const envType = body.config?.type
if (envType !== 'cloud' && envType !== 'self_hosted') {
return NextResponse.json(
{ error: 'Environment returned an unrecognised config.type' },
{ status: 502 }
)
}
const data: ManagedAgentEnvironment = {
id: body.id,
name: body.name ?? null,
description: body.description ?? null,
envType,
scope: body.scope ?? null,
}
return NextResponse.json({ data })
} catch (error) {
if (error instanceof ManagedAgentProxyError) {
const status = error.status === 404 ? 404 : 502
return NextResponse.json({ error: error.message }, { status })
}
throw error
}
} catch (error) {
logger.error(`[${requestId}] Failed to fetch environment`, error)
return NextResponse.json(
{ error: getErrorMessage(error, 'Failed to fetch environment') },
{ status: 500 }
)
}
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { createLogger } from '@sim/logger'
import { getErrorMessage } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import {
type ManagedAgentEnvironment,
managedAgentProxyParamsSchema,
managedAgentProxyQuerySchema,
} from '@/lib/api/contracts'
import { checkSessionOrInternalAuth } from '@/lib/auth/hybrid'
import { generateRequestId } from '@/lib/core/utils/request'
import { withRouteHandler } from '@/lib/core/utils/with-route-handler'
import { getDecryptedApiKey } from '@/lib/managed-agents/connections'
import {
type AnthropicListPage,
apiKeyFailureResponse,
ManagedAgentProxyError,
proxyManagedAgentsGet,
} from '@/lib/managed-agents/proxy'
import { getUserEntityPermissions } from '@/lib/workspaces/permissions/utils'

const logger = createLogger('ManagedAgentEnvironmentsAPI')

interface AnthropicEnvironment {
id: string
name?: string
description?: string
scope?: 'organization' | 'account' | null
config?: { type?: 'cloud' | 'self_hosted' }
}

interface RouteContext {
params: Promise<{ id: string }>
}

export const GET = withRouteHandler(async (request: NextRequest, context: RouteContext) => {
const requestId = generateRequestId()
try {
const authResult = await checkSessionOrInternalAuth(request, { requireWorkflowId: false })
if (!authResult.success || !authResult.userId) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
const userId = authResult.userId

const rawParams = await context.params
const paramsValidation = managedAgentProxyParamsSchema.safeParse(rawParams)
const queryValidation = managedAgentProxyQuerySchema.safeParse(
Object.fromEntries(request.nextUrl.searchParams.entries())
)
if (!paramsValidation.success || !queryValidation.success) {
return NextResponse.json({ error: 'Invalid request data' }, { status: 400 })
}
const { id } = paramsValidation.data
const { workspaceId } = queryValidation.data

const userPermission = await getUserEntityPermissions(userId, 'workspace', workspaceId)
if (!userPermission) {
return NextResponse.json({ error: 'Access denied' }, { status: 403 })
}

const keyResult = await getDecryptedApiKey({ id, workspaceId })
if (!keyResult.ok) return apiKeyFailureResponse(keyResult)
const apiKey = keyResult.apiKey

try {
const body = await proxyManagedAgentsGet<AnthropicListPage<AnthropicEnvironment>>(
apiKey,
'/v1/environments?limit=100'
)
const data: ManagedAgentEnvironment[] = (body.data ?? [])
.map((row) => {
const envType = row.config?.type
if (envType !== 'cloud' && envType !== 'self_hosted') return null
return {
id: row.id,
name: row.name ?? null,
description: row.description ?? null,
envType,
scope: row.scope ?? null,
}
})
.filter((row): row is ManagedAgentEnvironment => row !== null)
return NextResponse.json({ data })
} catch (error) {
if (error instanceof ManagedAgentProxyError) {
return NextResponse.json({ error: error.message }, { status: 502 })
}
throw error
}
} catch (error) {
logger.error(`[${requestId}] Failed to list environments`, error)
return NextResponse.json(
{ error: getErrorMessage(error, 'Failed to list environments') },
{ status: 500 }
)
}
})
Loading