diff --git a/apps/docs/content/docs/en/tools/agiloft.mdx b/apps/docs/content/docs/en/tools/agiloft.mdx
index 235300ea259..5032b74663d 100644
--- a/apps/docs/content/docs/en/tools/agiloft.mdx
+++ b/apps/docs/content/docs/en/tools/agiloft.mdx
@@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
{/* MANUAL-CONTENT-START:intro */}
@@ -137,6 +137,28 @@ Delete a record from an Agiloft table.
| `id` | string | ID of the deleted record |
| `deleted` | boolean | Whether the record was successfully deleted |
+### `agiloft_get_choice_line_id`
+
+Resolve the internal numeric ID of a choice-list value, for use in EWSelect WHERE clauses against choice fields.
+
+#### Input
+
+| Parameter | Type | Required | Description |
+| --------- | ---- | -------- | ----------- |
+| `instanceUrl` | string | Yes | Agiloft instance URL \(e.g., https://mycompany.agiloft.com\) |
+| `knowledgeBase` | string | Yes | Knowledge base name |
+| `login` | string | Yes | Agiloft username |
+| `password` | string | Yes | Agiloft password |
+| `table` | string | Yes | Table name \(e.g., "case", "contracts"\) |
+| `fieldName` | string | Yes | Choice field name \(e.g., "priority", "status"\) |
+| `value` | string | Yes | Choice display value to resolve \(e.g., "High", "Active"\) |
+
+#### Output
+
+| Parameter | Type | Description |
+| --------- | ---- | ----------- |
+| `choiceLineId` | number | Internal numeric line ID of the choice value |
+
### `agiloft_lock_record`
Lock, unlock, or check the lock status of an Agiloft record.
@@ -254,7 +276,7 @@ List saved searches defined for an Agiloft table.
| `searches` | array | List of saved searches for the table |
| ↳ `name` | string | Saved search name |
| ↳ `label` | string | Saved search display label |
-| ↳ `id` | string | Saved search database identifier |
+| ↳ `id` | number | Saved search database identifier |
| ↳ `description` | string | Saved search description |
### `agiloft_search_records`
diff --git a/apps/docs/content/docs/en/tools/posthog.mdx b/apps/docs/content/docs/en/tools/posthog.mdx
index 61b50e82810..6b471ef60fb 100644
--- a/apps/docs/content/docs/en/tools/posthog.mdx
+++ b/apps/docs/content/docs/en/tools/posthog.mdx
@@ -87,7 +87,7 @@ List persons (users) in PostHog. Returns user profiles with their properties and
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
-| `personalApiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
+| `apiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
| `region` | string | No | PostHog region: us \(default\) or eu |
| `projectId` | string | Yes | PostHog Project ID \(e.g., "12345" or project UUID\) |
| `limit` | number | No | Number of persons to return \(default: 100, max: 100\) |
@@ -115,7 +115,7 @@ Get detailed information about a specific person in PostHog by their ID or UUID.
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
-| `personalApiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
+| `apiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
| `region` | string | No | PostHog region: us \(default\) or eu |
| `projectId` | string | Yes | PostHog Project ID \(e.g., "12345" or project UUID\) |
| `personId` | string | Yes | Person ID or UUID to retrieve \(e.g., "01234567-89ab-cdef-0123-456789abcdef"\) |
@@ -139,7 +139,7 @@ Delete a person from PostHog. This will remove all associated events and data. U
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
-| `personalApiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
+| `apiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
| `region` | string | No | PostHog region: us \(default\) or eu |
| `projectId` | string | Yes | PostHog Project ID \(e.g., "12345" or project UUID\) |
| `personId` | string | Yes | Person ID or UUID to delete \(e.g., "01234567-89ab-cdef-0123-456789abcdef"\) |
@@ -158,7 +158,7 @@ Execute a HogQL query in PostHog. HogQL is PostHog
| Parameter | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
-| `personalApiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
+| `apiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
| `region` | string | No | PostHog region: us \(default\) or eu |
| `projectId` | string | Yes | PostHog Project ID \(e.g., "12345" or project UUID\) |
| `query` | string | Yes | HogQL query to execute. Example: \{"kind": "HogQLQuery", "query": "SELECT event, count\(\) FROM events WHERE timestamp > now\(\) - INTERVAL 1 DAY GROUP BY event"\} |
diff --git a/apps/sim/app/(landing)/integrations/data/integrations.json b/apps/sim/app/(landing)/integrations/data/integrations.json
index 346cb98feeb..7067930cb24 100644
--- a/apps/sim/app/(landing)/integrations/data/integrations.json
+++ b/apps/sim/app/(landing)/integrations/data/integrations.json
@@ -321,7 +321,7 @@
"name": "Agiloft",
"description": "Manage records in Agiloft CLM",
"longDescription": "Integrate with Agiloft contract lifecycle management to create, read, update, delete, and search records. Supports file attachments, SQL-based selection, saved searches, and record locking across any table in your knowledge base.",
- "bgColor": "#FFFFFF",
+ "bgColor": "#001028",
"iconName": "AgiloftIcon",
"docsUrl": "https://docs.sim.ai/tools/agiloft",
"operations": [
@@ -372,9 +372,13 @@
{
"name": "Lock Record",
"description": "Lock, unlock, or check the lock status of an Agiloft record."
+ },
+ {
+ "name": "Get Choice Line ID",
+ "description": "Resolve the internal numeric ID of a choice-list value, for use in EWSelect WHERE clauses against choice fields."
}
],
- "operationCount": 12,
+ "operationCount": 13,
"triggers": [],
"triggerCount": 0,
"authType": "none",
diff --git a/apps/sim/app/api/tools/agiloft/attach/route.ts b/apps/sim/app/api/tools/agiloft/attach/route.ts
index d0ec62e0fd8..edcbdc4c0f3 100644
--- a/apps/sim/app/api/tools/agiloft/attach/route.ts
+++ b/apps/sim/app/api/tools/agiloft/attach/route.ts
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
+import { toError } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { agiloftAttachContract } from '@/lib/api/contracts/tools/agiloft'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -90,7 +91,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
const agiloftResponse = await fetch(url, {
method: 'PUT',
headers: {
- 'Content-Type': userFile.type || 'application/octet-stream',
+ 'Content-Type': 'application/octet-stream',
Authorization: `Bearer ${token}`,
},
body: new Uint8Array(fileBuffer),
@@ -136,9 +137,6 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
} catch (error) {
logger.error(`[${requestId}] Error attaching file to Agiloft:`, error)
- return NextResponse.json(
- { success: false, error: error instanceof Error ? error.message : 'Internal server error' },
- { status: 500 }
- )
+ return NextResponse.json({ success: false, error: toError(error).message }, { status: 500 })
}
})
diff --git a/apps/sim/app/api/tools/agiloft/retrieve/route.ts b/apps/sim/app/api/tools/agiloft/retrieve/route.ts
index 3f94c8bc739..64bd72daae8 100644
--- a/apps/sim/app/api/tools/agiloft/retrieve/route.ts
+++ b/apps/sim/app/api/tools/agiloft/retrieve/route.ts
@@ -1,4 +1,5 @@
import { createLogger } from '@sim/logger'
+import { toError } from '@sim/utils/errors'
import { type NextRequest, NextResponse } from 'next/server'
import { agiloftRetrieveContract } from '@/lib/api/contracts/tools/agiloft'
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -127,9 +128,6 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
} catch (error) {
logger.error(`[${requestId}] Error retrieving Agiloft attachment:`, error)
- return NextResponse.json(
- { success: false, error: error instanceof Error ? error.message : 'Internal server error' },
- { status: 500 }
- )
+ return NextResponse.json({ success: false, error: toError(error).message }, { status: 500 })
}
})
diff --git a/apps/sim/blocks/blocks/agiloft.ts b/apps/sim/blocks/blocks/agiloft.ts
index 36e571dad99..ee1791d3048 100644
--- a/apps/sim/blocks/blocks/agiloft.ts
+++ b/apps/sim/blocks/blocks/agiloft.ts
@@ -13,7 +13,7 @@ export const AgiloftBlock: BlockConfig = {
category: 'tools',
integrationType: IntegrationType.Productivity,
tags: ['automation'],
- bgColor: '#FFFFFF',
+ bgColor: '#001028',
icon: AgiloftIcon,
authMode: AuthMode.ApiKey,
@@ -35,6 +35,7 @@ export const AgiloftBlock: BlockConfig = {
{ label: 'Remove Attachment', id: 'remove_attachment' },
{ label: 'Attachment Info', id: 'attachment_info' },
{ label: 'Lock Record', id: 'lock_record' },
+ { label: 'Get Choice Line ID', id: 'get_choice_line_id' },
],
value: () => 'search_records',
},
@@ -44,7 +45,6 @@ export const AgiloftBlock: BlockConfig = {
type: 'short-input',
placeholder: 'https://mycompany.agiloft.com',
required: true,
- password: false,
},
{
id: 'knowledgeBase',
@@ -151,16 +151,36 @@ export const AgiloftBlock: BlockConfig = {
id: 'fieldName',
title: 'Field Name',
type: 'short-input',
- placeholder: 'e.g., attached_docs',
+ placeholder: 'e.g., attached_docs, priority',
condition: {
field: 'operation',
- value: ['attach_file', 'retrieve_attachment', 'remove_attachment', 'attachment_info'],
+ value: [
+ 'attach_file',
+ 'retrieve_attachment',
+ 'remove_attachment',
+ 'attachment_info',
+ 'get_choice_line_id',
+ ],
},
required: {
field: 'operation',
- value: ['attach_file', 'retrieve_attachment', 'remove_attachment', 'attachment_info'],
+ value: [
+ 'attach_file',
+ 'retrieve_attachment',
+ 'remove_attachment',
+ 'attachment_info',
+ 'get_choice_line_id',
+ ],
},
},
+ {
+ id: 'value',
+ title: 'Choice Value',
+ type: 'short-input',
+ placeholder: 'e.g., High, Active',
+ condition: { field: 'operation', value: 'get_choice_line_id' },
+ required: { field: 'operation', value: 'get_choice_line_id' },
+ },
{
id: 'uploadFile',
title: 'File',
@@ -254,6 +274,7 @@ export const AgiloftBlock: BlockConfig = {
'agiloft_attachment_info',
'agiloft_create_record',
'agiloft_delete_record',
+ 'agiloft_get_choice_line_id',
'agiloft_lock_record',
'agiloft_read_record',
'agiloft_remove_attachment',
@@ -288,7 +309,8 @@ export const AgiloftBlock: BlockConfig = {
data: { type: 'string', description: 'Record data as JSON' },
query: { type: 'string', description: 'Search query' },
where: { type: 'string', description: 'SQL WHERE clause for select' },
- fieldName: { type: 'string', description: 'Attachment field name' },
+ fieldName: { type: 'string', description: 'Attachment field name or choice field name' },
+ value: { type: 'string', description: 'Choice value to resolve to its line ID' },
attachFile: { type: 'file', description: 'File to attach' },
fileName: { type: 'string', description: 'Name for the attached file' },
position: { type: 'string', description: 'Attachment position index' },
@@ -403,5 +425,10 @@ export const AgiloftBlock: BlockConfig = {
description: 'Minutes until the lock expires',
condition: { field: 'operation', value: 'lock_record' },
},
+ choiceLineId: {
+ type: 'number',
+ description: 'Internal numeric ID of the resolved choice value',
+ condition: { field: 'operation', value: 'get_choice_line_id' },
+ },
},
}
diff --git a/apps/sim/lib/api/contracts/tools/agiloft.ts b/apps/sim/lib/api/contracts/tools/agiloft.ts
index 38b18657eb9..f8c6e1f565c 100644
--- a/apps/sim/lib/api/contracts/tools/agiloft.ts
+++ b/apps/sim/lib/api/contracts/tools/agiloft.ts
@@ -50,8 +50,8 @@ export const agiloftAttachBodySchema = z.object({
table: z.string().min(1, 'Table is required'),
recordId: z.string().min(1, 'Record ID is required'),
fieldName: z.string().min(1, 'Field name is required'),
- file: FileInputSchema.optional().nullable(),
- fileName: z.string().optional().nullable(),
+ file: FileInputSchema.optional(),
+ fileName: z.string().optional(),
})
export const agiloftRetrieveContract = defineRouteContract({
diff --git a/apps/sim/tools/agiloft/attachment_info.ts b/apps/sim/tools/agiloft/attachment_info.ts
index 38471b74e3b..07986303fe8 100644
--- a/apps/sim/tools/agiloft/attachment_info.ts
+++ b/apps/sim/tools/agiloft/attachment_info.ts
@@ -91,9 +91,13 @@ export const agiloftAttachmentInfoTool: ToolConfig<
for (let i = 0; i < result.length; i++) {
const item = result[i] as Record
attachments.push({
- position: (item.position as number) ?? i,
- name: (item.name as string) ?? (item.filename as string) ?? '',
- size: (item.size as number) ?? 0,
+ position: (item.filePosition as number) ?? (item.position as number) ?? i,
+ name:
+ (item.fileName as string) ??
+ (item.name as string) ??
+ (item.filename as string) ??
+ '',
+ size: (item.size as number) ?? (item.fileSize as number) ?? 0,
})
}
}
diff --git a/apps/sim/tools/agiloft/create_record.ts b/apps/sim/tools/agiloft/create_record.ts
index d89943f9750..f4763f55bad 100644
--- a/apps/sim/tools/agiloft/create_record.ts
+++ b/apps/sim/tools/agiloft/create_record.ts
@@ -72,7 +72,7 @@ export const agiloftCreateRecordTool: ToolConfig ({
url: buildCreateRecordUrl(base, params),
method: 'POST',
- headers: { 'Content-Type': 'application/json' },
+ headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
body,
}),
async (response) => {
diff --git a/apps/sim/tools/agiloft/delete_record.ts b/apps/sim/tools/agiloft/delete_record.ts
index 3796459dd64..42538104961 100644
--- a/apps/sim/tools/agiloft/delete_record.ts
+++ b/apps/sim/tools/agiloft/delete_record.ts
@@ -60,6 +60,7 @@ export const agiloftDeleteRecordTool: ToolConfig ({
url: buildDeleteRecordUrl(base, params),
method: 'DELETE',
+ headers: { Accept: 'application/json' },
}),
async (response) => {
if (!response.ok) {
diff --git a/apps/sim/tools/agiloft/get_choice_line_id.ts b/apps/sim/tools/agiloft/get_choice_line_id.ts
new file mode 100644
index 00000000000..11df1040565
--- /dev/null
+++ b/apps/sim/tools/agiloft/get_choice_line_id.ts
@@ -0,0 +1,130 @@
+import type {
+ AgiloftGetChoiceLineIdParams,
+ AgiloftGetChoiceLineIdResponse,
+} from '@/tools/agiloft/types'
+import { buildGetChoiceLineIdUrl, executeAgiloftRequest } from '@/tools/agiloft/utils'
+import type { ToolConfig } from '@/tools/types'
+
+export const agiloftGetChoiceLineIdTool: ToolConfig<
+ AgiloftGetChoiceLineIdParams,
+ AgiloftGetChoiceLineIdResponse
+> = {
+ id: 'agiloft_get_choice_line_id',
+ name: 'Agiloft Get Choice Line ID',
+ description:
+ 'Resolve the internal numeric ID of a choice-list value, for use in EWSelect WHERE clauses against choice fields.',
+ version: '1.0.0',
+
+ params: {
+ instanceUrl: {
+ type: 'string',
+ required: true,
+ visibility: 'user-only',
+ description: 'Agiloft instance URL (e.g., https://mycompany.agiloft.com)',
+ },
+ knowledgeBase: {
+ type: 'string',
+ required: true,
+ visibility: 'user-only',
+ description: 'Knowledge base name',
+ },
+ login: {
+ type: 'string',
+ required: true,
+ visibility: 'user-only',
+ description: 'Agiloft username',
+ },
+ password: {
+ type: 'string',
+ required: true,
+ visibility: 'user-only',
+ description: 'Agiloft password',
+ },
+ table: {
+ type: 'string',
+ required: true,
+ visibility: 'user-or-llm',
+ description: 'Table name (e.g., "case", "contracts")',
+ },
+ fieldName: {
+ type: 'string',
+ required: true,
+ visibility: 'user-or-llm',
+ description: 'Choice field name (e.g., "priority", "status")',
+ },
+ value: {
+ type: 'string',
+ required: true,
+ visibility: 'user-or-llm',
+ description: 'Choice display value to resolve (e.g., "High", "Active")',
+ },
+ },
+
+ request: {
+ url: 'https://placeholder.agiloft.com',
+ method: 'GET',
+ headers: () => ({}),
+ },
+
+ directExecution: async (params) => {
+ return executeAgiloftRequest(
+ params,
+ (base) => ({
+ url: buildGetChoiceLineIdUrl(base, params),
+ method: 'GET',
+ headers: { Accept: 'application/json' },
+ }),
+ async (response) => {
+ if (!response.ok) {
+ const errorText = await response.text()
+ return {
+ success: false,
+ output: { choiceLineId: null },
+ error: `Agiloft error: ${response.status} - ${errorText}`,
+ }
+ }
+
+ const data = (await response.json()) as Record
+ const result = data.result ?? data
+ let choiceLineId: number | null = null
+
+ if (typeof result === 'number') {
+ choiceLineId = result
+ } else if (typeof result === 'string') {
+ const parsed = Number(result)
+ choiceLineId = Number.isFinite(parsed) ? parsed : null
+ } else if (typeof result === 'object' && result !== null) {
+ const obj = result as Record
+ const idVal = obj.id ?? obj.choiceLineId ?? obj.lineId
+ if (typeof idVal === 'number') {
+ choiceLineId = idVal
+ } else if (typeof idVal === 'string') {
+ const parsed = Number(idVal)
+ choiceLineId = Number.isFinite(parsed) ? parsed : null
+ }
+ }
+
+ if (choiceLineId === null) {
+ return {
+ success: false,
+ output: { choiceLineId: null },
+ error: `No choice line ID found for value "${params.value}" in field "${params.fieldName}"`,
+ }
+ }
+
+ return {
+ success: data.success !== false,
+ output: { choiceLineId },
+ }
+ }
+ )
+ },
+
+ outputs: {
+ choiceLineId: {
+ type: 'number',
+ description: 'Internal numeric line ID of the choice value',
+ optional: true,
+ },
+ },
+}
diff --git a/apps/sim/tools/agiloft/index.ts b/apps/sim/tools/agiloft/index.ts
index 2ff7ac6f4f0..c47d18f98c2 100644
--- a/apps/sim/tools/agiloft/index.ts
+++ b/apps/sim/tools/agiloft/index.ts
@@ -2,6 +2,7 @@ export { agiloftAttachFileTool } from '@/tools/agiloft/attach_file'
export { agiloftAttachmentInfoTool } from '@/tools/agiloft/attachment_info'
export { agiloftCreateRecordTool } from '@/tools/agiloft/create_record'
export { agiloftDeleteRecordTool } from '@/tools/agiloft/delete_record'
+export { agiloftGetChoiceLineIdTool } from '@/tools/agiloft/get_choice_line_id'
export { agiloftLockRecordTool } from '@/tools/agiloft/lock_record'
export { agiloftReadRecordTool } from '@/tools/agiloft/read_record'
export { agiloftRemoveAttachmentTool } from '@/tools/agiloft/remove_attachment'
diff --git a/apps/sim/tools/agiloft/read_record.ts b/apps/sim/tools/agiloft/read_record.ts
index c9760a70089..70b015c43bf 100644
--- a/apps/sim/tools/agiloft/read_record.ts
+++ b/apps/sim/tools/agiloft/read_record.ts
@@ -65,6 +65,7 @@ export const agiloftReadRecordTool: ToolConfig ({
url: buildReadRecordUrl(base, params),
method: 'GET',
+ headers: { Accept: 'application/json' },
}),
async (response) => {
if (!response.ok) {
diff --git a/apps/sim/tools/agiloft/remove_attachment.ts b/apps/sim/tools/agiloft/remove_attachment.ts
index 3117017719f..7e9a9d6f2d4 100644
--- a/apps/sim/tools/agiloft/remove_attachment.ts
+++ b/apps/sim/tools/agiloft/remove_attachment.ts
@@ -67,7 +67,7 @@ export const agiloftRemoveAttachmentTool: ToolConfig<
request: {
url: 'https://placeholder.agiloft.com',
- method: 'GET',
+ method: 'DELETE',
headers: () => ({}),
},
@@ -76,7 +76,7 @@ export const agiloftRemoveAttachmentTool: ToolConfig<
params,
(base) => ({
url: buildRemoveAttachmentUrl(base, params),
- method: 'GET',
+ method: 'DELETE',
}),
async (response) => {
const text = await response.text()
diff --git a/apps/sim/tools/agiloft/saved_search.ts b/apps/sim/tools/agiloft/saved_search.ts
index 8b28cbd140b..8d645d871d0 100644
--- a/apps/sim/tools/agiloft/saved_search.ts
+++ b/apps/sim/tools/agiloft/saved_search.ts
@@ -107,8 +107,12 @@ export const agiloftSavedSearchTool: ToolConfig<
properties: {
name: { type: 'string', description: 'Saved search name' },
label: { type: 'string', description: 'Saved search display label' },
- id: { type: 'string', description: 'Saved search database identifier' },
- description: { type: 'string', description: 'Saved search description' },
+ id: { type: 'number', description: 'Saved search database identifier' },
+ description: {
+ type: 'string',
+ description: 'Saved search description',
+ optional: true,
+ },
},
},
},
diff --git a/apps/sim/tools/agiloft/search_records.ts b/apps/sim/tools/agiloft/search_records.ts
index 422140a81aa..b05465c0be5 100644
--- a/apps/sim/tools/agiloft/search_records.ts
+++ b/apps/sim/tools/agiloft/search_records.ts
@@ -94,45 +94,44 @@ export const agiloftSearchRecordsTool: ToolConfig<
const data = (await response.json()) as Record
const records: Record[] = []
+ const result = (data.result ?? data) as Record
- if (data.result && Array.isArray(data.result)) {
- for (const item of data.result as Record[]) {
+ if (Array.isArray(result)) {
+ for (const item of result as Record[]) {
records.push(item)
}
- } else if (Array.isArray(data)) {
- for (const item of data as Record[]) {
- records.push(item)
- }
- } else if (data.results && Array.isArray(data.results)) {
- for (const item of data.results as Record[]) {
- records.push(item)
- }
- } else if (data.records && Array.isArray(data.records)) {
- for (const item of data.records as Record[]) {
- records.push(item)
- }
- } else if (typeof data.EWREST_length === 'number') {
- const count = data.EWREST_length as number
- for (let i = 0; i < count; i++) {
- const record: Record = {}
- for (const key of Object.keys(data)) {
- const match = key.match(/^EWREST_(.+)_(\d+)$/)
- if (match && Number(match[2]) === i) {
- record[match[1]] = data[key]
+ } else {
+ const lengthRaw = result.EWREST_length ?? data.EWREST_length
+ const count = typeof lengthRaw === 'string' ? Number(lengthRaw) : (lengthRaw as number)
+ if (typeof count === 'number' && Number.isFinite(count)) {
+ const source = (result.EWREST_length != null ? result : data) as Record
+ for (let i = 0; i < count; i++) {
+ const record: Record = {}
+ for (const key of Object.keys(source)) {
+ const match = key.match(/^EWREST_(.+)_(\d+)$/)
+ if (match && Number(match[2]) === i) {
+ record[match[1]] = source[key]
+ }
+ }
+ if (Object.keys(record).length > 0) {
+ records.push(record)
}
- }
- if (Object.keys(record).length > 0) {
- records.push(record)
}
}
}
- const totalCount =
- (data.totalCount as number) ??
- (data.total as number) ??
- (data.count as number) ??
- (data.EWREST_length as number) ??
+ const totalCountRaw =
+ result.totalCount ??
+ result.total ??
+ result.count ??
+ result.EWREST_length ??
+ data.totalCount ??
+ data.total ??
+ data.count ??
+ data.EWREST_length ??
records.length
+ const totalCount =
+ typeof totalCountRaw === 'string' ? Number(totalCountRaw) : (totalCountRaw as number)
const page = params.page ? Number(params.page) : 0
const limit = params.limit ? Number(params.limit) : 25
diff --git a/apps/sim/tools/agiloft/select_records.ts b/apps/sim/tools/agiloft/select_records.ts
index 521ea497fbd..de4be3139cb 100644
--- a/apps/sim/tools/agiloft/select_records.ts
+++ b/apps/sim/tools/agiloft/select_records.ts
@@ -95,14 +95,22 @@ export const agiloftSelectRecordsTool: ToolConfig<
}
}
- const totalCount =
- data.EWREST_id_length ?? data.totalCount ?? data.total ?? data.count ?? recordIds.length
+ const totalCountRaw =
+ result.EWREST_id_length ??
+ result.totalCount ??
+ result.total ??
+ result.count ??
+ data.EWREST_id_length ??
+ data.totalCount ??
+ data.total ??
+ data.count ??
+ recordIds.length
return {
success: data.success !== false,
output: {
recordIds,
- totalCount: Number(totalCount),
+ totalCount: Number(totalCountRaw),
},
}
}
diff --git a/apps/sim/tools/agiloft/types.ts b/apps/sim/tools/agiloft/types.ts
index 9d132631556..849c6ab05c9 100644
--- a/apps/sim/tools/agiloft/types.ts
+++ b/apps/sim/tools/agiloft/types.ts
@@ -160,3 +160,14 @@ export interface AgiloftRemoveAttachmentResponse extends ToolResponse {
remainingAttachments: number
}
}
+
+export interface AgiloftGetChoiceLineIdParams extends AgiloftBaseParams {
+ fieldName: string
+ value: string
+}
+
+export interface AgiloftGetChoiceLineIdResponse extends ToolResponse {
+ output: {
+ choiceLineId: number | null
+ }
+}
diff --git a/apps/sim/tools/agiloft/update_record.ts b/apps/sim/tools/agiloft/update_record.ts
index 0c3f8a2d096..661be1b3a8a 100644
--- a/apps/sim/tools/agiloft/update_record.ts
+++ b/apps/sim/tools/agiloft/update_record.ts
@@ -78,7 +78,7 @@ export const agiloftUpdateRecordTool: ToolConfig ({
url: buildUpdateRecordUrl(base, params),
method: 'PUT',
- headers: { 'Content-Type': 'application/json' },
+ headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
body,
}),
async (response) => {
diff --git a/apps/sim/tools/agiloft/utils.ts b/apps/sim/tools/agiloft/utils.ts
index 252dcb4a819..47184deb5fb 100644
--- a/apps/sim/tools/agiloft/utils.ts
+++ b/apps/sim/tools/agiloft/utils.ts
@@ -4,6 +4,7 @@ import type {
AgiloftAttachmentInfoParams,
AgiloftBaseParams,
AgiloftDeleteRecordParams,
+ AgiloftGetChoiceLineIdParams,
AgiloftLockRecordParams,
AgiloftReadRecordParams,
AgiloftRemoveAttachmentParams,
@@ -243,6 +244,15 @@ export function buildAttachFileUrl(
return `${base}/ewws/EWAttach?$KB=${kb}&$table=${table}&$lang=en&id=${recordId}&field=${fieldName}&fileName=${encodedFileName}`
}
+export function buildGetChoiceLineIdUrl(
+ base: string,
+ params: AgiloftGetChoiceLineIdParams
+): string {
+ const field = encodeURIComponent(params.fieldName.trim())
+ const value = encodeURIComponent(params.value.trim())
+ return `${base}/ewws/EWGetChoiceLineId/.json?${buildEwBaseQuery(params)}&field=${field}&value=${value}`
+}
+
export function getLockHttpMethod(lockAction: string): HttpMethod {
switch (lockAction) {
case 'lock':
diff --git a/apps/sim/tools/registry.ts b/apps/sim/tools/registry.ts
index 9130ac52dee..6bc8feea7e3 100644
--- a/apps/sim/tools/registry.ts
+++ b/apps/sim/tools/registry.ts
@@ -60,6 +60,7 @@ import {
agiloftAttachmentInfoTool,
agiloftCreateRecordTool,
agiloftDeleteRecordTool,
+ agiloftGetChoiceLineIdTool,
agiloftLockRecordTool,
agiloftReadRecordTool,
agiloftRemoveAttachmentTool,
@@ -3003,6 +3004,7 @@ export const tools: Record = {
agiloft_attachment_info: agiloftAttachmentInfoTool,
agiloft_create_record: agiloftCreateRecordTool,
agiloft_delete_record: agiloftDeleteRecordTool,
+ agiloft_get_choice_line_id: agiloftGetChoiceLineIdTool,
agiloft_lock_record: agiloftLockRecordTool,
agiloft_read_record: agiloftReadRecordTool,
agiloft_remove_attachment: agiloftRemoveAttachmentTool,