Skip to content

Commit f7bc3e5

Browse files
committed
fix(agiloft): correct response parsing, add EWGetChoiceLineId tool (#4477)
* fix(agiloft): correct response parsing, add EWGetChoiceLineId tool * fix(agiloft): address PR review feedback
1 parent 766ac77 commit f7bc3e5

21 files changed

Lines changed: 287 additions & 67 deletions

File tree

apps/docs/content/docs/en/tools/agiloft.mdx

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { BlockInfoCard } from "@/components/ui/block-info-card"
77

88
<BlockInfoCard
99
type="agiloft"
10-
color="#FFFFFF"
10+
color="#001028"
1111
/>
1212

1313
{/* MANUAL-CONTENT-START:intro */}
@@ -137,6 +137,28 @@ Delete a record from an Agiloft table.
137137
| `id` | string | ID of the deleted record |
138138
| `deleted` | boolean | Whether the record was successfully deleted |
139139

140+
### `agiloft_get_choice_line_id`
141+
142+
Resolve the internal numeric ID of a choice-list value, for use in EWSelect WHERE clauses against choice fields.
143+
144+
#### Input
145+
146+
| Parameter | Type | Required | Description |
147+
| --------- | ---- | -------- | ----------- |
148+
| `instanceUrl` | string | Yes | Agiloft instance URL \(e.g., https://mycompany.agiloft.com\) |
149+
| `knowledgeBase` | string | Yes | Knowledge base name |
150+
| `login` | string | Yes | Agiloft username |
151+
| `password` | string | Yes | Agiloft password |
152+
| `table` | string | Yes | Table name \(e.g., "case", "contracts"\) |
153+
| `fieldName` | string | Yes | Choice field name \(e.g., "priority", "status"\) |
154+
| `value` | string | Yes | Choice display value to resolve \(e.g., "High", "Active"\) |
155+
156+
#### Output
157+
158+
| Parameter | Type | Description |
159+
| --------- | ---- | ----------- |
160+
| `choiceLineId` | number | Internal numeric line ID of the choice value |
161+
140162
### `agiloft_lock_record`
141163

142164
Lock, unlock, or check the lock status of an Agiloft record.
@@ -254,7 +276,7 @@ List saved searches defined for an Agiloft table.
254276
| `searches` | array | List of saved searches for the table |
255277
|`name` | string | Saved search name |
256278
|`label` | string | Saved search display label |
257-
|`id` | string | Saved search database identifier |
279+
|`id` | number | Saved search database identifier |
258280
|`description` | string | Saved search description |
259281

260282
### `agiloft_search_records`

apps/docs/content/docs/en/tools/posthog.mdx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ List persons (users) in PostHog. Returns user profiles with their properties and
8787

8888
| Parameter | Type | Required | Description |
8989
| --------- | ---- | -------- | ----------- |
90-
| `personalApiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
90+
| `apiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
9191
| `region` | string | No | PostHog region: us \(default\) or eu |
9292
| `projectId` | string | Yes | PostHog Project ID \(e.g., "12345" or project UUID\) |
9393
| `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.
115115

116116
| Parameter | Type | Required | Description |
117117
| --------- | ---- | -------- | ----------- |
118-
| `personalApiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
118+
| `apiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
119119
| `region` | string | No | PostHog region: us \(default\) or eu |
120120
| `projectId` | string | Yes | PostHog Project ID \(e.g., "12345" or project UUID\) |
121121
| `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
139139

140140
| Parameter | Type | Required | Description |
141141
| --------- | ---- | -------- | ----------- |
142-
| `personalApiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
142+
| `apiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
143143
| `region` | string | No | PostHog region: us \(default\) or eu |
144144
| `projectId` | string | Yes | PostHog Project ID \(e.g., "12345" or project UUID\) |
145145
| `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
158158

159159
| Parameter | Type | Required | Description |
160160
| --------- | ---- | -------- | ----------- |
161-
| `personalApiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
161+
| `apiKey` | string | Yes | PostHog Personal API Key \(for authenticated API access\) |
162162
| `region` | string | No | PostHog region: us \(default\) or eu |
163163
| `projectId` | string | Yes | PostHog Project ID \(e.g., "12345" or project UUID\) |
164164
| `query` | string | Yes | HogQL query to execute. Example: \{"kind": "HogQLQuery", "query": "SELECT event, count\(\) FROM events WHERE timestamp &gt; now\(\) - INTERVAL 1 DAY GROUP BY event"\} |

apps/sim/app/(landing)/integrations/data/integrations.json

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@
321321
"name": "Agiloft",
322322
"description": "Manage records in Agiloft CLM",
323323
"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.",
324-
"bgColor": "#FFFFFF",
324+
"bgColor": "#001028",
325325
"iconName": "AgiloftIcon",
326326
"docsUrl": "https://docs.sim.ai/tools/agiloft",
327327
"operations": [
@@ -372,9 +372,13 @@
372372
{
373373
"name": "Lock Record",
374374
"description": "Lock, unlock, or check the lock status of an Agiloft record."
375+
},
376+
{
377+
"name": "Get Choice Line ID",
378+
"description": "Resolve the internal numeric ID of a choice-list value, for use in EWSelect WHERE clauses against choice fields."
375379
}
376380
],
377-
"operationCount": 12,
381+
"operationCount": 13,
378382
"triggers": [],
379383
"triggerCount": 0,
380384
"authType": "none",

apps/sim/app/api/tools/agiloft/attach/route.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createLogger } from '@sim/logger'
2+
import { toError } from '@sim/utils/errors'
23
import { type NextRequest, NextResponse } from 'next/server'
34
import { agiloftAttachContract } from '@/lib/api/contracts/tools/agiloft'
45
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -90,7 +91,7 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
9091
const agiloftResponse = await fetch(url, {
9192
method: 'PUT',
9293
headers: {
93-
'Content-Type': userFile.type || 'application/octet-stream',
94+
'Content-Type': 'application/octet-stream',
9495
Authorization: `Bearer ${token}`,
9596
},
9697
body: new Uint8Array(fileBuffer),
@@ -136,9 +137,6 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
136137
} catch (error) {
137138
logger.error(`[${requestId}] Error attaching file to Agiloft:`, error)
138139

139-
return NextResponse.json(
140-
{ success: false, error: error instanceof Error ? error.message : 'Internal server error' },
141-
{ status: 500 }
142-
)
140+
return NextResponse.json({ success: false, error: toError(error).message }, { status: 500 })
143141
}
144142
})

