Skip to content
336 changes: 324 additions & 12 deletions apps/sim/blocks/blocks/hex.ts

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion apps/sim/tools/hex/cancel_run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const cancelRunTool: ToolConfig<HexCancelRunParams, HexCancelRunResponse>

request: {
url: (params) =>
`https://app.hex.tech/api/v1/projects/${params.projectId}/runs/${params.runId}`,
`https://app.hex.tech/api/v1/projects/${params.projectId.trim()}/runs/${params.runId.trim()}`,
method: 'DELETE',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
Expand Down
78 changes: 78 additions & 0 deletions apps/sim/tools/hex/create_group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import type { HexCreateGroupParams, HexCreateGroupResponse } from '@/tools/hex/types'
import type { ToolConfig } from '@/tools/types'

export const createGroupTool: ToolConfig<HexCreateGroupParams, HexCreateGroupResponse> = {
id: 'hex_create_group',
name: 'Hex Create Group',
description: 'Create a new group in the Hex workspace, optionally with initial members.',
version: '1.0.0',

params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Hex API token (Personal or Workspace)',
},
name: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'Name for the new group',
},
memberUserIds: {
type: 'json',
required: false,
visibility: 'user-or-llm',
description:
'JSON array of user UUIDs to add as initial group members (e.g., ["uuid1", "uuid2"])',
},
},

request: {
url: 'https://app.hex.tech/api/v1/groups',
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
body: (params) => {
const body: Record<string, unknown> = { name: params.name }
if (params.memberUserIds) {
let userIds: unknown
try {
userIds =
typeof params.memberUserIds === 'string'
? JSON.parse(params.memberUserIds)
: params.memberUserIds
} catch {
throw new Error('memberUserIds must be a valid JSON array of user UUID strings')
}
if (!Array.isArray(userIds) || !userIds.every((id) => typeof id === 'string')) {
throw new Error('memberUserIds must be a valid JSON array of user UUID strings')
}
body.members = { users: userIds.map((id: string) => ({ id: id.trim() })) }
Comment thread
waleedlatif1 marked this conversation as resolved.
}
return body
},
},

transformResponse: async (response: Response) => {
const data = await response.json()

return {
success: true,
output: {
id: data.id ?? null,
name: data.name ?? null,
createdAt: data.createdAt ?? null,
},
}
},
Comment thread
waleedlatif1 marked this conversation as resolved.

outputs: {
id: { type: 'string', description: 'Newly created group UUID' },
name: { type: 'string', description: 'Group name' },
createdAt: { type: 'string', description: 'Creation timestamp' },
},
}
60 changes: 60 additions & 0 deletions apps/sim/tools/hex/deactivate_user.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import type { HexDeactivateUserParams, HexDeactivateUserResponse } from '@/tools/hex/types'
import type { ToolConfig } from '@/tools/types'

export const deactivateUserTool: ToolConfig<HexDeactivateUserParams, HexDeactivateUserResponse> = {
id: 'hex_deactivate_user',
name: 'Hex Deactivate User',
description: 'Deactivate a user in the Hex workspace.',
version: '1.0.0',

params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Hex API token (Personal or Workspace)',
},
userId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The UUID of the user to deactivate',
},
},

request: {
url: (params) => `https://app.hex.tech/api/v1/users/${params.userId.trim()}/deactivate`,
method: 'POST',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},

transformResponse: async (response: Response, params) => {
if (response.status === 204 || response.ok) {
return {
success: true,
output: {
success: true,
userId: params?.userId ?? '',
},
}
}

const data = await response.json().catch(() => ({}))
return {
success: false,
output: {
success: false,
userId: params?.userId ?? '',
},
error: (data as Record<string, string>).message ?? 'Failed to deactivate user',
}
},

outputs: {
success: { type: 'boolean', description: 'Whether the user was successfully deactivated' },
userId: { type: 'string', description: 'User UUID that was deactivated' },
},
}
60 changes: 60 additions & 0 deletions apps/sim/tools/hex/delete_group.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import type { HexDeleteGroupParams, HexDeleteGroupResponse } from '@/tools/hex/types'
import type { ToolConfig } from '@/tools/types'

export const deleteGroupTool: ToolConfig<HexDeleteGroupParams, HexDeleteGroupResponse> = {
id: 'hex_delete_group',
name: 'Hex Delete Group',
description: 'Delete a group from the Hex workspace.',
version: '1.0.0',

params: {
apiKey: {
type: 'string',
required: true,
visibility: 'user-only',
description: 'Hex API token (Personal or Workspace)',
},
groupId: {
type: 'string',
required: true,
visibility: 'user-or-llm',
description: 'The UUID of the group to delete',
},
},

request: {
url: (params) => `https://app.hex.tech/api/v1/groups/${params.groupId.trim()}`,
method: 'DELETE',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
'Content-Type': 'application/json',
}),
},

