Skip to content

Commit 7ef695e

Browse files
committed
fix(microsoft): zero-drift fixes from verification — dedicated subBlock ids, restored legacy outputs and caps
1 parent 902edf0 commit 7ef695e

28 files changed

Lines changed: 194 additions & 64 deletions

File tree

‎apps/docs/content/docs/integrations/microsoft_dataverse.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,7 +346,7 @@ Query and list records from a Microsoft Dataverse table. Supports OData query op
346346
| `expand` | string | No | Navigation properties to expand \(OData $expand\) |
347347
| `count` | string | No | Set to "true" to include total record count in response \(OData $count\) |
348348
| `pageSize` | number | No | Records per page \(Prefer: odata.maxpagesize, 1-5000\). Defaults to 100 when Max Results is not set. Dataverse ignores $top when a page size is sent. When following nextLink, pass the same pageSize used for the first page, as Dataverse requires. |
349-
| `nextLink` | string | No | nextLink returned by a previous page. When set, the other query options are ignored and the same page size must be used. |
349+
| `nextLink` | string | No | nextLink returned by a previous page. When set, the other query options are ignored and the same page size must be used. It is empty on the last page; stop when empty. |
350350

351351
#### Output
352352

‎apps/docs/content/docs/integrations/microsoft_teams.mdx‎

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,8 @@ Write or update content in a Microsoft Teams chat
112112
| `createdTime` | string | Timestamp when message was created |
113113
| `url` | string | Web URL to the message |
114114
| `updatedContent` | boolean | Whether content was successfully updated |
115+
| `content` | string | Content of the sent message |
116+
| `attachmentCount` | number | Number of attachments sent with the message |
115117
| `files` | file[] | Files attached to the message |
116118

117119
</ReferenceDetails>
@@ -129,7 +131,7 @@ Read content from a Microsoft Teams channel
129131
| `teamId` | string | Yes | The ID of the team to read from \(e.g., "12345678-abcd-1234-efgh-123456789012" - a GUID from team listings\) |
130132
| `channelId` | string | Yes | The ID of the channel to read from \(e.g., "19:abc123def456@thread.tacv2" - from channel listings\) |
131133
| `includeAttachments` | boolean | No | Download and include message attachments \(hosted contents\) into storage |
132-
| `includeReplies` | boolean | No | Include thread replies for each root message \(Graph returns up to 1,000 replies per message\) |
134+
| `includeReplies` | boolean | No | Include thread replies for each root message \(Graph caps the replies returned per message; hasMoreReplies is true when more exist\) |
133135
| `top` | number | No | Number of root messages to return per page \(1-50, default 50\) |
134136
| `pageToken` | string | No | Page token from a previous read \(nextPageToken\) to fetch the next page |
135137

@@ -178,6 +180,8 @@ Write or send a message to a Microsoft Teams channel
178180
| `createdTime` | string | Timestamp when message was created |
179181
| `url` | string | Web URL to the message |
180182
| `updatedContent` | boolean | Whether content was successfully updated |
183+
| `content` | string | Content of the sent message |
184+
| `attachmentCount` | number | Number of attachments sent with the message |
181185
| `files` | file[] | Files attached to the message |
182186

183187
</ReferenceDetails>

‎apps/docs/content/docs/integrations/onedrive.mdx‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ Upload a file to OneDrive
5252
| `content` | string | No | The text content to upload \(if no file is provided\) |
5353
| `mimeType` | string | No | The MIME type of the file to create \(e.g., text/plain for .txt, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet for .xlsx\) |
5454
| `folderId` | string | No | Folder ID to upload the file to \(e.g., "01BYE5RZ6QN3ZWBTUFOFD3GSPGOHDJD36M"\) |
55-
| `conflictBehavior` | string | No | What to do when a file with the same name exists: "replace" \(Graph default\), "rename", or "fail" |
55+
| `conflictBehavior` | string | No | What to do when a file with the same name exists: "replace" \(used when unset\), "rename", or "fail" |
5656

5757
#### Output
5858