apps/sim/app/api/tools/agiloft/retrieve/route.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createLogger } from '@sim/logger'
2+
import { toError } from '@sim/utils/errors'
23
import { type NextRequest, NextResponse } from 'next/server'
34
import { agiloftRetrieveContract } from '@/lib/api/contracts/tools/agiloft'
45
import { getValidationErrorMessage, parseRequest } from '@/lib/api/server'
@@ -127,9 +128,6 @@ export const POST = withRouteHandler(async (request: NextRequest) => {
127128
} catch (error) {
128129
logger.error(`[${requestId}] Error retrieving Agiloft attachment:`, error)
129130

130-
return NextResponse.json(
131-
{ success: false, error: error instanceof Error ? error.message : 'Internal server error' },
132-
{ status: 500 }
133-
)
131+
return NextResponse.json({ success: false, error: toError(error).message }, { status: 500 })
134132
}
135133
})

apps/sim/blocks/blocks/agiloft.ts

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ export const AgiloftBlock: BlockConfig = {
1313
category: 'tools',
1414
integrationType: IntegrationType.Productivity,
1515
tags: ['automation'],
16-
bgColor: '#FFFFFF',
16+
bgColor: '#001028',
1717
icon: AgiloftIcon,
1818
authMode: AuthMode.ApiKey,
1919

@@ -35,6 +35,7 @@ export const AgiloftBlock: BlockConfig = {
3535
{ label: 'Remove Attachment', id: 'remove_attachment' },
3636
{ label: 'Attachment Info', id: 'attachment_info' },
3737
{ label: 'Lock Record', id: 'lock_record' },
38+
{ label: 'Get Choice Line ID', id: 'get_choice_line_id' },
3839
],
3940
value: () => 'search_records',
4041
},
@@ -44,7 +45,6 @@ export const AgiloftBlock: BlockConfig = {
4445
type: 'short-input',
4546
placeholder: 'https://mycompany.agiloft.com',
4647
required: true,
47-
password: false,
4848
},
4949
{
5050
id: 'knowledgeBase',
@@ -151,16 +151,36 @@ export const AgiloftBlock: BlockConfig = {
151151
id: 'fieldName',
152152
title: 'Field Name',
153153
type: 'short-input',
154-
placeholder: 'e.g., attached_docs',
154+
placeholder: 'e.g., attached_docs, priority',
155155
condition: {
156156
field: 'operation',
157-
value: ['attach_file', 'retrieve_attachment', 'remove_attachment', 'attachment_info'],
157+
value: [
158+
'attach_file',
159+
'retrieve_attachment',
160+
'remove_attachment',
161+
'attachment_info',
162+
'get_choice_line_id',
163+
],
158164
},
159165
required: {
160166
field: 'operation',
161-
value: ['attach_file', 'retrieve_attachment', 'remove_attachment', 'attachment_info'],
167+
value: [
168+
'attach_file',
169+
'retrieve_attachment',
170+
'remove_attachment',
171+
'attachment_info',
172+
'get_choice_line_id',
173+
],
162174
},
163175
},
176+
{
177+
id: 'value',
178+
title: 'Choice Value',
179+
type: 'short-input',
180+
placeholder: 'e.g., High, Active',
181+
condition: { field: 'operation', value: 'get_choice_line_id' },
182+
required: { field: 'operation', value: 'get_choice_line_id' },
183+
},
164184
{
165185
id: 'uploadFile',
166186
title: 'File',
@@ -254,6 +274,7 @@ export const AgiloftBlock: BlockConfig = {
254274
'agiloft_attachment_info',
255275
'agiloft_create_record',
256276
'agiloft_delete_record',
277+
'agiloft_get_choice_line_id',
257278
'agiloft_lock_record',
258279
'agiloft_read_record',
259280
'agiloft_remove_attachment',
@@ -288,7 +309,8 @@ export const AgiloftBlock: BlockConfig = {
288309
data: { type: 'string', description: 'Record data as JSON' },
289310
query: { type: 'string', description: 'Search query' },
290311
where: { type: 'string', description: 'SQL WHERE clause for select' },
291-
fieldName: { type: 'string', description: 'Attachment field name' },
312+
fieldName: { type: 'string', description: 'Attachment field name or choice field name' },
313+
value: { type: 'string', description: 'Choice value to resolve to its line ID' },
292314
attachFile: { type: 'file', description: 'File to attach' },
293315
fileName: { type: 'string', description: 'Name for the attached file' },
294316
position: { type: 'string', description: 'Attachment position index' },
@@ -403,5 +425,10 @@ export const AgiloftBlock: BlockConfig = {
403425
description: 'Minutes until the lock expires',
404426
condition: { field: 'operation', value: 'lock_record' },
405427
},
428+
choiceLineId: {
429+
type: 'number',
430+
description: 'Internal numeric ID of the resolved choice value',
431+
condition: { field: 'operation', value: 'get_choice_line_id' },
432+
},
406433
},
407434
}

apps/sim/lib/api/contracts/tools/agiloft.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ export const agiloftAttachBodySchema = z.object({
5050
table: z.string().min(1, 'Table is required'),
5151
recordId: z.string().min(1, 'Record ID is required'),
5252
fieldName: z.string().min(1, 'Field name is required'),
53-
file: FileInputSchema.optional().nullable(),
54-
fileName: z.string().optional().nullable(),
53+
file: FileInputSchema.optional(),
54+
fileName: z.string().optional(),
5555
})
5656

5757
export const agiloftRetrieveContract = defineRouteContract({

apps/sim/tools/agiloft/attachment_info.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,13 @@ export const agiloftAttachmentInfoTool: ToolConfig<
9191
for (let i = 0; i < result.length; i++) {
9292
const item = result[i] as Record<string, unknown>
9393
attachments.push({
94-
position: (item.position as number) ?? i,
95-
name: (item.name as string) ?? (item.filename as string) ?? '',
96-
size: (item.size as number) ?? 0,
94+
position: (item.filePosition as number) ?? (item.position as number) ?? i,
95+
name:
96+
(item.fileName as string) ??
97+
(item.name as string) ??
98+
(item.filename as string) ??
99+
'',
100+
size: (item.size as number) ?? (item.fileSize as number) ?? 0,
97101
})
98102
}
99103
}

apps/sim/tools/agiloft/create_record.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export const agiloftCreateRecordTool: ToolConfig<AgiloftCreateRecordParams, Agil
7272
(base) => ({
7373
url: buildCreateRecordUrl(base, params),
7474
method: 'POST',
75-
headers: { 'Content-Type': 'application/json' },
75+
headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
7676
body,
7777
}),
7878
async (response) => {

apps/sim/tools/agiloft/delete_record.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export const agiloftDeleteRecordTool: ToolConfig<AgiloftDeleteRecordParams, Agil
6060
(base) => ({
6161
url: buildDeleteRecordUrl(base, params),
6262
method: 'DELETE',
63+
headers: { Accept: 'application/json' },
6364
}),
6465
async (response) => {
6566
if (!response.ok) {

0 commit comments

Comments
 (0)