transformResponse: async (response: Response, params) => {
if (response.status === 204 || response.ok) {
return {
success: true,
output: {
success: true,
groupId: params?.groupId ?? '',
},
}
}

const data = await response.json().catch(() => ({}))
return {
success: false,
output: {
success: false,
groupId: params?.groupId ?? '',
},
error: (data as Record<string, string>).message ?? 'Failed to delete group',
}
},

outputs: {
success: { type: 'boolean', description: 'Whether the group was successfully deleted' },
groupId: { type: 'string', description: 'Group UUID that was deleted' },
},
}
2 changes: 1 addition & 1 deletion apps/sim/tools/hex/get_collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const getCollectionTool: ToolConfig<HexGetCollectionParams, HexGetCollect
},

request: {
url: (params) => `https://app.hex.tech/api/v1/collections/${params.collectionId}`,
url: (params) => `https://app.hex.tech/api/v1/collections/${params.collectionId.trim()}`,
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
Expand Down
3 changes: 2 additions & 1 deletion apps/sim/tools/hex/get_data_connection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export const getDataConnectionTool: ToolConfig<
},

request: {
url: (params) => `https://app.hex.tech/api/v1/data-connections/${params.dataConnectionId}`,
url: (params) =>
`https://app.hex.tech/api/v1/data-connections/${params.dataConnectionId.trim()}`,
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
Expand Down
2 changes: 1 addition & 1 deletion apps/sim/tools/hex/get_group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export const getGroupTool: ToolConfig<HexGetGroupParams, HexGetGroupResponse> =
},

request: {
url: (params) => `https://app.hex.tech/api/v1/groups/${params.groupId}`,
url: (params) => `https://app.hex.tech/api/v1/groups/${params.groupId.trim()}`,
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
Expand Down
2 changes: 1 addition & 1 deletion apps/sim/tools/hex/get_project.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export const getProjectTool: ToolConfig<HexGetProjectParams, HexGetProjectRespon
},

request: {
url: (params) => `https://app.hex.tech/api/v1/projects/${params.projectId}`,
url: (params) => `https://app.hex.tech/api/v1/projects/${params.projectId.trim()}`,
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
Expand Down
17 changes: 16 additions & 1 deletion apps/sim/tools/hex/get_project_runs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ export const getProjectRunsTool: ToolConfig<HexGetProjectRunsParams, HexGetProje
description:
'Filter by run status: PENDING, RUNNING, ERRORED, COMPLETED, KILLED, UNABLE_TO_ALLOCATE_KERNEL',
},
runTriggerFilter: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Filter by how the run was triggered: ALL, API, SCHEDULED, or APP_REFRESH',
},
},