‎apps/sim/blocks/blocks/azure_devops.ts‎

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -195,15 +195,31 @@ export const AzureDevOpsBlock: BlockConfig = {
195195
title: 'Max Results',
196196
type: 'short-input',
197197
placeholder: '50',
198-
condition: {
199-
field: 'operation',
200-
value: [
201-
'azure_devops_list_builds',
202-
'azure_devops_list_pipelines',
203-
'azure_devops_query_work_items',
204-
'azure_devops_get_comments',
205-
],
206-
},
198+
condition: { field: 'operation', value: 'azure_devops_list_builds' },
199+
mode: 'advanced',
200+
},
201+
{
202+
id: 'pipelinesTop',
203+
title: 'Max Results',
204+
type: 'short-input',
205+
placeholder: 'Server default when empty',
206+
condition: { field: 'operation', value: 'azure_devops_list_pipelines' },
207+
mode: 'advanced',
208+
},
209+
{
210+
id: 'queryTop',
211+
title: 'Max Results',
212+
type: 'short-input',
213+
placeholder: 'Server default when empty',
214+
condition: { field: 'operation', value: 'azure_devops_query_work_items' },
215+
mode: 'advanced',
216+
},
217+
{
218+
id: 'commentsTop',
219+
title: 'Max Results',
220+
type: 'short-input',
221+
placeholder: 'Server default when empty',
222+
condition: { field: 'operation', value: 'azure_devops_get_comments' },
207223
mode: 'advanced',
208224
},
209225
{
@@ -606,10 +622,15 @@ export const AzureDevOpsBlock: BlockConfig = {
606622
title: 'Iteration Path',
607623
type: 'short-input',
608624
placeholder: 'e.g. MyProject\\Sprint 1',
609-
condition: {
610-
field: 'operation',
611-
value: ['azure_devops_create_work_item', 'azure_devops_update_work_item'],
612-
},
625+
condition: { field: 'operation', value: 'azure_devops_create_work_item' },
626+
mode: 'advanced',
627+
},
628+
{
629+
id: 'updateIterationPath',
630+
title: 'Iteration Path',
631+
type: 'short-input',
632+
placeholder: 'e.g. MyProject\\Sprint 2',
633+
condition: { field: 'operation', value: 'azure_devops_update_work_item' },
613634
mode: 'advanced',
614635
},
615636
{
@@ -688,7 +709,7 @@ export const AzureDevOpsBlock: BlockConfig = {
688709
case 'azure_devops_list_pipelines':
689710
return {
690711
...base,
691-
top: params.top ? Number(params.top) : undefined,
712+
top: params.pipelinesTop ? Number(params.pipelinesTop) : undefined,
692713
continuationToken: (params.continuationToken as string) || undefined,
693714
}
694715
case 'azure_devops_get_pipeline':
@@ -734,7 +755,7 @@ export const AzureDevOpsBlock: BlockConfig = {
734755
return {
735756
...base,
736757
wiqlQuery: params.wiqlQuery as string,
737-
top: params.top ? Number(params.top) : undefined,
758+
top: params.queryTop ? Number(params.queryTop) : undefined,
738759
}
739760
case 'azure_devops_get_work_item':
740761
return { ...base, workItemId: Number(params.workItemId) }
@@ -774,7 +795,7 @@ export const AzureDevOpsBlock: BlockConfig = {
774795
completedWork: params.completedWork ? Number(params.completedWork) : undefined,
775796
description: (params.description as string) || undefined,
776797
areaPath: (params.areaPath as string) || undefined,
777-
iterationPath: (params.iterationPath as string) || undefined,
798+
iterationPath: (params.updateIterationPath as string) || undefined,
778799
tags: (params.tags as string) || undefined,
779800
}
780801
case 'azure_devops_add_comment':
@@ -788,7 +809,7 @@ export const AzureDevOpsBlock: BlockConfig = {
788809
return {
789810
...base,
790811
workItemId: Number(params.workItemId),
791-
top: params.top ? Number(params.top) : undefined,
812+
top: params.commentsTop ? Number(params.commentsTop) : undefined,
792813
continuationToken: (params.continuationToken as string) || undefined,
793814
}
794815
default:
@@ -807,6 +828,9 @@ export const AzureDevOpsBlock: BlockConfig = {
807828
runId: { type: 'number', description: 'Pipeline run ID' },
808829
resultFilter: { type: 'string', description: 'Build result filter' },
809830
top: { type: 'number', description: 'Maximum number of results' },
831+
pipelinesTop: { type: 'number', description: 'Maximum pipelines to return (list pipelines)' },
832+
queryTop: { type: 'number', description: 'Maximum work items to return (query work items)' },
833+
commentsTop: { type: 'number', description: 'Maximum comments to return (get comments)' },
810834
buildId: { type: 'number', description: 'Build ID' },
811835
logId: { type: 'number', description: 'Build log ID' },
812836
fromBuildId: { type: 'number', description: 'Starting build ID for work item range' },
@@ -847,6 +871,7 @@ export const AzureDevOpsBlock: BlockConfig = {
847871
},
848872
areaPath: { type: 'string', description: 'Area path' },
849873
iterationPath: { type: 'string', description: 'Iteration path' },
874+
updateIterationPath: { type: 'string', description: 'New iteration path (update work item)' },
850875
tags: { type: 'string', description: 'Semicolon-separated tags' },
851876
state: {
852877
type: 'string',

‎apps/sim/blocks/blocks/microsoft_ad.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1182,7 +1182,7 @@ export const MicrosoftAdBlockMeta = {
11821182
description:
11831183
'Disable an Azure AD account and strip its group memberships when someone leaves. Use for secure offboarding.',
11841184
content:
1185-
'# Offboard User\n\nRevoke access for a departing user.\n\n## Steps\n1. Resolve the account with Get User by user principal name or id.\n2. Use Update User to set Account Enabled to No so the user can no longer sign in.\n3. Use List User Memberships with the user id to enumerate everything the user belongs to directly.\n4. For each membership whose odataType is #microsoft.graph.group, call Remove Group Member with the user id. For each one whose odataType is #microsoft.graph.directoryRole, call Remove Directory Role Member with the role id and user id. List any other types (such as administrative units) for manual follow-up.\n\n## Output\nReturn the disabled user id and the groups and directory roles the user was removed from. Note any group where removal failed so it can be handled manually, and recommend writing the action to an audit record.',
1185+
'# Offboard User\n\nRevoke access for a departing user.\n\n## Steps\n1. Resolve the account with Get User by user principal name or id.\n2. Use Update User to set Account Enabled to No so the user can no longer sign in.\n3. Use List User Memberships with the user id to enumerate everything the user belongs to directly.\n4. For each membership whose odataType is #microsoft.graph.group, call Remove Group Member with the user id. For each one whose odataType is #microsoft.graph.directoryRole, call Remove Directory Role Member with the role id and user id. List any other types (such as administrative units) for manual follow-up.\n\n## Output\nReturn the disabled user id and the groups and directory roles the user was removed from. Note any group or role where removal failed so it can be handled manually, and recommend writing the action to an audit record.',
11861186
},
11871187
{
11881188
name: 'audit-group-membership',

‎apps/sim/blocks/blocks/microsoft_dataverse.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -555,7 +555,7 @@ Return ONLY the orderby expression - no $orderby= prefix, no explanations.`,
555555
id: 'nextLink',
556556
title: 'Next Page Link',
557557
type: 'short-input',
558-
placeholder: 'nextLink output from the previous page',
558+
placeholder: 'nextLink from the previous page (empty on the last page; stop when empty)',
559559
condition: { field: 'operation', value: 'list_records' },
560560
mode: 'advanced',
561561
},

‎apps/sim/blocks/blocks/sharepoint.ts‎

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1240,10 +1240,19 @@ Return ONLY the filter expression - no explanations, no quotes around the whole
12401240
placeholder: 'Comma-separated column names, e.g. Title,Status,DueDate',
12411241
condition: {
12421242
field: 'operation',
1243-
value: ['sharepoint_get_list', 'sharepoint_get_list_item'],
1243+
value: 'sharepoint_get_list',
1244+
and: { field: 'includeColumns', value: 'true', not: true },
12441245
},
12451246
mode: 'advanced',
12461247
},
1248+
{
1249+
id: 'itemSelectFields',
1250+
title: 'Fields to Return',
1251+
type: 'short-input',
1252+
placeholder: 'Comma-separated column names, e.g. Title,Status,DueDate',
1253+
condition: { field: 'operation', value: 'sharepoint_get_list_item' },
1254+
mode: 'advanced',
1255+
},
12471256
{
12481257
id: 'listDisplayName',
12491258
title: 'List Display Name',
@@ -1477,6 +1486,10 @@ Return ONLY the JSON object - no explanations, no markdown, no extra text.`,
14771486
result.top = undefined
14781487
result.selectFields = undefined
14791488
}
1489+
if (rest.operation === 'sharepoint_get_list_item') {
1490+
result.selectFields = cleanString(result.itemSelectFields)
1491+
}
1492+
result.itemSelectFields = undefined
14801493

14811494
if (columnDefinitions && rest.operation === 'sharepoint_create_list') {
14821495
result.pageContent = columnDefinitions
@@ -1505,6 +1518,10 @@ Return ONLY the JSON object - no explanations, no markdown, no extra text.`,
15051518
filter: { type: 'string', description: 'OData $filter for list items' },
15061519
top: { type: 'number', description: 'Maximum list items per page' },
15071520
selectFields: { type: 'string', description: 'Comma-separated item field names to return' },
1521+
itemSelectFields: {
1522+
type: 'string',
1523+
description: 'Comma-separated field names to return (get list item)',
1524+
},
15081525
includeColumns: { type: 'boolean', description: 'Include columns in response' },
15091526
includeItems: { type: 'boolean', description: 'Include items in response' },
15101527
listDisplayName: { type: 'string', description: 'List display name' },

‎apps/sim/lib/internal/azure-data-explorer/client.ts‎

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,12 @@ const MAX_ERROR_MESSAGE_LENGTH = 2000
3434
const MAX_TOKEN_RESPONSE_BYTES = 256 * 1024
3535
const MAX_PROJECTED_ROWS = 10_000
3636
/**
37-
* Serialized bytes the projected rows and records may take together. The projection carries each
38-
* row twice (positional and keyed), so it is bounded below the inline tool response cap rather
39-
* than left to fail there with a generic size error.
37+
* Serialized bytes the projected tables may take together. The projection carries each row twice
38+
* (positional and keyed), so it is bounded by the inline tool response cap, minus each table's
39+
* actual envelope and a small margin for the response wrapper, rather than left to fail there
40+
* with a generic size error.
4041
*/
41-
const MAX_PROJECTED_BYTES = MAX_TOOL_RESPONSE_BODY_BYTES - 512 * 1024
42+
const MAX_PROJECTED_BYTES = MAX_TOOL_RESPONSE_BODY_BYTES - 16 * 1024
4243

4344
interface CachedToken {
4445
accessToken: string
@@ -245,6 +246,16 @@ function projectTable(
245246
const allRows = table.Rows ?? []
246247
const rows: unknown[][] = []
247248
const records: Array<Record<string, unknown>> = []
249+
const envelope: AzureDataExplorerResultTable = {
250+
tableName: table.TableName ?? null,
251+
columns,
252+
rows: [],
253+
records: [],
254+
rowCount: allRows.length,
255+
totalRowCount: allRows.length,
256+
truncated: false,
257+
}
258+
budget.bytes -= Buffer.byteLength(JSON.stringify(envelope))
248259
for (const row of allRows) {
249260
if (budget.rows <= 0) break
250261
const record: Record<string, unknown> = {}

‎apps/sim/lib/internal/sharepoint/operations.ts‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,10 @@ function buildUploadUrl(
8585
input: SharePointUploadFileInput,
8686
fileName: string
8787
): { url: string; replaceUrl: string } {
88+
const trimmedName = fileName.trim()
89+
if (trimmedName === '.' || trimmedName === '..') {
90+
throw new Error('File name cannot be "." or ".."')
91+
}
8892
const folderPath = input.folderPath?.trim() || ''
8993
const normalizedPath = folderPath.startsWith('/') ? folderPath : `/${folderPath}`
9094
const cleanPath = normalizedPath.endsWith('/') ? normalizedPath.slice(0, -1) : normalizedPath

‎apps/sim/lib/webhooks/polling/outlook.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,7 @@ async function processOutlookEmails(
422422
{
423423
fetchImpl: (url, init) => fetchWithRetry(url, init),
424424
keepPartialOnLimit: true,
425+
preferMetadataSize: true,
425426
onFailure: (stage, status) =>
426427
logger.warn('Outlook attachment request failed', {
427428
emailId: email.id,

0 commit comments

Comments
 (0)