request: {
Expand All @@ -48,8 +54,9 @@ export const getProjectRunsTool: ToolConfig<HexGetProjectRunsParams, HexGetProje
if (params.limit) searchParams.set('limit', String(params.limit))
if (params.offset) searchParams.set('offset', String(params.offset))
if (params.statusFilter) searchParams.set('statusFilter', params.statusFilter)
if (params.runTriggerFilter) searchParams.set('runTriggerFilter', params.runTriggerFilter)
const qs = searchParams.toString()
return `https://app.hex.tech/api/v1/projects/${params.projectId}/runs${qs ? `?${qs}` : ''}`
return `https://app.hex.tech/api/v1/projects/${params.projectId.trim()}/runs${qs ? `?${qs}` : ''}`
},
method: 'GET',
headers: (params) => ({
Expand Down Expand Up @@ -78,6 +85,8 @@ export const getProjectRunsTool: ToolConfig<HexGetProjectRunsParams, HexGetProje
})),
total: runs.length,
traceId: data.traceId ?? null,
nextPage: data.nextPage ?? null,
previousPage: data.previousPage ?? null,
},
}
},
Expand Down Expand Up @@ -111,5 +120,11 @@ export const getProjectRunsTool: ToolConfig<HexGetProjectRunsParams, HexGetProje
},
total: { type: 'number', description: 'Total number of runs returned' },
traceId: { type: 'string', description: 'Top-level trace ID', optional: true },
nextPage: { type: 'string', description: 'Cursor for the next page of runs', optional: true },
previousPage: {
type: 'string',
description: 'Cursor for the previous page of runs',
optional: true,
},
},
}
2 changes: 1 addition & 1 deletion apps/sim/tools/hex/get_queried_tables.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ export const getQueriedTablesTool: ToolConfig<
const searchParams = new URLSearchParams()
if (params.limit) searchParams.set('limit', String(params.limit))
const qs = searchParams.toString()
return `https://app.hex.tech/api/v1/projects/${params.projectId}/queriedTables${qs ? `?${qs}` : ''}`
return `https://app.hex.tech/api/v1/projects/${params.projectId.trim()}/queriedTables${qs ? `?${qs}` : ''}`
},
method: 'GET',
headers: (params) => ({
Expand Down
2 changes: 1 addition & 1 deletion apps/sim/tools/hex/get_run_status.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const getRunStatusTool: ToolConfig<HexGetRunStatusParams, HexGetRunStatus

request: {
url: (params) =>
`https://app.hex.tech/api/v1/projects/${params.projectId}/runs/${params.runId}`,
`https://app.hex.tech/api/v1/projects/${params.projectId.trim()}/runs/${params.runId.trim()}`,
method: 'GET',
headers: (params) => ({
Authorization: `Bearer ${params.apiKey}`,
Expand Down
10 changes: 10 additions & 0 deletions apps/sim/tools/hex/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
import { cancelRunTool } from '@/tools/hex/cancel_run'
import { createCollectionTool } from '@/tools/hex/create_collection'
import { createGroupTool } from '@/tools/hex/create_group'
import { deactivateUserTool } from '@/tools/hex/deactivate_user'
import { deleteGroupTool } from '@/tools/hex/delete_group'
import { getCollectionTool } from '@/tools/hex/get_collection'
import { getDataConnectionTool } from '@/tools/hex/get_data_connection'
import { getGroupTool } from '@/tools/hex/get_group'
Expand All @@ -13,10 +16,15 @@ import { listGroupsTool } from '@/tools/hex/list_groups'
import { listProjectsTool } from '@/tools/hex/list_projects'
import { listUsersTool } from '@/tools/hex/list_users'
import { runProjectTool } from '@/tools/hex/run_project'
import { updateCollectionTool } from '@/tools/hex/update_collection'
import { updateGroupTool } from '@/tools/hex/update_group'
import { updateProjectTool } from '@/tools/hex/update_project'

export const hexCancelRunTool = cancelRunTool
export const hexCreateCollectionTool = createCollectionTool
export const hexCreateGroupTool = createGroupTool
export const hexDeactivateUserTool = deactivateUserTool
export const hexDeleteGroupTool = deleteGroupTool
export const hexGetCollectionTool = getCollectionTool
export const hexGetDataConnectionTool = getDataConnectionTool
export const hexGetGroupTool = getGroupTool
Expand All @@ -30,4 +38,6 @@ export const hexListGroupsTool = listGroupsTool
export const hexListProjectsTool = listProjectsTool
export const hexListUsersTool = listUsersTool
export const hexRunProjectTool = runProjectTool
export const hexUpdateCollectionTool = updateCollectionTool
export const hexUpdateGroupTool = updateGroupTool
export const hexUpdateProjectTool = updateProjectTool
22 changes: 22 additions & 0 deletions apps/sim/tools/hex/list_collections.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,27 @@ export const listCollectionsTool: ToolConfig<HexListCollectionsParams, HexListCo
visibility: 'user-only',
description: 'Sort by field: NAME',
},
after: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Cursor to fetch the page of results after this value',
},
before: {
type: 'string',
required: false,
visibility: 'user-or-llm',
description: 'Cursor to fetch the page of results before this value',
},
},

request: {
url: (params) => {
const searchParams = new URLSearchParams()
if (params.limit) searchParams.set('limit', String(params.limit))
if (params.sortBy) searchParams.set('sortBy', params.sortBy)
if (params.after) searchParams.set('after', params.after)
if (params.before) searchParams.set('before', params.before)
const qs = searchParams.toString()
return `https://app.hex.tech/api/v1/collections${qs ? `?${qs}` : ''}`
},
Expand Down Expand Up @@ -63,6 +77,8 @@ export const listCollectionsTool: ToolConfig<HexListCollectionsParams, HexListCo
: null,
})),
total: collections.length,
after: data.pagination?.after ?? null,
before: data.pagination?.before ?? null,
},
}
},
Expand Down Expand Up @@ -90,5 +106,11 @@ export const listCollectionsTool: ToolConfig<HexListCollectionsParams, HexListCo
},
},
total: { type: 'number', description: 'Total number of collections returned' },
after: { type: 'string', description: 'Cursor for the next page of results', optional: true },
before: {
type: 'string',
description: 'Cursor for the previous page of results',
optional: true,
},
},
}
Loading
Loading